覆盖enter键,但保留wpf数据网格中其他键的默认行为

本文关键字:其他 网格 默认 数据 enter 保留 覆盖 wpf 数据网 | 更新日期: 2023-09-27 17:50:04

在Datagrid中按enter键将选择向下移动一个项目,这真的让我很困扰,我希望能够决定它在正常的按下键事件中做什么。

所以我所做的是创建一个继承DataGrid的新类并覆盖OnKeyDown事件并使用它作为我的DataGrid。

这产生了一套全新的问题,因为我显然必须重写所有其他按键(箭头键导航,shift+箭头键选择,pgup/pgdn等)。我一直在尝试破解它,但是花时间重写已经写好的东西似乎毫无意义,而且可能比我想出来的更好。

那么,我如何才能使enter键做我想做的事情,而不干扰数据网格的其他默认键绑定呢?

Thanks in advance

覆盖enter键,但保留wpf数据网格中其他键的默认行为

您需要将PreviewKeyDown处理程序绑定到Datagrid,然后手动检查键值是否为Key.Enter

是,设置"e.Handled = true"

检查按下的键是否为enter,如果不是,调用KeyDown的基本事件处理程序(如base.OnKeyDown(sender, args);)

一个更简单的实现。这个想法是捕捉keydown事件,如果键是"Enter",决定你想要走的方向。
FocusNavigationDirection有几个属性,可以根据这些属性修改焦点。

/// <summary>
/// On Enter Key, it tabs to into next cell.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void LiquidityInstrumentViewsGrid_OnPreviewKeyDown(object sender, KeyEventArgs e)
{
    var uiElement = e.OriginalSource as UIElement;
    if (e.Key == Key.Enter && uiElement != null)
    {
        e.Handled = true;
        uiElement.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    }
}

如果它的工作原理与winforms类似,那么对于未处理的按键,将已处理的标记为false,它将继续传递按键。KeyEventArgs类

Handled获取或设置一个值,该值指示路由事件在传递路由时的事件处理的当前状态。(继承自RoutedEventArgs.)

PreviewKeyDown with Handled = true是一个bad解决方案。它将停止处理隧道阶段的关键,永远不会冒泡的关键事件。简单地说,它会吃掉任何输入键。这意味着上面的面板,永远不会得到KeyDown事件(想象一下,你的窗口接受输入KeyDown…)。

正确的解决方案是Anthony所建议的:离开Handled = false, -因此它继续冒泡-并跳过处理DataGrid内的Enter

public class DataGridWithUnhandledReturn : DataGrid
{
    /// <inheritdoc/>
    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (e.Key == Key.Return && e.KeyboardDevice.Modifiers == ModifierKeys.None)
        {
            return;
        }
        base.OnKeyDown(e);
    }
}