HierarchicalDataTemplate不同的叶子

时间:2010-04-12 21:04:16

标签: c# wpf hierarchicaldatatemplate

我有一组数据结构如下:

 ItemA.GroupA
 ItemB.GroupA
 ItemC.GroupB
 ItemD.GroupC

我需要在WPF树视图中显示数据,如下所示:

A组

--- ItemA

--- ItemB

组B

--- ItemC

C组

--- ItemD

我可以使用什么XAML按叶子分组?例如,集合中可能有多个项目是GroupA.ItemA,但是,我只想呈现节点和叶子一次。

2 个答案:

答案 0 :(得分:1)

你无法在XAML中做到这一点,至少不是以任何自然的方式。更好的方法是引入一个视图模型 - 一个以视图友好的方式表示数据的类,以便您可以保持简单和自然的XAML。

因此,在您的情况下,您将拥有一个包装您的ItemX集合的类,并公开这些组及其不同的成员:

public class MyItemsViewModel
{
  public IList<MyGroupViewModel> Groups { get; }
}

public class MyGroupViewModel
{
  public string GroupName { get; }
  public IList<MyItem> DistinctItems { get; }
}

您的HierarchicalDataTemplate几乎会自动消失。另外一个好处是,因为您的视图模型类只是数据对象,您可以将它们置于自动测试之下,而复杂的XAML需要手动测试。

答案 1 :(得分:1)

我在这里不同意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属性对您的项目集合进行分组。在项目在组中之后,您将创建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