如何使用ItemsSource和DataTemplates从数据对象呈现function区
我试图为我的function区提供数据模板。
function区声明如下,并附加了ItemTemplate。
Datatemplate如下:
然后我附上ItemsSource:
public MainWindow() { InitializeComponent(); var RibbonTabData = new ObservableCollection(); RibbonTabData.Add(new RibbonContainer("HeaderName", "GroupName")); RibbonMain.ItemsSource = RibbonTabData; }
最后是类:(其中只包含两个字符串字段)
class RibbonContainer { public string HeaderName { get; set; } public string GroupName { get; set; } public RibbonContainer(string _headername, string _groupname) { HeaderName = _headername; GroupName = _groupname; } }
我得到了在标题标题中显示完全限定类名的不起眼的结果,并且ribbongroup也没有显示。 (这是datatemplate应解决的问题?)怎么办?
最好的祝福
我不确定从哪里开始,但也许有一个简短的警告,在尝试完全从数据Binding
和数据项创建一个RibbonControl
,你真的正在为自己开辟一大堆屁股 。 这是因为为其设计代码的开发人员使用了非常规模式,并且未能充分记录如何使用它进行操作。 通过在本网站上搜索可以找到一些最好的来源。
所以无论如何,如果你想要一场痛苦的,艰难的斗争,请继续阅读。 您的第一个错误是尝试将DataTemplate
用于RibbonTab
因为它扩展了System.Windows.Controls.ItemsControl
,因此需要HierarchicalDataTemplate
。 你的第二个错误是在模板中声明了RibbonTab
,正如评论中提到的@devhedgehog。
你的第三个错误是为你的DataTemplate
设置x:Key
值并将其应用到Ribbon.ItemsTemplate
属性……我知道,我知道…… 如果这不是RibbonControl
那么这是一个明智的做法。 你不得不问那些开发人员为什么不起作用,但你最好只是接受它没有并调整你的代码。 您只需要删除x:Key
值和Ribbon.ItemsTemplate
属性,并让Framework 隐式应用模板。
现在,如果你想要多个RibbonGroup
,那么你的第四个错误是在RibbonTab
的模板中定义它。 如果您要正确执行此操作,那么您的数据类将需要匹配Ribbon
中的各种UI元素级别。 这样,我的意思是你也需要创建一个RibbonGroupData
类。 该类需要一组RibbonButtonData
对象, RibbonButtonData
对象为UI中的每个RibbonButton
提供数据。 所以你应该得到这样的东西:
public class RibbonTabData : BaseDataType { private string name = string.Empty; private ObservableCollection ribbonGroupData = new ObservableCollection (); public string Name { get { return name; } set { name = value; NotifyPropertyChanged("Name"); } } public ObservableCollection RibbonGroupData { get { return ribbonGroupData; } set { ribbonGroupData = value; NotifyPropertyChanged("RibbonGroupData"); } } } public class RibbonGroupData : BaseDataType { private string name = string.Empty; private ObservableCollection ribbonButtonData = new ObservableCollection (); public string Name { get { return name; } set { name = value; NotifyPropertyChanged("Name"); } } public ObservableCollection RibbonButtonData { get { return ribbonButtonData; } set { ribbonButtonData = value; NotifyPropertyChanged("RibbonButtonData"); } } } public class RibbonButtonData : BaseDataType { private string name = string.Empty; public string Name { get { return name; } set { name = value; NotifyPropertyChanged("Name"); } } }
BaseDataType
类只实现了INotifyPropertyChanged
接口。 当然,您需要为ICommand
和图像源等添加额外的属性。您甚至可能需要具有不同类型的RibbonButton
的不同属性的不同RibbonButtonData
类,然后您需要一个共同的RibbonButtonBaseData
类,它们都扩展了,因此您的collections可以包含所有不同类型。 所以你还有很多事要做,但是给定这个示例代码,你可以在Ribbon
显示它,如下所示:
现在在设置为Window
的DataContext
的视图模型中,我可以添加一些虚拟数据来测试它是否全部工作:
RibbonTabData.Add(new RibbonTabData() { Name = "Tab 1", RibbonGroupData = new ObservableCollection() { new RibbonGroupData() { Name = "Group 1", RibbonButtonData = new ObservableCollection() { new RibbonButtonData() { Name = "Button 1" }, new RibbonButtonData() { Name = "Button 2" }, new RibbonButtonData() { Name = "Button 3" } } }, new RibbonGroupData() { Name = "Group 2", RibbonButtonData = new ObservableCollection () { new RibbonButtonData() { Name = "Button 1" }, new RibbonButtonData() { Name = "Button 2" } } } } }); RibbonTabData.Add(new RibbonTabData() { Name = "Tab 2" }); RibbonTabData.Add(new RibbonTabData() { Name = "Tab 3" });
我们得到这个:
然而,即使有了这个有用的开始,你还有很多工作要做。
通过阅读Sheridans的回答,我设法创建了以下结果:
(可以将事件处理程序附加到所需控件的不同控件)。
我是如何进行事件处理的(例如使用ribbonbutton)
- 将标签属性附加到您的ribbonbutton模板(当然使用数据绑定)
- 将加载的事件附加到function区按钮模板中
-
创建一个字典:(在你的windowname.xaml.cs中
public Dictionary
> EventLibrary = new Dictionary >(); -
将事件添加到字典并使用事件类型扩展字符串
EventLibrary.Add("NAME_RIBBONBUTTON_CLICKEVENT", new List
{ new RoutedEventHandler(RibbonButton_Test)}); -
这是加载事件的代码:
private void RibbonButton_Loaded(object sender, EventArgs e) { System.Windows.Controls.Ribbon.RibbonButton cmd = (System.Windows.Controls.Ribbon.RibbonButton)sender; if (EventLibrary.ContainsKey(cmd.Tag.ToString() + "_CLICKEVENT")) { List
value = EventLibrary[cmd.Tag.ToString() + "_CLICKEVENT"]; for (int i = 0; i < value.Count; i++) { cmd.AddHandler(RibbonButton.ClickEvent, value[i]); } } }
这是WPF博客中旧post的链接,在那里你可以下载存档与解决方案,在那里你可以找到几个有用的东西:
- 所有function区控件的ViewModels
- 具有所有适当绑定的样式
所以最后使用上面的东西我收到了更简单的解决方案:
我添加到VM的唯一内容是子元素的集合。