我不同意 itowlson 的观点。这不是一个棘手的问题,HierarchicalDataTemplate 就是为这种事情而设计的。在您随意深入研究模式和视图模型以及其他不必要的混淆之前,请考虑您的问题可以通过两个类和一个 Linq GroupBy 语句来解决。
这是你的课程:
public class GroupItem
{
public string Name
{
get;
private set;
}
public string Group
{
get;
private set;
}
public GroupItem(string name, string group)
{
Name = name;
Group = group;
}
}
public class Group
{
public IEnumerable<GroupItem> Children
{
get;
set;
}
public string Name
{
get;
private set;
}
public Group(string name)
{
Name = name;
}
}
到目前为止,一切都很好。你有两个简单的类来保存所有必要的数据。名称和组存储为字符串。 Group 有一个 GroupItem 集合。现在查看Window 中的代码:
public partial class DistinctLeaves : Window
{
public ObservableCollection<GroupItem> Items
{
get;
set;
}
public IEnumerable<Group> Groups
{
get;
set;
}
public DistinctLeaves()
{
Items = new ObservableCollection<GroupItem>();
Items.Add(new GroupItem("Item A", "Group A"));
Items.Add(new GroupItem("Item B", "Group A"));
Items.Add(new GroupItem("Item C", "Group B"));
Items.Add(new GroupItem("Item D", "Group C"));
Groups = Items.
GroupBy(i => i.Group).
Select(g => new Group(g.Key) { Children = g });
InitializeComponent();
}
}
再一次,除了 group-by 行之外,这都是样板文件。该声明值得进一步调查。这将根据它们的Group 属性对您的项目集合进行分组。将项目分组后,然后创建Group 类的新实例。传入组的名称属性(这是键),并将子项设置为组本身,然后ta-da!
最后,这是Window 的XAML,它使用HierarchicalDataTemplate:
<Window x:Class="TestWpfApplication.DistinctLeaves"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DistinctLeaves" Height="300" Width="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<TreeView ItemsSource="{Binding Groups}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
结果如下:
alt text http://img339.imageshack.us/img339/8555/distinctleaves.jpg