问题
I want the parent of a node that is selected as TreeViewItem
I have a Person class with 2 fields. Name(String) and Children(List of string)
This is my xaml code
<Grid x:Name="gridView" Margin="10">
<TreeView Name="treeView1" TreeViewItem.Selected="TreeViewItem_OnItemSelected" ItemsSource="{Binding}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Source=Check, Mode=TwoWay}" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type loc:Person}" ItemsSource="{Binding Children}" >
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
this is my code behind. I set the item source to a list of Person objects.
void set()
{
if (treeView1.Items.IndexOf(treeView1.SelectedItem) != -1)
{
//is a parent
//returns -1 for children
Person selected = (Person)treeView1.SelectedItem;
int index = search(selected);
TreeViewItem parent = treeView1.Tag as TreeViewItem;
setSelected(parent,index);
}
else
{
//is a child
TreeViewItem child = treeView1.Tag as TreeViewItem; //returns the selected node
TreeViewItem parent = child.Parent as TreeViewItem; //returns null
}
}
private void TreeViewItem_OnItemSelected(object sender, RoutedEventArgs e)
{
treeView1.Tag = e.OriginalSource;
int ind = 0;
foreach (var _item in treeView1.Items)
{
if (_item == treeView1.SelectedItem)
{
selectedIndex = ind;
break;
}
ind++;
}
}
In the else part, The child.Parent
always returns null. I tried other methods but none of them return a TreeViewItem
instead they return DependencyObject
or ItemsControl
.
I also tried ContainerFromItem
method but it only works for direct children(parent) and not the children of the parent.
Please help
回答1:
You could use the VisualTreeHelper.GetParent()
method:
https://msdn.microsoft.com/de-de/library/system.windows.media.visualtreehelper.getparent(v=vs.110).aspx
Example Code:
private TreeViewItem FindParentTreeViewItem(object child)
{
try
{
var parent = VisualTreeHelper.GetParent(child as DependencyObject);
while ((parent as TreeViewItem) == null)
{
parent = VisualTreeHelper.GetParent(parent);
}
return parent as TreeViewItem;
}
catch (Exception e)
{
//could not find a parent of type TreeViewItem
return null;
}
}
The while loop is needed, as the visual parent of a tree view item isn't its parent tree view item as can be seen in this WPF Tree Visualizer:
WPF Tree Visualizer showing tree view
回答2:
ItemsSource
is typically a collection of DependencyObject
s which you can bind to. It doesn't reflect any information about UI. What you are looking for is actually the ItemContainer of each Item which is a part of WPF UI.
In most cases you can access a UIElement from another without any problem. But in my experience as the UI gets complicated by Styles, Templates and hierarchical items, some UIElements will be hard to find.
I suggest the following way:
Implement a Parent property in your ViewModel (Person Class) with type of Person and initialize it in the constructor of Person, Then you can get both the parent Person and the parent TreeViewItem like this:
var parentPerson = (treeView1.SelectedItem as Person).Parent;
var parentNode = treeView1.ItemContainerGenerator.ContainerFromItem(parentPerson);
来源:https://stackoverflow.com/questions/26624982/get-parent-treeviewitem-of-a-selected-node-in-wpf