wpf TreeView数据模板-用树代替元素

本文关键字:元素 TreeView 数据 wpf | 更新日期: 2023-09-27 17:49:18

给定以下模型

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

我想在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

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

我不确定如何实现它,我的主要问题是如何得到Schema显示。当我改变我的模型包装Schema在一个单例列表,它开始工作,但我想避免污染我的模型与这样的事情,也仍然,我不想显示文件名,而不是文件显示其模式。

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

这是我的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>();
    }
}

wpf TreeView数据模板-用树代替元素

我不想显示文件名而不是文件显示它的模式

所以改变数据模板文件

<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" } }