c# – 使用CommandParameter在树视图项上进行键绑定
发布时间:2020-12-16 01:47:39 所属栏目:百科 来源:网络整理
导读:我正在尝试使用带有KeyBinding的TreeViewItem和MenuContext来执行位于我的ViewModel上的命令. 目前,使用上下文菜单,在正确的ViewModel实例上调用该命令. 但是,当我选择TreeViewItem并按“C”键时,将在“根”ViewModel上调用该命令. 我也尝试过扩展KeyBinding
我正在尝试使用带有KeyBinding的TreeViewItem和MenuContext来执行位于我的ViewModel上的命令.
目前,使用上下文菜单,在正确的ViewModel实例上调用该命令. 我也尝试过扩展KeyBinding类(Keybinding a RelayCommand)而没有运气. 也许我会走错路:我只想显示正确的MessageBox,如果我使用上下文菜单或键. 名为WpfTest的WPF项目的代码示例. MainWindow.xaml <Window x:Class="WpfTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="clr-namespace:WpfTest" Title="MainWindow" Height="350" Width="525"> <Grid> <TreeView ItemsSource="{Binding}"> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Child}" DataType="{x:Type vm:ViewModel}"> <TextBlock Text="{Binding Name}" /> </HierarchicalDataTemplate> </TreeView.ItemTemplate> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <Setter Property="ContextMenu"> <Setter.Value> <ContextMenu> <MenuItem Header="{Binding Name}" Command="{Binding SomeCommand}" CommandParameter="{Binding}"/> </ContextMenu> </Setter.Value> </Setter> <Setter Property="vm:MyAttached.InputBindings"> <Setter.Value> <InputBindingCollection> <KeyBinding Key="C" Command="{Binding SomeCommand}" CommandParameter="{Binding}"/> </InputBindingCollection> </Setter.Value> </Setter> </Style> </TreeView.ItemContainerStyle> </TreeView> </Grid> </Window> MainWindow.xaml.cs: namespace WpfTest { using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Windows; using System.Windows.Input; public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.DataContext = new List<ViewModel> { new ViewModel { Name = "Parent",Child = new ObservableCollection<ViewModel> { new ViewModel { Name = "Child 1" },new ViewModel { Name = "Child 2" },new ViewModel { Name = "Child 3" } } } }; } } public class ViewModel { public string Name { get; set; } public ObservableCollection<ViewModel> Child { get; set; } public ICommand SomeCommand { get; set; } public ViewModel() { this.SomeCommand = new RelayCommand<ViewModel>(OnCommandExecuted); } private void OnCommandExecuted(ViewModel parameter) { MessageBox.Show("CommandExecuted on " + Name + " with parameter " + parameter.Name); } } public class MyAttached { public static readonly DependencyProperty InputBindingsProperty = DependencyProperty.RegisterAttached("InputBindings",typeof(InputBindingCollection),typeof(MyAttached),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); } } public class RelayCommand<T> : ICommand { readonly Action<T> _execute = null; public RelayCommand(Action<T> execute) { _execute = execute; } public bool CanExecute(object parameter) { return true; } public void Execute(object parameter) { _execute((T)parameter); } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } } } 解决方法
问题是:Style只为所有ListViewItem创建一个InputBindingCollection,因此您必须非常小心Setter.Values.
这是修复: <TreeView ItemsSource="{Binding}"> <TreeView.Resources> <!-- x:Shared="False" forces the new creation of that object whenever referenced --> <InputBindingCollection x:Shared="False" x:Key="InputBindings"> <KeyBinding Key="C" Command="{Binding SomeCommand}" CommandParameter="{Binding}" /> </InputBindingCollection> </TreeView.Resources> <!-- ... --> <TreeView.ItemContainerStyle> <Style TargetType="{x:Type TreeViewItem}"> <!-- ... --> <Setter Property="vm:MyAttached.InputBindings" Value="{StaticResource InputBindings}"/> </Style> </TreeView.ItemContainerStyle> </TreeView> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |