WPF树数据模板取决于项目的类型

本文关键字:项目 类型 取决于 数据 WPF | 更新日期: 2023-09-27 18:03:16

我有一个MVVM WPF应用程序,其中包含自引用数据的树,该数据与分层转换器绑定到树。(例如:http://www.telerik.com/help/wpf/radtreeview-how-to-bind-to-self-referencing-data.html)

此数据包括ID, ParentID, Text和Type(以及更多)。

示例数据:

1,0,"FirstItem","Triangle"
2,1,"SubItem1","Circle"
3,1,"SubItem2","Square"
4,2,"SubItem11","Triangle"
5,2,"SubItem12","Heart"
6,3,"SubItem21","Circle"

现在我想有三角形,心,圆和正方形的不同模板。我指的不是仅仅改变一个图像,而是一个模板。我怎样才能做到呢?

敬礼,Paul。

WPF树数据模板取决于项目的类型

如果您的ItemsSource由不同的type组成,那么您可以简单地创建HierarchicalDataTemplates而不分配x:Key。如果DataTemplate没有x:Key属性,框架将在遇到该类型时使用该DataTemplate,并尝试可视化地显示它(您可以在这里阅读有关隐式DataTemplates的更多信息)。例如,如果您有一个类型Circle和另一个类型Square,那么您将在资源中拥有以下模板:

<Window.Resources>
    <HierarchicalDataTemplate DataType="{x:Type local:Circle}" ItemsSource="{Binding Children}">
        <Ellipse Fill="{Binding Fill}" Width="25" Height="25" Stroke="Black" StrokeThickness="0.25"/>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate DataType="{x:Type local:Square}" ItemsSource="{Binding Children}">
        <Rectangle Fill="{Binding Fill}" Width="25" Height="25" Stroke="Black" StrokeThickness="0.25"/>
    </HierarchicalDataTemplate>
</Window.Resources>

如果你的TreeView在它的ItemsSource中遇到了这些类型之一,它将使用HierarchicalDataTemplate作为该特定类型。

你可以在这里阅读更多关于HierarchicalDataTemplates的信息,这个链接有一个如何在TreeView中使用它们的示例。

如果您的项目都是相同的类型,并且仅通过属性(如Type)区分,则需要使用DataTemplateSelector。下面是一个简单的例子:

后台代码:

public class ShapeTemplateSelector : DataTemplateSelector
{
    public DataTemplate CircleTemplate { get; set; }
    public DataTemplate SquareTemplate { get; set; }
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        Shape shape = item as Shape;
        if (shape != null)
        {
            if (shape.Type == "Circle")
                return this.CircleTemplate;
            else if (shape.Type == "Square")
                return this.SquareTemplate;
            }
            return null;
        }
}
XAML:

<local:ShapeTemplateSelector x:Key="shapeSelector">
    <local:ShapeTemplateSelector.CircleTemplate>
        <HierarchicalDataTemplate DataType="{x:Type local:Shape}" ItemsSource="{Binding Children}">
            <Ellipse Fill="{Binding Fill}" Width="25" Height="25" Stroke="Black" StrokeThickness="0.25"/>
        </HierarchicalDataTemplate>
    </local:ShapeTemplateSelector.CircleTemplate>
    <local:ShapeTemplateSelector.SquareTemplate>
        <HierarchicalDataTemplate DataType="{x:Type local:Shape}" ItemsSource="{Binding Children}">
            <Rectangle Fill="{Binding Fill}" Width="25" Height="25" Stroke="Black" StrokeThickness="0.25"/>
        </HierarchicalDataTemplate>
    </local:ShapeTemplateSelector.SquareTemplate>
</local:ShapeTemplateSelector>

然后在TreeView中,您只需分配选择器

<TreeView x:Name="Tree" ItemsSource="{Binding Shapes}" ItemTemplateSelector="{DynamicResource shapeSelector}"/>

如果你有实际不同的类型,你可以在HierarchicalDataTemplate中使用DataType属性指定类型(我如何在WPF DataTemplate上使用DataType属性?),WPF将根据类选择模板。

如果您没有不同的类型,但将依赖于类中的属性或值,则需要指定DataTemplateSelector (http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector)