wpf TreeView DataTemplate - 用树

时间:2016-06-26 13:43:43

标签: c# wpf xaml treeview

给出以下模型

class Storage
{
    public List<Stored> StoredItems { get; }
}

class Stored
{
    public string Name { get; set; }
    public List<File> Files { get; } = new List<File>();
}

class File
{
    public string Name { get; set; }
    public Tree Schema { get; set; }
}

class Tree
{
    public string Label { get; set; }
    public List<Tree> Children { get; set; } = new List<Tree>();
}

我想在Storage中显示TreeView,如下所示:

StoredItem1.Name
  File1.Schema.Label
    File1.Schema.Children[0].Label
    File1.Schema.Children[1].Label
      File1.Schema.Children[1].Children.Label
  File2.Schema.Label
StoredItem2.Name

即。显示包含每个文件Stored的所有Schema,这是递归的。

我不知道如何实现它,我的主要问题是如何显示Schema。当我改变我的模型以将Schema包装在单个列表中时,它开始工作但我想避免用这样的东西污染我的模型,同样,我也不想显示文件名而是文件显示其架构。

我希望在我的视图模型中有一个属性SelectedStoredItem并将其绑定到选定的Stored项目。如果例如选择了某个模式节点,或者它等于所选节点所属的Stored,则它可以为null,但我更喜欢第一个选项。

这是我的xaml,它没有做我想要的,只显示Stored项及其文件名。

<Window x:Class="TreeViewTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TreeViewTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:Storage/>
    </Window.DataContext>
    <Grid>
        <TreeView
                ItemsSource="{Binding StoredItems}">
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type local:Stored}"
                                          ItemsSource="{Binding Files}">
                    <TextBlock Text="{Binding Name}"/>
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:File}"
                                          ItemsSource="{Binding Schema}">
                    <TextBlock Text="{Binding Name}"/>
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:Tree}"
                                          ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding Label}"/>
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>
    </Grid>
</Window>

这里是完整的代码

namespace TreeViewTest
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    class Storage
    {
        public Storage()
        {
            StoredItems = new List<Stored>();
            var a1 = new Stored {Name = "Stored1"};
            a1.Files.Add(new File
            {
                Name = "File1",
                Schema = new Tree
                {
                    Label = "1_1",
                    Children = new List<Tree> { new Tree { Label = "1_1_1" } }
                }
            });
            a1.Files.Add(new File
            {
                Name = "File2",
                Schema = new Tree
                {
                    Label = "2_1",
                    Children = new List<Tree> { new Tree { Label = "2_1_1" }, new Tree { Label = "2_1_2" } }
                }
            });

            var a2 = new Stored { Name = "Stored2" };
            a2.Files.Add(new File
            {
                Name = "File1",
                Schema = new Tree
                {
                    Label = "1_1",
                    Children = new List<Tree> { new Tree { Label = "1_1_1" } }
                }
            });

            StoredItems.Add(a1);
            StoredItems.Add(a2);
        }

        public List<Stored> StoredItems { get; }
    }

    class Stored
    {
        public string Name { get; set; }
        public List<File> Files { get; } = new List<File>();
    }

    class File
    {
        public string Name { get; set; }
        public Tree Schema { get; set; }
    }

    class Tree
    {
        public string Label { get; set; }
        public List<Tree> Children { get; set; } = new List<Tree>();
    }
}

1 个答案:

答案 0 :(得分:1)

  

我不想显示文件名而不是文件显示其架构

所以更改文件的数据模板

<HierarchicalDataTemplate DataType="{x:Type local:File}"
                          ItemsSource="{Binding Schema.Children}">
    <TextBlock Text="{Binding Schema.Label}"/>
</HierarchicalDataTemplate>

旁注

Children = new List<Tree> { new Tree { Label = "2_1_1" }, new Tree { Label = "2_1_2" } }

在此处不需要在对象初始化程序内创建新的List。它已经初始化(public List<Tree> Children { get; set; } = new List<Tree>();),您可以这样写

Children = { new Tree { Label = "2_1_1" }, new Tree { Label = "2_1_2" } }