I have a data-bound TreeView
and I want to bind SelectedItem
. This attached behavior works perfectly without HierarchicalDataTemplate
but with it the attached behavior only works one way (UI to data) not the other because now e.NewValue
is MyViewModel
not TreeViewItem
.
This is a code snippet from the attached behavior:
private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var item = e.NewValue as TreeViewItem;
if (item != null)
{
item.SetValue(TreeViewItem.IsSelectedProperty, true);
}
}
This is my TreeView
definition:
<Window xmlns:interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<TreeView ItemsSource="{Binding MyItems}" VirtualizingStackPanel.IsVirtualizing="True">
<interactivity:Interaction.Behaviors>
<behaviors:TreeViewSelectedItemBindingBehavior SelectedItem="{Binding SelectedItem, Mode=TwoWay}" />
</interactivity:Interaction.Behaviors>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:MyViewModel}" ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Window>
If I can get a reference to the TreeView
in the attached behavior method OnSelectedItemChanged
, maybe I can use the answers in this question to get the TreeViewItem
but I don't know how to get there. Does anyone know how and is it the right way to go?
Here is an improved version of the above mentioned attached behavior. It fully supports twoway binding and also works with
HeriarchicalDataTemplate
andTreeView
s where its items are virtualized. Please note though that to find the 'TreeViewItem' that needs to be selected, it will realize (i.e. create) the virtualizedTreeViewItem
s until it finds the right one. This could potentially be a performance problem with big virtualized trees.And for the sake of completeness hier is the implementation of
GetVisualDescentants
:I know this is old question, but perhaps it will be helpful for others. I combined a code from Link
And it looks now:
If you find, like I did, that this answer sometimes crashes because
itemPresenter
is null, then this modification to that solution might work for you.Change
OnSelectedItemChanged
to this (if the Tree isn't loaded yet, then it waits until the Tree is loaded and tries again):