I have a TreeView
which uses a HierarchicalDataTemplate
to bind its data.
It looks like this:
<TreeView x:Name="mainTreeList" ItemsSource="{Binding MyCollection}>
<TreeView.Resources>
<HierarchicalDataTemplate
DataType="{x:Type local:MyTreeViewItemViewModel}"
ItemsSource="{Binding Children}">
<!-- code code code -->
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
Now, from the code-behind of say the main window, I want to get the current selected TreeViewItem
. However, if I use:
this.mainTreeList.SelectedItem;
The selectedItem is of type MyTreeViewItemViewModel
. But I want to get the 'parent' or 'bound' TreeViewItem
. I do not pass that to my TreeViewItemModel
object (wouldn't even know how).
How can I do this?
TreeViewItem item = (TreeViewItem)(mainTreeList
.ItemContainerGenerator
.ContainerFromIndex(mainTreeList.Items.CurrentPosition));
DOES NOT WORK (for me) as mainTreeList.Items.CurrentPosition in a treeview using a HierarchicalDataTemplate will always be -1.
NEITHER DOES below as as mainTreeList.Items.CurrentItem in a treeview using a HierarchicalDataTemplate will always be null.
TreeViewItem item = (TreeViewItem)mainTreeList
.ItemContainerGenerator
.ContainerFromItem(mainTreeList.Items.CurrentItem);
INSTEAD I had to set a the last selected TreeViewItem in the routed TreeViewItem.Selected event which bubbles up to the tree view (the TreeViewItem's themselves do not exist at design time as we are using a HierarchicalDataTemplate).
The event can be captured in XAML as so:
<TreeView TreeViewItem.Selected="TreeViewItemSelected" .../>
Then the last TreeViewItem selected can be set in the event as so:
private void TreeViewItemSelected(object sender, RoutedEventArgs e)
{
TreeViewItem tvi = e.OriginalSource as TreeViewItem;
// set the last tree view item selected variable which may be used elsewhere as there is no other way I have found to obtain the TreeViewItem container (may be null)
this.lastSelectedTreeViewItem = tvi;
...
}
From Bea Stollnitz's blog entry about this, try
TreeViewItem item = (TreeViewItem)(mainTreeList
.ItemContainerGenerator
.ContainerFromIndex(mainTreeList.Items.CurrentPosition));
I ran into this same problem. I needed to get to the TreeViewItem so that I could have it be selected. I then realized that I could just add a property IsSelected to my ViewModel, which I then bound to the TreeViewItems IsSelectedProperty. This can be achieved with the ItemContainerStyle:
<TreeView>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
Now if I want to have an item in the treeview selected, I just call IsSelected on my ViewModel class directly.
Hope it helps someone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With