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>();
}
}
我不想显示文件名而不是文件显示它的模式
所以改变数据模板文件
<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" } }