问题解释简短:
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
获取父节点元素。
答案 0 :(得分: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>
)。然后,您的问题就找到了TreeViewItem
IGrouping
的相应内容,可以使用ItemContainerGenerator.ContainerFromItem
来完成。您也不能手动创建这样的层次结构,因为如果您将String
项添加到TreeView
中,您怎么能为它添加子项? 如果我们忽略这些怪癖,只要假设你的TreeView
中有这样的模型层次结构:
string Node1
Childs ChildX
Childs ChildY
string Node2
Childs ChildZ
现在你想得到一个孩子的相应TreeViewItem
,说ChildY。你的问题在于,你无法从TreeView.ItemContainerGenerator
获得它,因为它不存在,不像你想象的那样,如果它的模型是一个字符串,你就无法得到它。您只能在其父TreeViewItem
TreeViewItem
中找到ItemContainerGenerator
。
在这种情况下,您必须递归遍历树,在每个TreeViewItem
的{{1}}中找到子容器。
答案 1 :(得分:0)
不幸的是,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
答案 2 :(得分: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..
我希望它会帮助很多人患上同样的问题。虽然解决方案很简单,但我发布了这个,因为我也浪费了太多时间寻找解决方案。