如何使用ItemsSource和DataTemplates从数据对象呈现功能区

Lam*_*der 1 c# wpf binding

我试图为我的功能区提供数据模板.

功能区声明如下,并附加了ItemTemplate.

<r:Ribbon Name="RibbonMain"
          ItemTemplate="{StaticResource HomeRibbonTabTemplate}">
</r:Ribbon>
Run Code Online (Sandbox Code Playgroud)

Datatemplate如下:

<Window.Resources>
    <DataTemplate DataType="{x:Type local:RibbonContainer}" 
                  x:Key="HomeRibbonTabTemplate">
        <r:RibbonTab Header="{Binding Path=HeaderName}">
            <r:RibbonGroup Header="{Binding Path=GroupName}">
            </r:RibbonGroup>
        </r:RibbonTab>
    </DataTemplate>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

然后我附上ItemsSource:

    public MainWindow()
    {
        InitializeComponent();

        var RibbonTabData = new ObservableCollection<RibbonContainer>();
        RibbonTabData.Add(new RibbonContainer("HeaderName", "GroupName"));
        RibbonMain.ItemsSource = RibbonTabData;
    }
Run Code Online (Sandbox Code Playgroud)

最后是类:(其中只包含两个字符串字段)

class RibbonContainer
{
    public string HeaderName
    {
        get;
        set;
    }

    public string GroupName
    {
        get;
        set;
    }

    public RibbonContainer(string _headername, string _groupname)
    {
        HeaderName = _headername;
        GroupName = _groupname;
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到了在标题标题中显示完全限定类名的不起眼的结果,并且ribbongroup也没有显示.(这是datatemplate应该解决的问题?)怎么办?

最好的祝福

She*_*dan 8

我不确定从哪里开始,但也许只是一个简短的警告,在尝试RibbonControl完全从数据Binding和数据项创建时,你真的正在为自己开辟一大堆屁股.这是因为为其设计代码的开发人员使用了非常规模式而未能充分记录如何使用它.通过在本网站上搜索可以找到一些最佳来源.

所以,无论如何,如果你想要一场痛苦的,艰难的斗争,请继续阅读.你的第一个错误是尝试使用a DataTemplate,RibbonTab因为它是扩展的System.Windows.Controls.ItemsControl,因此需要一个HierarchicalDataTemplate.你的第二个错误是RibbonTab在模板中声明,正如@devhedgehog在评论中提到的那样.

你的第三个错误就是x:Key为你设定价值DataTemplate并将其应用于Ribbon.ItemsTemplate财产......我知道,我知道...... 如果不是RibbonControl这样的话,这是一件明智的事情.你不得不问那些开发人员为什么不起作用,但你最好只是接受它没有并调整你的代码.您只需要删除x:Key值和Ribbon.ItemsTemplate属性,并让Framework 隐式应用模板.

现在,如果你想要不止一个RibbonGroup,那么你的第四个错误是在模板中定义RibbonTab.如果您要正确地执行此操作,那么您的数据类将需要匹配中的各种UI元素级别Ribbon.通过这个,我的意思是你也需要创建一个RibbonGroupData类.该类需要一组RibbonButtonData对象,这些对象RibbonButton为UI中的每个提供数据.所以你应该得到这样的东西:

public class RibbonTabData : BaseDataType
{
    private string name = string.Empty;
    private ObservableCollection<RibbonGroupData> ribbonGroupData = new ObservableCollection<RibbonGroupData>();

    public string Name
    {
        get { return name; }
        set { name = value; NotifyPropertyChanged("Name"); }
    }

    public ObservableCollection<RibbonGroupData> RibbonGroupData
    {
        get { return ribbonGroupData; }
        set { ribbonGroupData = value; NotifyPropertyChanged("RibbonGroupData"); }
    }
}

public class RibbonGroupData : BaseDataType
{
    private string name = string.Empty;
    private ObservableCollection<RibbonButtonData> ribbonButtonData = new ObservableCollection<RibbonButtonData>();

    public string Name
    {
        get { return name; }
        set { name = value; NotifyPropertyChanged("Name"); }
    }

    public ObservableCollection<RibbonButtonData> 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"); }
    }
}
Run Code Online (Sandbox Code Playgroud)

本BaseDataType类只是实现了INotifyPropertyChanged接口.当然,你需要为ICommands和图像源等添加额外的属性.你甚至可能需要RibbonButtonData为不同类型的RibbonButtons 使用不同属性的不同类,然后你需要一个RibbonButtonBaseData它们都扩展的公共类,所以你的集合可以包含所有不同类型.所以你还有很多事要做,但是给出这个示例代码,你可以用这样的方式显示它Ribbon:

<Ribbon:RibbonWindow.Resources>
    <HierarchicalDataTemplate DataType="{x:Type DataTypes:RibbonTabData}" 
        ItemsSource="{Binding RibbonGroupData}">
        <TextBlock Text="{Binding Name}" />
    </HierarchicalDataTemplate>
    <DataTemplate DataType="{x:Type DataTypes:RibbonButtonData}">
        <Ribbon:RibbonButton Label="{Binding Name}" 
            LargeImageSource="/WpfRibbonApplication1;component/Images/LargeIcon.png" />
    </DataTemplate>
    <HierarchicalDataTemplate DataType="{x:Type DataTypes:RibbonGroupData}" 
        ItemsSource="{Binding RibbonButtonData}">
        <Ribbon:RibbonGroup Header="{Binding Name}" />
    </HierarchicalDataTemplate>
</Ribbon:RibbonWindow.Resources>
<Ribbon:Ribbon x:Name="Ribbon" ItemsSource="{Binding RibbonTabData}" />
Run Code Online (Sandbox Code Playgroud)

现在在设置为DataContextfor 的视图模型中Window,我可以添加一些虚拟数据来测试它是否全部工作:

RibbonTabData.Add(new RibbonTabData() { Name = "Tab 1", RibbonGroupData = new ObservableCollection<RibbonGroupData>() { new RibbonGroupData() { Name = "Group 1", RibbonButtonData = new ObservableCollection<RibbonButtonData>() { new RibbonButtonData() { Name = "Button 1" }, new RibbonButtonData() { Name = "Button 2" }, new RibbonButtonData() { Name = "Button 3" } } }, new RibbonGroupData() { Name = "Group 2", RibbonButtonData = new ObservableCollection<RibbonButtonData>() { new RibbonButtonData() { Name = "Button 1" }, new RibbonButtonData() { Name = "Button 2" } } } } });
RibbonTabData.Add(new RibbonTabData() { Name = "Tab 2" });
RibbonTabData.Add(new RibbonTabData() { Name = "Tab 3" });
Run Code Online (Sandbox Code Playgroud)

我们得到这个:

在此输入图像描述

然而,即使有了这个有用的开始,你还有很多工作要做.