WPF Treeview - 绑定到具有不同深度的集合,并且样式不同

use*_*213 2 wpf treeview

为长篇文章道歉 - 阅读一些关于此的主题,但仍然难以实现.基本上,我有一组对象,定义如下:

public class LibData
{
    public string Name { get; set; }
    ObservableCollection<LibObject> _list;
    public ObservableCollection<LibObject> List { get { return _list; } }

    public LibData(string name, LibDataType type)
    {
        this.Name = name;
        _list = new ObservableCollection<LibObject>();
    }
}
Run Code Online (Sandbox Code Playgroud)

和对象:

public class LibObject
{
    public string Name { get; set; }

    public LibObject(string name)
    {
        this.Name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的主要问题是在XAML中,并为这个TreeView设计样式.我需要为"root"项具有特定样式,并为"leaf"指定特定样式.事实是,绑定列表中的一个项目是"Root-> Leaf",另一个是"Root-> Child-> Leaf".我试过这个:

<TreeView x:Name="myTree" ItemsSource="{x:Static local:myDataList}">
     <TreeView.ItemTemplate>
         <HierarchicalDataTemplate ItemsSource="{Binding Path=List}" >
             <Grid>
                 <StackPanel Orientation="Horizontal">
                      <TextBlock Text="{Binding Path=Name}" />
                      <CheckBox IsChecked="True" Content="HeaderCheckbox"/>
                 </StackPanel>
             </Grid>
         <HierarchicalDataTemplate.ItemTemplate >
              <DataTemplate>
                  <Grid>
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="True" Content="LeafCheckbox" />
                <TextBlock Text="{Binding Path=Name}"/>
            </StackPanel>
                  </Grid>
              </DataTemplate>
          </HierarchicalDataTemplate.ItemTemplate>
      </HierarchicalDataTemplate>
  </TreeView.ItemTemplate>
Run Code Online (Sandbox Code Playgroud)

这显然适用于"Root-> Leaf"项目,但不适用于"Root-Child-Leaf".XAML实现似乎更像是一个"硬编码"解决方案,我知道项目布局总是"Root-> Leaf" - 我如何使这个动态?再一次,我已经看到了不同级别的解决方案(包括使用转换器),但我遇到的问题是我需要根和叶子的特定样式,而不需要其间的级别.我想知道我是否正在看这个完全错误的......

mbu*_*ill 6

简单的方法来做到这一点.将DataTemplates从TreeView中拉出并将它们放在资源部分中.为每个DataTemplate指定DataType属性,但不包括键.TreeView上的ItemTemplateSelector(DataTemplateSelector类型的属性)将使用适合正确项目类型的DataTemplate.

为Root和Child类型创建HierarchicalDataTemplate,为Leaf类型创建DataTemplate.

像这样的东西:

<Window.Resources>
    <ResourceDictionary>

        <DataTemplate DataType="{x:Type local:Leaf}">
            <Grid>
                <StackPanel Orientation="Horizontal">
                    <CheckBox IsChecked="True" Content="LeafCheckbox" />
                    <TextBlock Text="{Binding Path=SomeValue}"/>
                </StackPanel>
            </Grid>
        </DataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type local:Child}"
                                  ItemsSource="{Binding Children}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Child " />
                <TextBlock Text="{Binding Path=SomeValue}" />
            </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type local:Root}"
                                  ItemsSource="{Binding Children}">
            <Grid>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Root " />
                    <TextBlock Text="{Binding Path=SomeValue}" />
                </StackPanel>
            </Grid>
        </HierarchicalDataTemplate>

    </ResourceDictionary>
</Window.Resources>

<Grid>
    <TreeView x:Name="myTree" ItemsSource="{Binding}" />
</Grid>
Run Code Online (Sandbox Code Playgroud)