如何正确处理快捷方式和键盘事件?

时间:2011-12-16 00:41:43

标签: c# .net wpf

快捷方式有问题,我们非常感谢任何帮助/提示! 目标:我需要能够在我的应用程序中处理带有和不带修饰符的快捷键。 因此,例如我需要处理键'a'以及'CTR + a'。但是,只有在没有控件处理这些键时我才想处理它们。例如,TextBox类占用大多数键,包括一些命令,如“Ctrl + C”等,所以当TextBox处理它们时我不想拦截这些事件。

我尝试使用命令以及将事件附加到KeyUp到窗口,但是,命令在TextBox有机会查看它们之前拦截键,KeyDown气泡到Window级别,即使TextBox使用了键!如何让我的窗口获取任何子控件未处理的键?请参阅下面的代码,该代码对我不起作用。此外,由于我有许多不同的控件,我宁愿有一个“正确的”解决方案:我宁愿不在我的窗口中为每个控件实例附加处理程序。

<Window x:Class="KeyTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">

<Window.CommandBindings>
    <CommandBinding Command="Help"
                    CanExecute="HelpCanExecute"
                    Executed="HelpExecuted" />
</Window.CommandBindings>

<Window.InputBindings>
    <KeyBinding Command="Help" Key="H" />
</Window.InputBindings>

<Grid>
    <WrapPanel>
        <TextBox Name="myLOG" Width="300" Height="200" Background="LightBlue" />
        <TextBox Name="myINPUT" Width="300" Height="200" />
        <Button Content="JUST FOR FUN" />
    </WrapPanel>
</Grid>

对于C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace KeyTest
{
   /// <summary>
   /// Interaction logic for MainWindow.xaml
   /// </summary>
   public partial class MainWindow : Window
   {
      private void HelpCanExecute(object sender, CanExecuteRoutedEventArgs e)
      {
         myLOG.Text += "HELP CAN EXECUTE\n";
         e.CanExecute = true;
         e.Handled = true;
      }

      private void HelpExecuted(object sender, ExecutedRoutedEventArgs e)
      {
         myLOG.Text += "HELP  EXECUTED!!!\n";
         e.Handled = true;
      }

      public void myKeyUpHandler(Object sender, KeyEventArgs args)
      {
         myLOG.Text += "KEY UP EVENT! " + args.Key + "\n";
      }

      public MainWindow()
      {
         InitializeComponent();
         this.KeyUp += new KeyEventHandler(myKeyUpHandler);
      }
   }
}

当焦点位于文本框中时,按“h”会触发该命令,即使我希望“h”仅转到文本框。此外,当在文本框内时,按任意字母数字键会触发KeyUp事件,即使据我所知,文本框应该处理= true该事件!

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

您需要使用预览事件类型进行调查。它们发生在其他控件将处理事件之前。然后你想停止冒泡的事件。我相信你正在用e.Handled正确地做到这一点。

调查此问题:http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.previewkeydown.aspx

不确定如何在xaml中执行此操作。表达式混合库对于从事件中生成命令非常有用。见这里:http://jacokarsten.wordpress.com/2009/03/27/applying-command-binding-to-any-control-and-any-event/

答案 1 :(得分:1)

Dude我认为你需要在这里使用previewKeyDown或PreviewKeyUp事件而不是keyup事件,因为PreviewKeydown和PreviewKeyup事件会产生隧道效应(冒泡效果的OPPOSITE,其中从触发事件的控件的RootParent开始触发事件控制最初解雇事件(也称为原始源))。您可以利用此隧道效果来处理事件,而不是使用通过冒泡效果触发的事件。另一件事是在keydown事件发生之前触发的PreviewKeyDown和PrevieKeyup事件。这可以让你以最干净的方式拦截事件。

另一件事,我认为您需要检查事件的原始来源,以便您可以选择可能触发此事件的控件。

以下是示例代码

 public void nameOfCotrol_PreviewKeyDown(object sender, RoutedEventArgs e)
 {
    if((e.OriginalSource as Control).Name == "NameOfControls That would be allowed to fire the event")
    {
        You're stuff to be done here
    }
    else
    {
        e.handled = true;
     }
 }

我希望这可能会有所帮助。感谢