如何实现包含不同父节点和不同子节点的WPF树形视图?

18 浏览
0 Comments

如何实现包含不同父节点和不同子节点的WPF树形视图?

我想要实现一个树形视图,其结构如下:

[根节点] <---- 树的根

--[父节点 P1] <---- ModelClass P1 的对象

----[子节点 C1] <----- ModelClass C1 的对象(也有不同类型的子节点)

----[子节点 C2] <----- ModelClass C2 的对象(也有不同类型的子节点)

----[子节点 C3] <----- ModelClass C3 的对象(也有不同类型的子节点)

--[父节点 Q1] <---- ModelClass Q1 的对象

----[子节点 B1] <----- ModelClass B1 的对象(也有不同类型的子节点)

----[子节点 B2] <----- ModelClass B2 的对象(也有不同类型的子节点)

----[子节点 B3] <----- ModelClass B3 的对象(也有不同类型的子节点)

--[父节点 R1] <---- ModelClass R1 的对象

----[子节点 A1] <----- ModelClass A1 的对象(也有不同类型的子节点)

----[子节点 A2] <----- ModelClass A2 的对象(也有不同类型的子节点)

----[子节点 A3] <----- ModelClass A3 的对象(也有不同类型的子节点)

我已经查看了这个网站以及其他网站上提出的许多解决方案,但就是无法弄清楚如何实现它......

这是我第一次尝试 Wpf,并且这是一个关键需求......

也很难为上述不同类别制定对象模型......

上面显示的所有类别还具有其他属性,包括它们的子节点......

我不想显示所有属性,只想显示子节点

对于不同的解决方案感到非常困惑

如果我能在这方面得到一些帮助,那将非常好......

谢谢

0
0 Comments

问题的出现原因是:希望在WPF的TreeView中实现不同的父节点和不同的子节点,但是使用默认的HierarchicalDataTemplate无法满足需求。

解决方法是:使用自定义的集合类来实现树形结构。首先定义了一个EntityBase类,继承自ObservableCollection,然后定义了Parent、ChildA和ChildB三个类,它们都继承自EntityBase类。在绑定数据到TreeView时,可以将ChildA和ChildB对象添加为Parent对象的子节点。最后,使用HierarchicalDataTemplate来定义TreeView的显示模板,根据不同的类型分别设置不同的样式。

这样就可以实现在WPF的TreeView中显示具有不同父节点和不同子节点的树形结构了。

0
0 Comments

问题的原因是用户想要在WPF的TreeView中实现不同的父节点和不同的子节点。用户已经尝试了使用多个HierarchicalDataTemplate,但是对于对象模型感兴趣。

在用户的情况下,有一个具有以下属性的父节点:

Public string Name { get; set; }
Public ObservableCollection ChildrenA { get; set; }
Public ObservableCollection ChildrenB { get; set; }

用户想要在TreeView中显示这些属性。用户想知道如何构建对象模型,因为他们需要在ChildA和ChildB集合的上级级别显示一些内容。

用户还发布了他们的解决方案,并希望能够检查并提出改进意见。

如果这是您所寻找的,请查看以下解决方案。

0
0 Comments

实现具有不同父节点和不同子节点的WPF树视图?

问题的出现原因是,如果这些类中有任何一个类具有共同的基类,那么使用一个DataTemplate就可以为多个类使用。然而,如果每个模型都是不同的,并且没有足够的共同之处,那么就需要使用DataTemplateSelector,尽管内置机制可能已经足够。

解决方法是首先为每种类型创建HierarchicalDataTemplate。如果任何类型不包含子节点,那么当然会为它们创建DataTemplate。由于每个类都继承自List,因此对象本身是子项目的源,而不是属性上的集合。因此,使用ItemsSource="{Binding}"。如果子项目在名为Children的属性下的集合中,那么它将变为ItemsSource="{Binding Children}"。

实现DataTemplateSelector的最简单方法是什么都不做。因为我只指定了DataType而没有在数据模板上使用x:Key,所以即使集合是模糊的(List),WPF仍然会检查底层类型,以确定是否为P1/Q1等,并找到正确的HierarchicalDataTemplate来使用。我的TreeView只需要像这样:

然而,为了向您展示一个不能隐式匹配的DataTemplateSelector,您可以在数据模板上使用x:Key,例如:


    a P1 object

然后,您的选择器可能在内部使用字典来确定给定类型的资源键(请记住,这是一个简单的实现):

public class CustomDataTemplateSelector : DataTemplateSelector {
    static Dictionary typeToKey = new Dictionary();
    static CustomDataTemplateSelector() {
        typeToKey[typeof(P1)] = "myKeyforP1";
    }
    public override DataTemplate SelectTemplate(object item, DependencyObject container) {
        var element = container as FrameworkElement;
        if (element != null && item != null) {
            var itemtype = item.GetType();
            object keyObject;
            if (typeToKey.TryGetValue(itemtype, out keyObject)) {
                var template = element.TryFindResource(keyObject) as DataTemplate;
                if (template != null) {
                    return template;
                }
            }
        }
        return base.SelectTemplate(item, container);
    }
}

然后,您将选择器添加到资源字典中,并且您的TreeView需要分配另一个属性:


    


由于base.SelectTemplate()将尝试将项目的Type作为资源键使用,因此您可以为模型创建一个标准的HierarchicalDataTemplate和一个自定义版本,仅在TreeView使用自定义DataTemplateSelector时才会使用:


    a P1 object


    a P1 that looks much different

感谢您帮助我...我能够使用上面提出的解决方案创建树...尽管我不理解自定义DataTemplateSelector的概念...继续上述场景,我是否需要为根节点创建一个类?我创建的树没有根节点,它从父节点开始...这个结构可以被序列化和反序列化吗?

WPF有自动查找正确DataTemplate的方式,主要是基于模板的DataType与要模板化的对象相同。DataTemplateSelectors用于在显示特定类型时自定义所选择的模板的方式,尤其是当一个类型有多个可能的模板或者想要在任何时候切换它们时。您甚至可以在选择器中创建模板并返回它。

这取决于根节点是否具有自己的属性,或者它只是用于作为P1、Q1、R1等的父节点。如果是后一种情况,创建一个单独的类没有太大意义。我只是创建了一个包含顶级父节点的List,并将其用作数据源。至于序列化,那是一个不同的问题。通常,您可以使用属性为类标记属性,以指导序列化器如何序列化它们。

谢谢,我会按照您提供的指导继续进行。

0