【问题标题】:In WPF, Apply different DataTemplate to the same Item at a different level of TreeView在 WPF 中,将不同的 DataTemplate 应用于不同级别的 TreeView 的同一个 Item
【发布时间】:2013-07-17 19:03:19
【问题描述】:

我遇到了一个奇怪的问题。

我有一个非常基本的递归树结构:

public class TreeNode
{
    public string Name { get; set; }
    public IEnumerable<TreeNode> Children { get; set; }
}

并使用 HierarchicalDataTemplate 在 TreeView 中显示数据,如下所示:

<TreeView Name="_tree">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <StackPanel Orientation="Horizontal" >
                <CheckBox/>
                <TextBlock Text="{Binding Path=Name}"/>
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

我从后面的代码填充树:

//allTreeNodes is a list of all existing Tree objects
public void PopulateTree(List<TreeNode> allTreeNodes)
{
    foreach (var node in allTreeNodes)
    {
        _tree.Items.Add(node);
    }
}

结果是一个 TreeView,每个现有 Tree 对象都作为根节点及其各自的子树。

请注意,每个 TreeNode 可以在树中的多个位置显示,具体取决于它是否具有祖先。

到目前为止,一切正常,但我现在要做的只是为 visual 根节点显示复选框。我尝试使用带有两个 HierarchicalDataTemplates 的 DataTemplateSelector,根据 TreeNode 的附加布尔属性选择模板,但这不起作用,因为 TreeNode 需要使用复选框显示一次,并且可能在没有复选框的情况下显示多次。

感谢任何帮助。

编辑:这里有一些虚拟数据来帮助解释我想要什么。 (还要注意数据中没有循环引用。)

+TreeNodeA
  -TreeNodeB
  -TreeNodeC
    -TreeNodeB
+TreeNodeB
+TreeNodeC
  -TreeNodeB
+TreeNodeD
  -TreeNodeE
    -TreeNodeC
      -TreeNodeB
+TreeNodeE
  -TreeNodeC
    -TreeNodeB

在上面的视图中,只有以+ 开头的节点才应该有复选框。

【问题讨论】:

  • 只是确认一下,你的意思是你可能有周期性引用吗?
  • 我实际上已经确认没有使用 Tarjan 算法的循环引用。
  • 我在TreeView 层次结构中对不同(但继承的)类型进行了类似的设置,如果你不介意你的根节点是一种特殊类型,我可以发布这种方法(尽管我认为下面提到的附加属性可能是更清洁的解决方案)。

标签: c# wpf hierarchicaldatatemplate datatemplateselector


【解决方案1】:

好吧,我不知道任何直接的方法,但您可以做的是创建一个附加属性并将其应用于每个 TreeViewItem 元素。查看更多关于在Overviewexample on StackOverflow 中实现附加属性的信息。

此附加属性将根据级别对 TreeViewItem 应用不同的样式。

除非您以编程方式生成TreeViewItem 层次结构,否则获取级别会有点棘手。

如果没有,您可以在每次注册附加属性调用时通过遍历可视树来计算它。

或者您可以尝试 - 理论上应该可行 - 通过将 RelativeSource 绑定到父级的附加属性并使用 IValueConverter 将其增加 1:

<TreeViewItem TreeViewLevelStyle.Level="{Binding RelativeSource=
         {RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}},
         Converter=IncrementByOneValueConverter}">

免责声明 - 这是一个想法,而不是我之前尝试过的)

【讨论】:

  • 附加属性是我所需要的。谢谢你指点我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-03
  • 2012-11-22
  • 2021-04-22
  • 1970-01-01
  • 2017-09-10
  • 1970-01-01
  • 2014-06-19
相关资源
最近更新 更多