c# - WPF 树数据模板取决于项目类型

标签 c# wpf mvvm

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

此数据包括 ID、ParentID、文本和类型(以及更多)。

示例数据:

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

现在我想为三角形、心形、圆形和正方形设置不同的模板。 我不是说只改变一个图像,而是一个模板。 我怎样才能做到这一点?

亲切的问候,保罗。

最佳答案

如果您的 ItemsSource 由不同的类型组成,那么您可以简单地创建 HierarchicalDataTemplates 并且不分配 x:Key。如果 DataTemplate 没有 x:Key 属性,框架将在遇到该类型时使用此 DataTemplate 并尝试以可视方式显示它(您可以阅读更多关于隐式 DataTemplates here )。例如,如果您有一个类型 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 的更多信息 here , 和 this link有一个如何在 TreeView 中使用它们的示例。

如果您的项目都是相同的类型,并且仅通过属性(例如类型)进行区分,您将需要使用 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}"/>

关于c# - WPF 树数据模板取决于项目类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15341728/

相关文章:

wpf - 是否可以 'refresh' WPF 数据绑定(bind)

c# - 从 ViewModel 到 Custom-Control 到 ControlTemplate 上的控件的多阶段绑定(bind)不起作用

c# - 自定义用户控件事件

datagrid - 使用 MVVM 的 DataGrid 中的 ContextMenu 绑定(bind)源

c# - EntityFramework - 选择具有自定义属性投影的实体

c# - 没有 ORM 的数据访问层

c# - 如何以编程方式设置动态创建以嵌入到 TableLayoutPanel 中的控件的 Column 和 Row 属性?

c# - NumericUpDown 允许用户键入大于最大值的数字

wpf - 使用 DataTrigger 而不是数据绑定(bind)更好吗?

wpf - 带百分比坐标的面板