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

发布于 2024-10-31 17:36:59 字数 312 浏览 1 评论 0原文

令我困扰的是,在数据网格中按 Enter 键会将选择向下移动一项,我希望能够决定它在正常的 keydown 事件中的作用。

所以我所做的就是创建一个继承 DataGrid 的新类并重写 OnKeyDown 事件并将其用作我的数据网格。

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

那么,如何让 Enter 键执行我想要的操作,而不与数据网格的其他默认键绑定混淆呢?

提前致谢

It really bothers me that the pressing the enter key in a Datagrid moves the selection down one item, I'd like to be able to decide what it does in a normal keydown event.

So what I did was create a new class that inherits DataGrid and override the OnKeyDown event and use that as my datagrid.

This creates a whole new set of problems, since I apparently have to rewrite all the other keypresses (arrow key navigation, shift+arrow key selection, pgup/pgdn, etc..). I've been trying to hack it, but it just seems so pointless spending time rewriting something that has already been written and probably better then whatever I'll come up with.

So how can I make the enter key do what I want without messing with the other default keybindings of the datagrid?

Thanks in advance

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

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

发布评论

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

评论(5

盛夏已如深秋| 2024-11-07 17:36:59

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

如果是,请设置e.Handled = true

You will need to bind a PreviewKeyDown handler to the Datagrid and then manually check whether the key value is Key.Enter.

If yes, set e.Handled = true.

悍妇囚夫 2024-11-07 17:36:59

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

Just check if the key pressed is enter, if it's not, call the base event handler for KeyDown (something like base.OnKeyDown(sender, args);)

听风吹 2024-11-07 17:36:59

一个更简单的实现。这个想法是捕获 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));
    }
}

A much simpler implementation. The idea is to capture the keydown event and if the key is "Enter",
decide in what direction you wish to traverse.


FocusNavigationDirection has several properties based on which the focus can be modified.

/// <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));
    }
}
长途伴 2024-11-07 17:36:59

PreviewKeyDownHandled = true 是一个糟糕的解决方案。它会在调整阶段停止处理 Key,并且永远不会冒泡 key 事件。简单来说,它会吃掉任何 Enter 键。这意味着上部面板永远不会收到 KeyDown 事件(想象一下您的窗口在 ENTER 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);
    }
}

PreviewKeyDown with Handled = true is a bad solution. It would stop handling Key on the tunelling phase and never bubble the key event up. Simply speaking it would eat any Enter key presses. That meant that upper panels, would never get KeyDown event (imagine that your Window accepts something on ENTER KeyDown...).

The right solution is what Anthony has suggested: to leave the Handled = false, -- so it continues bubbling -- and skip handling Enter inside DataGrid

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);
    }
}
朕就是辣么酷 2024-11-07 17:36:59

如果它的工作方式与 winform 类似,对于您没有处理的按键,则将处理标记为 false,并且它将传递按键。
KeyEventArgs Class

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

If it works similiarly to winforms, for the key presses that you aren't handling, than flag the handled as false, and it will pass the key press along.
KeyEventArgs Class

Handled Gets or sets a value that indicates the present state of the event handling for a routed event as it travels the route. (Inherited from RoutedEventArgs.)

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