覆盖enter键,但保留wpf数据网格中其他键的默认行为
本文关键字:其他 网格 默认 数据 enter 保留 覆盖 wpf 数据网 | 更新日期: 2023-09-27 17:50:04
在Datagrid中按enter键将选择向下移动一个项目,这真的让我很困扰,我希望能够决定它在正常的按下键事件中做什么。
所以我所做的是创建一个继承DataGrid的新类并覆盖OnKeyDown事件并使用它作为我的DataGrid。这产生了一套全新的问题,因为我显然必须重写所有其他按键(箭头键导航,shift+箭头键选择,pgup/pgdn等)。我一直在尝试破解它,但是花时间重写已经写好的东西似乎毫无意义,而且可能比我想出来的更好。
那么,我如何才能使enter键做我想做的事情,而不干扰数据网格的其他默认键绑定呢?
Thanks in advance
您需要将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);
}
}