如何为列表创建树形视图<List<int>?

问题描述 投票:0回答:1

我有一个 EntityDisplay 类,其中包含 2 个属性:

public sealed class EntityDisplayObject
{

    public ICollection Collection { get; private set; }

    public string CollectionName { get; private set; }

    public EntityDisplayObject(ICollection collection)
    {
        this.Collection = collection;

        this.CollectionName = $"{this.Collection.GetType().Name [{this.Collection.Count}]";
    }

}

有时收藏会是

List<int>
,但有时会是
List<List<int>

我目前可以使用它来处理列表,但无法找到一种方法来处理嵌套列表。

这是我现在的xaml:

<Grid x:Uid="Grid_4">

    <TreeView x:Uid="TreeView_2"
              Background="Transparent"
              BorderThickness="0"
              Padding="0">

        <TreeViewItem x:Uid="TreeViewItem_1"
                      Header="{Binding CollectionName}">

            <ListBox x:Uid="ListBox_2" MouseDoubleClick="TreeViewItem_MouseDoubleClick"
                     ItemsSource="{Binding Collection}"
                     Background="Transparent"
                     BorderThickness="0">
            </ListBox>

        </TreeViewItem>

    </TreeView>
</Grid>

使用 xaml 的简单列表

对于嵌套列表,我获得了树视图标题和可扩展选项,但它没有将列表显示为第一个屏幕截图,而是给了我(集合)。 当前嵌套列表

c# wpf xaml data-binding treeview
1个回答
0
投票

嵌套列表是一种糟糕的数据结构。这对于树结构来说尤其糟糕。一棵树有一个节点,该节点有子节点。嵌套列表仅提供没有节点的子级(因为每个子级的父级,一个列表,也是一个列表)。您可以创建一个

DataTemplate
来显示此类嵌套列表,但这些树节点不会有标题。

我建议修复您的数据结构,因为这将使您的对象和视图的使用变得更加简单。因此,您可以使用

List<List<int>>
代替
List<EntityDisplay>
。出于性能原因,该示例将
List<T>
替换为
ObservableCollection<T>

EntityDisplay.cs

class EntityDisplay : INotifyPropertyChanged
{
  public ObservableCOllection<EntityDisplay> Children { get; }

  public object Value { get; }

  public EntityDisplay(object value) : this(Enumerable.Empty<EntityDisplay>(), value)
  {
  }

  public EntityDisplay(IEnumerable<EntityDisplay> children, object value)
  {
    this.Children = children;
    this.Value = value;
  }
}

MainWindow.xaml.cs

partial class MainWindow : Window
{
  public ObservableCollection<EntityDisplay> TreeData { get; } 

  public MainWindow()
  {
    InitializeComponent();

    this.Loaded += OnLoaded;
    this.TreeData = new ObservableCollection<EntityDisplay>();
  }

  private void OnLoaded(object sender, RoutedEventArgs e)
  {    
    var rootItem = new EntityDisplay("Root");

    // Create a child without nested children. 
    // Children are a simple list of int values.
    var intChildren = Enumerable.Range(1, 10);
    var simpleChild = new EntityDisplay(intChildren, "Simple child");
    rootItem.Children.Add(simpleChild);

    // Create a child with nested children.
    // Each child contains a list of int values
    IEnumerable<EntityDisplay> nestedChildren = Enumerable
      .Range(11, 10)
      .Select(value => 
        {
          var children = Enumerable.Range(100 * value, 10)
            .Select(childValue => new EntityDisplay(childValue));
          var child = new EntityDisplay(children, value);
        });
    var nestedChildrenParent = new EntityDisplay(nestedChildren, "Nested child #1");
    rootItem.Add(nestedChildrenParent);
  
    // Create another child with nested children.
    // Each child contains a list of int values
    nestedChildren = Enumerable
      .Range(21, 10)
      .Select(value => 
        {
          var children = Enumerable.Range(200 * value, 10)
            .Select(childValue => new EntityDisplay(childValue));
          var child = new EntityDisplay(children, value);
        });
    nestedChildrenParent = new EntityDisplay(nestedChildren, "Nested child #1");
    rootItem.Add(nestedChildrenParent);

    this.TreeData.Add(rootItem);
  }
}

MainWindow.xaml

<Window x:Name="VisualRoot">
  <TreeView ItemsSource={Binding ElementName=VisualRoot, Path=TreeData}">
    <TreeView.ItemTemplate>
      <HierarchicalDataTemplate DataType="{x:Type EntityDisplay}" 
                                ItemsSource="{Binding Children}">
        <TextBlock Text="{Binding Value}" />
      </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
  </TreeView>
</Window>
© www.soinside.com 2019 - 2024. All rights reserved.