简体   繁体   English

wpf TreeView DataTemplate-用树替换元素

[英]wpf TreeView DataTemplate - replace element with tree

Given following model 给定以下模型

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>();
}

I would like to display Storage in TreeView as follows: 我想在TreeView显示Storage ,如下所示:

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

ie display all Stored s that would contain Schema of each file, which is recursive. 即显示所有包含每个文件的SchemaStored ,这是递归的。

I am not sure how to achieve it, my main problem is how to get the Schema to be displayed. 我不确定如何实现它,我的主要问题是如何显示该Schema When I changed my model to wrap Schema in a singleton list, it started to work but I would like to avoid polluting my model with such thing, also still, I don't want to display file name and instead of file display its schema. 当我更改模型以将Schema包装在单例列表中时,它开始起作用,但是我还是想避免用这种东西污染我的模型,而且,我还是不想显示文件名,而不是文件显示其模式。

Another thing I would like to have have a property SelectedStoredItem in my view model and bind it to, well, selected Stored item. 我想在我的视图模型中有一个属性SelectedStoredItem并将其绑定到选定的Stored项。 It can be null if for example some schema node is selected, or be equal to the Stored to which selected node belongs, but I prefer first option. 例如,如果选择了某个模式节点,则可以为null,或者等于所选节点所属的“ Stored ,但是我更喜欢第一个选项。

Here is my xaml, it doesn't do what I want, just displays Stored items and their file names. 这是我的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>

and here is complete code behind 这是后面的完整代码

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>();
    }
}

I don't want to display file name and instead of file display its schema 我不想显示文件名,而不是显示其架构的文件

so change data template for file 因此更改文件的数据模板

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

side note 边注

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

creating a new List inside object initializer is not necessary here. 在这里不需要在对象初始化程序内部创建新的List。 It has already been initialized ( public List<Tree> Children { get; set; } = new List<Tree>(); ) and you can write a like this: 它已经被初始化( public List<Tree> Children { get; set; } = new List<Tree>(); ),您可以编写如下的

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM