如何覆盖默认"全球"键盘快捷键和创建我自己的?

时间:2014-04-07 17:28:25

标签: c# .net wpf keyboard-shortcuts

我理解WPF中的基本事件路由/冒泡(虽然显然还不够)...我要做的是在我的WPF桌面应用程序中使用基本的键盘快捷键。例如,我有一个ListBox,当用户按 Page-Up Page-Down (任何东西都可以集中在应用程序中)时,我希望列表框为如果适用,请选择其上一个或下一个项目。

这是我到目前为止所做的,但它不起作用。这是名为“Main”的窗口的构造函数:

public Main()
{
    InitializeComponent();

    // Initialize keyboard shortcuts
    KeyDown += (s, e) =>
    {
        var viewModel = GetActiveViewModel();
        if (e.Key == Key.PageUp)
        {
            viewModel.SelectPreviousItem();
            e.Handled = true;
        }
        else if (e.Key == Key.PageDown)
        {
            viewModel.SelectNextItem();
            e.Handled = true;
        }
    };
}

主动控件不是使用此代码,而是“窃取”事件并实现默认行为,例如:如果我选择了一个文本框,文本框就会移动光标,如果我选择了列表框,列表框会将所选索引移动一个“页面”,而不是像我想要的那样移动一个项目。

如何指示WPF“忽略”任何默认键盘挂钩并用我自己的逻辑替换它们?我理解我将“覆盖”某些控件的默认行为(例如,文本框中的 Page-Up / Page-Down 将不再移动光标)那没关系,这就是我想要的。

2 个答案:

答案 0 :(得分:4)

您可以注册 PreviewKeyDown 事件。

WPF中发生的事情是每个控件都可以有一个事件的默认实现,然后将“Handled”属性设置为true,这告诉WPF中的可视树停止传播事件。

试试这个:

PreviewKeyDown += (s, e) =>
{
   var viewModel = GetActiveViewModel();
   if (e.Key == Key.PageUp)
   {
      viewModel.SelectPreviousItem();
      e.Handled = true;
   }
   else if (e.Key == Key.PageDown)
   {
      viewModel.SelectNextItem();
      e.Handled = true;
   }
};

答案 1 :(得分:-1)

这不会完全奏效。

您需要通过隧道浏览列表here中找到的操作系统注册的全局热键:

此解决方案适用于列表中未定义的解决方案。 是的,我已经在WPF中使用CommandBindings进行了测试并获得了更优雅的解决方案。

然而,我希望能够禁止此解决方案无法解决的操作系统热键。