在 DataGrid 中一致地使用 ICommand 和 InputBindings

发布于 2024-12-22 05:57:23 字数 1434 浏览 1 评论 0原文

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

  • 只读 Datagrid,但通过双击和单独的编辑表单(双击特定行)提供编辑功能
  • ContextMenu 调用新/编辑/删除表单(右键单击整个 DataGrid)
  • 调用删除表单的删除键(在特定选定的行上)

我认为使用 ICommand 是一个好主意,所以我创建了一个像这样的 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 方法中决定是否适合处理命令,而不是订阅大量不同的事件处理程序。

I'm trying to create a DataGrid having the following features:

  • Readonly Datagrid, but provide editing capabilities through double click and separate edit form (double click on specific row)
  • ContextMenu which calls new/edit/delete form (right click on whole DataGrid)
  • Delete key which calls delete form (on specific selected row)

I thought it would be a good idea to use ICommand, so I created a DataGrid like this:

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
    }
}

I then realized, double-clicking a row isn't working, so I added this:

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

And of course the delete key isn't working either, I added this:

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

Why do I have to do that? Isn't the whole point of having Commands to prevent this kind of hacking around with events? Do I miss something?

In my simple and perfect world, I want to decide in the CanExecute method whether it is appropriate to handle the command, and not subscribe to tons of different event handlers..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

愛上了 2024-12-29 05:57:23

通常我使用 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>

我不记得为什么将它附加到单元格而不是行,但我确信这是有原因的。您可以尝试将事件附加到行,看看会发生什么。

Usually I attach the command to the DataGridCell using a Style

Here's an example using a custom 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>

I can't remember why I attached it to the Cell instead of the Row, but I'm sure there was a reason. You could try attaching the event to the Row instead and see what happens.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文