WPF:TreeView获取父节点

3

问题简述:

 Node 1
     Child x
     Child Y
 Node 2
     Child z

当处理 TreeView 类型时,选择父节点时,SelectedItem 属性返回一个 TreeViewItem 类型的对象,并且以下内容可以正常工作。

 TreeViewItem parentNode = (TreeViewItem) treeView.SelectedItem;

在此期间,当选择节点的值时,该属性返回一个String,这意味着在这种情况下以下内容是正确的:
 Boolean valueType = treeView.SelectedItem is String; --> True 

因此,我们不能再将该对象转换为 TreeViewItem
假设您已经获得了以下内容:
IEnumerable<IGrouping<String, Childs>> treeModel;

如果您想知道子节点属于哪个节点,那么您应该如何从 TreeView 中获取父节点元素。

3个回答

0

关于将对象转换为TreeViewItem,你是正确的。每次都会返回null。我遇到了和你非常类似的问题,这是我找到的解决办法。

Node GetSelectedParentNode(){
object selectedItem = treeView.SelectedItem;
if(selectedItem == null)
    return null;   // No item is selected in treeview
else if(selectedItem is Node)
    return selectedItem;      // You already have a parent node selected
else if(selectedItem is Child)
    return FindParentNode(selectedItem as Child);   // Your main task
else
    return null;  // Exception case...
}

这是一个用于搜索子节点的父节点的主要函数。
Node FindParentNode(Child child){
    // assume you have some list of Node binding to treeview
    foreach(Node node in NodesList)
         if(node.childs.Contains(child)
             return node;      // here is your target parent node
    return null;   // Exception case..
}

现在你可以将这段代码用作
Node parentNode = GetSelectedParentNode();
// Do your stuff here..

我希望这能帮助很多遇到同样问题的人。虽然解决方案非常简单,但我发帖是因为我自己也浪费了太多时间寻找解决方法。


0

原始答案

TreeView.ItemContainerGenerator.ContainerFromItem应该可以解决问题:https://msdn.microsoft.com/en-us/library/system.windows.controls.itemcontainergenerator.containerfromitem(v=vs.110).aspx

新的答案

首先,你有一个类型为IEnumerable<IGrouping<String, Childs[]>>的树模型,这很奇怪:

  • 难道不应该是 IEnumerable<IGrouping<String, Childs>> 吗?否则,你将会有一个 Childs 数组作为节点的模型,而不是一个单独的 Childs
  • 你如何将模型与树绑定?如果你绑定它们,你永远不会得到一个具有 String 模型的父节点,因为它应该是类型为 IGrouping<String, Childs[]>(或者如果接受上一个观点,则为 IGrouping<String, Childs>)。然后你的问题变成了找到那个 IGrouping 事物对应的 TreeViewItem,这可以通过使用 ItemContainerGenerator.ContainerFromItem 来完成。你也不能手动创建这样的层次结构,因为如果你向 TreeView 添加一个 String 项,你怎么能为它添加子项呢?

如果我们忽略这些怪癖,假设你在你的 TreeView 中有这样的模型层次结构:

 string Node1
     Childs ChildX
     Childs ChildY
 string Node2
     Childs ChildZ

现在你想要获取一个子项的对应的TreeViewItem,比如ChildY。你的问题是,你无法从TreeView.ItemContainerGenerator中获取它,因为它不在那里,不像你所假设的那样,如果它的模型是一个字符串,你就无法获取它。你只能在其父级TreeViewItem的ItemContainerGenerator中找到那个TreeViewItem。
在这种情况下,你必须递归地遍历树,找到每个TreeViewItem的子项的容器。

不可能有任何可能性可以按照我所说的“值类型是String”来工作。 - undefined
好的,请检查我的修订答案。 - undefined
@"IEnumerable<IGrouping<String, Childs[]>>": 是的,你说得对,那是个打字错误,它是一个实体对象而不是一个数组。 - undefined

0
很不幸,SO上的所有帖子都指出了错误的解决方案,或者是由于我解释的原因可能已经不再适用的解决方案。(同样适用于所有微软文档,可能已过时)
看起来没有内置功能可以解决这个问题,所以决定设计自己的解决方案。可以通过创建一个自定义的TreeViewItem类并添加一个ParentNodeValue属性来解决这个问题。
public class AdvancedTreeViewItem<T>: TreeViewItem{
    public T ParentNodeValue {get; set;}
    public T RootParentNodeValue {get; set;}
}

我们可以通过以下方式获取节点的值:

var selectedValue = (AdvancedTreeViewItem<String>)treeView.SelectedItem;
MessageBox.Show(selectedValue.RootParentNodeValue);

在这种方法中,SelectedItem属性不可能返回一个String

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接