KeyBinding on TreeViewItem

I have a typical tree view and viewmodel. The viewmodel has an observable collection of other models that serve as a data source for the tree.

public class TreeViewVM { public ObservableCollection<ItemVM> Items { get; private set; } public ItemVM SelectedItem { get; set; } } 

and ItemVM:

 public class ItemVM { public string Name { get; set; } public ImageSource Image { get; private set; } public ObservableCollection<ItemVM> Children { get; private set; } public ICommand Rename { get; private set; } } 

View:

 <TreeView Selecteditem="{Binding SelectedItem}" ItemsSource="{Binding Items}"> <TreeView.ItemTemplate> <HierarchicalDataTemplate> <StackPanel Orientation="Horizontal"> <StackPanel.InputBindings> <KeyBinding Key="F2" Command="{Binding Rename}"/> </StackPanel.InputBindings> <Image Source="{Binding Image}"/> <TextBlock Text="{Binding Name}"/> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView> 

However, my command will not be called no matter what I try, while it is inside the "HierarchicalDataTemplate".

If I moved KeyBinding to TreeView.InputBindings (and ICommand / RelayCommand from ItemVM to TreeViewVM), everything will be fine, the command will be called.

But I would like to have a command in ItemVM (as it makes sense). Any ideas?

+8
wpf key-bindings treeview treeviewitem
source share
2 answers

Key binding must be defined in the TreeViewItem, since it is an element with focus. The problem is that you cannot define key bindings using the style that you probably want to do here.

Here is one workaround that uses a custom attached property to add items to the InputBinding collection through style. So you want to use something like this to define your style, which you would assign to TreeView.ItemContainerStyle.

+6
source share

But I would like to have a team on ItemVM (since exactly where it makes sense). Any ideas?

If TreeViewVM tracks the selected item through the SelectedItem property, you can define InputBindings in the TreeView and still have the commands implemented in ItemVM :

 <TreeView ItemsSource="{Binding Items}"> <TreeView.InputBindings> <KeyBinding Key="F2" Command="{Binding SelectedItem.Rename}"/> </TreeView.InputBindings> </TreeView> 

Notice how the syntax of the SelectedItem.Rename ItemVM used to use ItemVM as the binding source.

Unfortunately, snapping to a selected item on a TreeView bit tedious. You cannot directly contact SelectedItem (as your XAML seems to suggest), but there are various methods to overcome this limitation .

One easy way is to use mix interactivity :

 <TreeView Name="treeView" ItemsSource="{Binding Items}"> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectedItemChanged"> <i:InvokeCommandAction Command="{Binding SetSelectedItemCommand}" CommandParameter="{Binding SelectedItem, ElementName=treeView}" /> </i:EventTrigger> </i:Interaction.Triggers> </TreeView> 

You will need to implement SetSeletectedItemCommand in TreeViewVM , which sets the SelectedItem property.

+8
source share

All Articles