树视图和键绑定
本文关键字:绑定 视图 | 更新日期: 2023-09-27 18:09:02
我正试图使用这里描述的技术(第一个答案)在我的TreeView项目上设置键绑定。所以我有一个XAML中的TreeView,一个在TreeView项目的ViewModel中定义的iccommand属性,以及一个注册附加属性以支持TreeViewItem风格的键绑定的helper类。但是每次这个命令只在我的TreeView的第一个项目上被调用,不管哪个项目实际被选中了。为什么会这样,我该如何解决?或者可能有一些更好的方法来设置键绑定在TreeViewItems不打破MVVM模式?
XAML
<TreeView x:Name="tr" ItemsSource="{Binding Root}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="local:AttachedTVIBinding.InputBindings">
<Setter.Value>
<InputBindingCollection>
<KeyBinding Key="A" Command="{Binding SomeCommand}"/>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding SomeCommand}"/>
</InputBindingCollection>
</Setter.Value>
</Setter>
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
节点的视图模型
public class ConfigurationNodeViewModel : INotifyPropertyChanged
{
private DelegateCommand _someCommand;
public DelegateCommand SomeCommand
{
get { return _editDesignCommand; }
}
}
Helper类(与提供的链接完全相同)
public class AttachedTVIBinding : Freezable
{
public static readonly DependencyProperty InputBindingsProperty =
DependencyProperty.RegisterAttached("InputBindings", typeof(InputBindingCollection), typeof(AttachedTVIBinding),
new FrameworkPropertyMetadata(new InputBindingCollection(),
(sender, e) =>
{
var element = sender as UIElement;
if (element == null) return;
element.InputBindings.Clear();
element.InputBindings.AddRange((InputBindingCollection)e.NewValue);
}));
public static InputBindingCollection GetInputBindings(UIElement element)
{
return (InputBindingCollection)element.GetValue(InputBindingsProperty);
}
public static void SetInputBindings(UIElement element, InputBindingCollection inputBindings)
{
element.SetValue(InputBindingsProperty, inputBindings);
}
protected override Freezable CreateInstanceCore()
{
return new AttachedTVIBinding();
}
}
这是一个迟了3年的答案,但可能对某人有用。
解决方案是通过设置x:Shared="False"来应用包含KeyBinding和MouseBinding元素的非共享资源。这允许创建多个InputBindingCollection实例,因为WPF默认只创建一个样式实例。
<InputBindingCollection x:Key="myBindings" x:Shared="False">
<KeyBinding Key="A" Command="{Binding SomeCommand}"/>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding SomeCommand}"/>
</InputBindingCollection>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="local:AttachedTVIBinding.InputBindings" Value="{DynamicResource myBindings}"/>
</Style>
请注意,x:Shared只能在已编译的ResourceDictionary中使用。你也可以使用相同的ResourceDictionary,你已经为TreeViewItem定义了一个样式,但是InputBindingCollection需要放在这个样式的上面。