在TreeView中动态分组/嵌套平面数据

本文关键字:嵌套 平面 数据 TreeView 动态 | 更新日期: 2023-09-27 18:09:33

我想采用对象的平面列表,并使用自定义组在TreeView中呈现它们。

public enum DocumentType { Current, Inactive, Transition, Checkpack, TechLog, Delivery }
public enum Status { Approved, Rejected, Pending }
public class Document
{
    public string Name { get; set; }
    public DateTime Created { get; set; }
    public string CreatedBy { get; set; }
    public DateTime Modified { get; set; }
    public string ModifiedBy { get; set; }
    public DocumentType Type { get; set; }
    public Status Status { get; set; }
}
例如

…用户可能希望看到这个列表,其中顶级组是"Status",第二级组是"Name"。这一切都需要从UI配置,我正在努力找到实现它的最佳方法。

我已经简要地看了一下CollectionViewSource对象,但是找不到一个好的方法来动态地构建一个TreeView。

我的直觉是,我需要在XAML中做一些聪明的模板-这是我目前为止得到的…

<Window.Resources>
    <DataTemplate x:Key="DocumentTemplate">
        <DockPanel>
            <TextBlock Text="{Binding Name}" />
        </DockPanel>
    </DataTemplate>
    <HierarchicalDataTemplate x:Key="GroupTemplate"
                              ItemsSource="{Binding Path=Items}"
                              ItemTemplate="{StaticResource DocumentTemplate}">
        <TextBlock Text="{Binding Path=Name}" />
    </HierarchicalDataTemplate>
</Window.Resources>
<Grid>
    <TreeView ItemsSource="{Binding Documents.View.Groups}"
              ItemTemplate="{StaticResource GroupTemplate}"/>
</Grid>


    public CollectionViewSource Documents
    {
        get
        {
            var docs = new CollectionViewSource();
            docs.Source = DocumentFactory.Documents;
            docs.GroupDescriptions.Add(new PropertyGroupDescription("CreatedBy"));
            return docs;
        }
    }

当然,这只显示顶级组("CreatedBy")。


看了下面的一个问题后,我想出了一个更好的问题…

我的问题:是否有可能有一个通用的HierarchicalDataTemplate为TreeView显示自定义组应用于CollectionViewSource.

在TreeView中动态分组/嵌套平面数据

老实说,这应该被标记为WPF中的一个bug。我也试过了,发现Documents.View.Groups抛出绑定错误,View属性为null。

 <TextBlock Text="{Binding Path=Name}" />

GroupTemplate中正确,在DocumentTemplate中不正确。注意,Groups是特殊类型GroupItem,其中Name是这样一个属性,它保存了分组发生的值。

另一方面,在DocumentTemplate中,我们应该参考我们需要在叶子节点项上显示的属性,例如,在我的示例中,我使用Employee.FirstName(我在Gender上分组)。

 <DataTemplate x:Key="DocumentTemplate">
      <DockPanel>
          <TextBlock Text="{Binding FirstName}" />
      </DockPanel>
 </DataTemplate>

现在,为了使绑定生效,我必须引入一个简单返回Groups的转换器。

public class GroupsConverter : IValueConverter
{
    public object Convert(object value, ...)
    {
        return ((CollectionViewSource)value).View.Groups;
    }
    ....
}

和树视图绑定是这样改变的…

<TreeView x:Name="treeView"                  
          ItemsSource="{Binding Path=Documents,
                                Converter={StaticResource GroupsConverter}}"
          ItemTemplate="{StaticResource GroupTemplate}" />

然后这对我有用。

这个对你有帮助吗?