繁体   English   中英

WPF:TreeView获取父节点

[英]WPF: TreeView get parent node

问题简短说明:

 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转换为TreeViewItem

假设您得到以下

IEnumerable<IGrouping<String, Childs>> treeModel;

并且您想知道子节点属于哪个节点,如何从TreeView获取父节点元素。

原始答案

TreeView.ItemContainerGenerator.ContainerFromItem应该可以解决问题: https//msdn.microsoft.com/zh-cn/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<String, Childs> )。 然后您的问题就变成了找到该IGrouping事物的相应TreeViewItem ,这可以通过ItemContainerGenerator.ContainerFromItem完成。 您也不能手动建立这样的层次结构,因为如果将String项添加到TreeView ,如何为其添加子项?

而且,如果我们忽略了这些怪癖,只需假设您在TreeView具有这样的模型层次结构即可:

 string Node1
     Childs ChildX
     Childs ChildY
 string Node2
     Childs ChildZ

现在,您要获取孩子的对应TreeViewItem ,例如ChildY。 您的问题在这里, 您无法从TreeView.ItemContainerGenerator获取它,因为它不存在 ,不是您想象的那样,如果它的模型是字符串则无法获取它。 您只能在其父级TreeViewItemItemContainerGenerator找到该TreeViewItem

在这种情况下,您必须递归遍历树,在每个TreeViewItemItemContainerGenerator找到子容器。

不幸的是,SO中的所有帖子都指出了错误的解决方案,或者由于我解释的原因,该解决方案可能不再起作用。 (这同样适用于所有Microsoft文档,可能已过时)

似乎没有“ **Built-In**功能,因此决定设计自己的解决方案。 通过创建自定义的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

您将对象强制转换为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..

我希望它能帮助很多遭受同样问题困扰的人。 尽管解决方案非常简单,但是我发布了此信息,因为我也浪费了太多时间寻找解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM