在DataGrid中一致使用ICommand和InputBindings

本文关键字:ICommand InputBindings DataGrid | 更新日期: 2023-09-27 18:18:18

我正在尝试创建一个具有以下功能的DataGrid:

  • 只读数据网格,但通过双击和单独的编辑表单(双击特定行)提供编辑功能
  • 调用新建/编辑/删除表单的上下文菜单(右键单击整个DataGrid)
  • 删除键,调用删除表单(特定选定行)

我认为这将是一个好主意使用iccommand,所以我创建了一个DataGrid像这样:

public class MyDataGrid : DataGrid {
    public static readonly RoutedCommand NewEntry = new RoutedCommand();
    public static readonly RoutedCommand EditEntry = new RoutedCommand();
    public static readonly RoutedCommand DeleteEntry = new RoutedCommand();
    public MyDataGrid() {
        CommandBindings.Add(new CommandBinding(NewEntry, ..., ...));
        CommandBindings.Add(new CommandBinding(EditEntry, ..., ...));
        CommandBindings.Add(new CommandBinding(DeleteEntry, ..., ...));
        InputBindings.Add(new InputBinding(DeleteCommand, new KeyGesture(Key.Delete)));
        InputBindings.Add(new MouseBinding(EditEntry, new MouseGesture(MouseAction.LeftDoubleClick)));
        // ContextMenu..working fine
    }
}

然后我意识到,双击一行不工作,所以我添加了这个:

LoadingRow += (s, e) =>
    e.Row.InputBindings.Add(new MouseBinding(EditEntry,
        new MouseGesture(MouseAction.LeftDoubleClick)));

当然,删除键也不起作用,我添加了这个:

PreviewKeyDown += (s, e) => { if(e.Key == Key.Delete) { ... } };

为什么我必须这样做?使用命令的全部意义不就是为了防止这种对事件的攻击吗?我错过什么了吗?

在我简单而完美的世界里,我想在CanExecute方法中决定是否适合处理命令,而不是订阅大量不同的事件处理程序。

在DataGrid中一致使用ICommand和InputBindings

通常我使用Style将命令附加到DataGridCell

下面是使用自定义AttachedCommandBehavior

的示例
<Style TargetType="{x:Type DataGridCell}">
    <Setter Property="my:CommandBehavior.Command" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MyView}}, Path=DataContext.ShowPopupCommand}" />
    <Setter Property="my:CommandBehavior.CommandParameter" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}, Path=DataContext}" />
    <Setter Property="my:CommandBehavior.Event" Value="MouseDoubleClick" />
</Style>

我不记得为什么我把它附加到单元格而不是行,但我肯定有一个原因。您可以尝试将事件附加到Row,看看会发生什么。