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

标签 c# wpf

我想获取对象的平面列表并使用自定义组将它们呈现在 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; }
}

例如...用户可能希望看到此列表,其中顶级组是“状态”,第二级是“姓名”。这一切都需要从 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”)。


阅读下面的问题后,我想出了一个更好的问题...

我的问题:是否可以为显示应用于 CollectionViewSource 的自定义组的 TreeView 使用通用的 HierarchicalDataTemplate。

最佳答案

老实说,这应该被标记为 WPF 中的错误。我也尝试过,发现 Documents.View.GroupsView 属性为 null 时抛出绑定(bind)错误。

还有

 <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>

现在为了使绑定(bind)生效,我必须引入一个转换器,它只返回 Groups

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

    ....
}

并且 TreeView 绑定(bind)被这样改变了......

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

然后这对我有用。

这对你有帮助吗?

关于c# - 在 TreeView 中动态分组/嵌套平面数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7512041/

相关文章:

wpf - 在 Wpf 中创建垂直菜单

.net - 从wpf打印的xps文档-太短,纸张尺寸奇怪吗?

c# - 如何对可观察集合进行排序?

c# - 从 Windows Phone 8.1 WinRT 相机预览中捕获 WriteableBitmap

c# - 使用不同的界面使用 Web 服务

c# - ExcelDataReader 在某些情况下不读取 xls 文件

c# - 如何使用 C# 从字节数组为 WPF 媒体元素创建源?

c# - 我在 VS2017 中启动的项目不会在 VS2019 : error CS1061 上构建

c# - SQL 或平面文件访问哪个更有效?

c# - C# 中的列表切片