[英]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
获取它,因为它不存在 ,不是您想象的那样,如果它的模型是字符串则无法获取它。 您只能在其父级TreeViewItem
的ItemContainerGenerator
找到该TreeViewItem
。
在这种情况下,您必须递归遍历树,在每个TreeViewItem
的ItemContainerGenerator
找到子容器。
不幸的是,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.