【问题标题】:Nested XAML Treeview Structure with mixed object types具有混合对象类型的嵌套 XAML 树视图结构
【发布时间】:2018-06-29 18:26:33
【问题描述】:

所以我一直在使用 WPF 绑定处理复杂的树视图结构。我在网上找到的所有方案都无法解决问题,但它们已经接近了。

所以我有三个看起来像这样的对象:

public class A
{
    public string Name {get; set;}
    public List<A> ListOfA {get; set;}
    public List<B> ListOfB {get; set;}
}

public class B
{
    public string Name {get; set;}
    public List<C> ListOfC {get; set;}
    public List<D> ListOfD {get; set;}
}

public class C
{
    public string Name {get; set;} 
    public List<D> {get; set;}
}

public class D
{
    public string Name{get; set;}
} 

需要注意的是,ListOfA、ListOfB、ListOfC 和 ListOfD 都可以为空。我知道这看起来很复杂,但是对于我的应用程序来说,我为什么要这样做是很有意义的。

下面是树视图的示例

A - Name
    | - A - Name
        | - B - Name
            | - D - Name
            | - D - Name
            | - D - Name
        | - A - Name
            | - B - Name
                | - C - Name
                    | - D - Name
                    | - D - Name
        | - A - Name
    | - A - Name
        | - A - Name
        | - A - Name
    | - A - Name

所以我想出了如何在 A 类中使用如下内容格式化 A 和 B 的树视图。

public IList Children
    {
        get
        {
            return new CompositeCollection()
            {
                new CollectionContainer() { Collection = ListOfA },
                new CollectionContainer() { Collection = ListOfB }
            };
        }
    }
}

我从这个问题中得到的:WPF Treeview Databinding Hierarchal Data with mixed types

下面是我的 XAML 代码,用 A/B/C 替换真实对象。注意 ListOfA 是视图模型成员。

<TreeView ItemsSource = "{Binding Children}">
    <TreeView.Resources>

        <HierarchicalDataTemplate DataType="{x:Type local:A}" 
         ItemsSource="{Binding Children}">
                <TextBlock Text="{Binding}"/>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type local:B}" 
        ItemsSource="{Binding Children}">
                <TextBlock Text="{Binding Name}"/>
      </HierarchicalDataTemplate>

    </TreeView.Resources>
</TreeView>

这很好用,但我不知道如何在功能上将 D 添加到此树视图。我已经能够通过添加一个树视图项来做到这一点,其中嵌套的树视图包含类型 B 的 HierarchicalDataTemplate 中的 ListOfD,但我知道这不是一个好方法。

我还尝试添加类似:

<DataTemplate DataType={x:Type local:D>
    <TextBlock Text={Binding Name}/>
</DataTemplate>

但这不起作用,我认为是因为并非该“儿童”对象的每个子对象都没有任何 D 类型的对象。我也不确定如何处理 C 类型的对象,但我现在更专注于 D,并且愿意打赌,一旦我让 D 工作,我就会知道如何处理它。

我是否让这变得比它需要的更难,或者我在分层数据模板中嵌套事物是否走在正确的轨道上?

【问题讨论】:

    标签: c# wpf xaml treeview


    【解决方案1】:

    C 只需要一个看起来像这样的模板

    <HierarchicalDataTemplate DataType="{x:Type local:C}" ItemsSource="{Binding ListOfD}">
        <TextBlock Text="{Binding}"/>
    </HierarchicalDataTemplate>
    

    所以你最终会得到:

    <HierarchicalDataTemplate DataType="{x:Type local:A}" ItemsSource="{Binding Children}">
        <TextBlock Text="{Binding}"/>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate DataType="{x:Type local:B}" ItemsSource="{Binding Children}">
         <TextBlock Text="{Binding Name}"/>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate DataType="{x:Type local:C}" ItemsSource="{Binding ListOfD}">
        <TextBlock Text="{Binding Name}"/>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplateDataType="{x:Type local:D}">
        <TextBlock Text="{Binding Name}" />
    </HierarchicalDataTemplate>
    

    和你的班级:

    public class A
    {
        public string Name {get; set;}
        public List<A> ListOfA {get; set;}
        public List<B> ListOfB {get; set;}
        public IList Children
        {
            get
            {
                return new CompositeCollection()
                {
                    new CollectionContainer() { Collection = ListOfA },
                    new CollectionContainer() { Collection = ListOfB }
                };
            }
        }
    }
    
    public class B
    {
        public string Name {get; set;}
        public List<C> ListOfC {get; set;}
        public List<D> ListOfD {get; set;}
        public IList Children
        {
            get
            {
                return new CompositeCollection()
                {
                    new CollectionContainer() { Collection = ListOfC },
                    new CollectionContainer() { Collection = ListOfD }
                };
            }
        }
    }
    
    public class C
    {
        public string Name {get; set;} 
        public List<D> ListOfD {get; set;}
    }
    
    public class D
    {
        public string Name{get; set;}
    }
    

    【讨论】:

    • 哎呀,本来是想问怎么处理D,但我一定会补充的!
    • 哦,如果 DataTemplate 不起作用,请将其更改为 HierarchicalDataTemplate 并且不要指定 ItemsSource
    • 哇,我真的把它复杂化了,谢谢!我现在唯一遇到的问题是 D 的成员出现在 B 下,但不在 C 类型的对象下。
    • 哦,呃,我看到我错过了 C 中 Text 的绑定,应该是 我会修改我的答案。
    猜你喜欢
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    • 2023-01-13
    • 2016-12-08
    • 2023-03-18
    相关资源
    最近更新 更多