我有一个典型的树视图和一个视图模型。 viewmodel有一个可观察的其他视图模型集合,用作树的数据源。
public class TreeViewVM {
public ObservableCollection<ItemVM> Items { get; private set; }
public ItemVM SelectedItem { get; set; }
}
和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; }
}
观点:
<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>
然而,无论我尝试什么,只要它在HierarchicalDataTemplate的“内部”,我的命令就不会被调用。
如果我将TreeView.InputBindings中的KeyBinding(以及从ItemVM中的ICommand / RelayCommand移动到TreeViewVM)一切都很好,则会调用该命令。
但是我想在ItemVM上使用命令(因为它是有意义的)。有什么想法吗?
答案 0 :(得分:7)
但是我想在ItemVM上使用命令(因为它是有意义的)。有什么想法吗?
如果TreeViewVM
通过SelectedItem
属性跟踪所选项目,您可以在InputBindings
上定义TreeView
并仍然在ItemVM
上执行命令:< / p>
<TreeView ItemsSource="{Binding Items}">
<TreeView.InputBindings>
<KeyBinding Key="F2" Command="{Binding SelectedItem.Rename}"/>
</TreeView.InputBindings>
</TreeView>
注意如何使用子属性语法SelectedItem.Rename
来使用ItemVM
作为绑定的来源。
不幸的是,绑定到TreeView
上的所选项目有点单调乏味。您不能直接绑定到SelectedItem
(正如您的XAML似乎建议的那样),但存在various methods to overcome this limitation。我喜欢的一个简单方法是使用Blend Interativity:
<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>
您必须在SetSeletectedItemCommand
上实施设置属性TreeViewVM
的{{1}}。
答案 1 :(得分:5)
需要在TreeViewItem上定义键绑定,因为它是具有焦点的元素。问题是你无法使用Style定义键绑定,这是你可能想要在这里做的。
Here是一种解决方法,它使用自定义附加属性通过Style将项添加到InputBinding集合。所以你想使用类似的东西来定义你的Style,你将它分配给TreeView.ItemContainerStyle。