【发布时间】:2015-10-21 03:23:46
【问题描述】:
我一直在浏览教程并在线阅读一些关于树视图中多种类型的文章。但是,我没有遇到过解释如何构建或处理包含多个嵌套的不同节点类型的树视图的教程。例如考虑一个典型的文件夹结构。一个文件夹可以包含文件和文件夹,其中的文件夹可以包含更多的文件和文件夹。因此,我试图将其分解为一个简单的解决方案,希望有人可以修改/向我解释如何让一个家庭嵌套在另一个家庭中,如下图所示。另一个堆栈溢出的链接没有详细解释 INode 接口是如何工作的。
根据我的阅读,我知道我需要三个课程。
-
第 1 类:FamilyNode
- 该类包含 3 个属性 Members、Name、Parent
-
第 2 类:家庭成员
- 该类包含 2 个属性名称、年龄
-
第 3 类:INode
- 此类包含 1 个属性名称。为此类创建 INode 接口将允许我们在 Treeview 中创建所需的每个内容项的不同实现。我相信这个类的一个例子会像这样......
public interface INode
{
string Name { get; }
string Path { get; }
}
下面是上图中“当前”下的代码。我知道它没有以最好的方式组织起来,我只是想得到一个简单的例子和解释。我希望你们能提供帮助,这很费时间研究。我只是可以围绕如何制作可能是 Family 或 FamilyMember 类型的节点集合,然后开始构建树视图。谢谢大家的帮助。
ViewModel.cs
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace WpfApplication1
{
public class ViewModel : INotifyPropertyChanged
{
private ObservableCollection<Family> families;
public ObservableCollection<Family> Families
{
get { return families; }
set
{
families = value;
NotifyPropertyChanged("Families");
}
}
public ViewModel()
{
// FAMILIES
Families = new ObservableCollection<Family>();
Family family1 = new Family() { Name = "The Doe's" };
family1.Members.Add(new FamilyMember() { Name = "John Doe", Age = 42 });
family1.Members.Add(new FamilyMember() { Name = "Jane Doe", Age = 39 });
family1.Members.Add(new FamilyMember() { Name = "Sammy Doe", Age = 13 });
Families.Add(family1);
Family family2 = new Family() { Name = "The Moe's" };
family2.Members.Add(new FamilyMember() { Name = "Mark Moe", Age = 31 });
family2.Members.Add(new FamilyMember() { Name = "Norma Moe", Age = 28 });
Families.Add(family2);
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class Family
{
public Family()
{
this.Members = new ObservableCollection<FamilyMember>();
}
public string Name { get; set; }
public ObservableCollection<FamilyMember> Members { get; set; }
}
public class FamilyMember
{
public string Name { get; set; }
public int Age { get; set; }
}
}
MainWindow.Xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:self="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="305"
WindowStartupLocation="CenterScreen">
<Window.DataContext>
<self:ViewModel/>
</Window.DataContext>
<Grid>
<TreeView Name="trvFamilies" ItemsSource="{Binding Families}" Grid.Row="1" Grid.ColumnSpan="2">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type self:Family}" ItemsSource="{Binding Members}">
<StackPanel Orientation="Horizontal">
<Label VerticalAlignment="Center" FontFamily="WingDings" Content="1"/>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type self:FamilyMember}">
<StackPanel Orientation="Horizontal">
<Label VerticalAlignment="Center" FontFamily="WingDings" Content="2"/>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Window>
【问题讨论】:
-
我不能代表 WPF,但是在 winforms 中,您可以为每个节点类型分配一个 Tag 并按照它来操作。
-
是的,这根本不适用于 wpf
-
你能解释一下this answer 怎么不能满足你的需要吗?在我看来,您在这里提出的所有问题都已在您之前的帖子中得到解答。
-
在您单击每个单独的节点之前,该帖子不会填充树视图。在这种情况下,我不是试图模仿文件目录。只是想更好地了解它的工作原理。