键盘输入返回键

时间:2013-03-19 16:19:11

标签: c# wpf input keyboard

我正在使用C#编写计算器,我正在尝试为其添加键盘输入。问题是如果我点击GUI上的一个按钮,那么Enter / Return键就会集中在那里。按下返回键后,再次单击该键,而不是由我的KeyDown事件处理程序处理。我该如何解决这个问题?

private void Window_KeyDown(object sender, KeyEventArgs e)
    {
        switch (e.Key)
        {
            case Key.NumPad1:
            case Key.D1:
                addInput('1');
                break;
            case Key.Return:
                MessageBox.Show("Enter!");
                break;
        }
    }

3 个答案:

答案 0 :(得分:1)

试试这个:

    private void Window_KeyDown(object sender, KeyEventArgs e)
    {
        switch (e.Key)
        {
            case Key.NumPad1:
            case Key.D1:
                addInput('1');
                MyTextBox.Focus(); // <-- NEW LINE OF CODE
                break;
            case Key.Return:
                MessageBox.Show("Enter!");
                MyTextBox.Focus(); // <-- NEW LINE OF CODE
                break;
        }
    }

答案 1 :(得分:1)

您需要处理表单的PreviewKeyDown事件。然后检查是否要处理该事件,如果这样做,请在执行后将事件的Handled属性设置为true

这可能看起来像这样:

public MainWindow()
{
    InitializeComponent();

    PreviewKeyDown += new KeyEventHandler(MainWindow_PreviewKeyDown);
}

void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Space)
    {
        Log("Intercepted space in preview");
        e.Handled = true;
    }
}

为什么需要将Handled设为true? WPF中的事件在几个UI元素上触发,其方式取决于它的&#34; 路由策略&#34;。当您的事件处理程序将Handled设置为true时,该事件的可见性将仅限于其他UI元素。很快,它不会被其他UI元素触发。要了解有关上述解决方案详情的更多信息,请阅读下面的其他答案。


如果要在WPF中正确使用事件,有些事情需要了解。事件附加到UI元素(文本框,按钮等),事件处理程序可以连接到这些UI元素。此外,UI元素以树结构组织。每个元素都有它的父元素,直到根UI元素。如前所述,事件是根据他们的&#34; 路由策略&#34;在多个元素上触发的。这里的多个元素表示事件被定位的元素及其父元素,直到根元素为止。事件路由策略可以遵循:

  • 冒泡:事件首先针对事件目标元素触发。然后,它被激活它的父母,然后是它的父母的父母,依此类推,直到根元素(通常这是窗口)
  • 隧道:首先针对根UI元素触发事件,然后沿着到目标元素的路径向下触发UI元素树。
  • 直接:仅针对目标元素触发事件。

enter image description here

这与Handled属性有何关系?当事件使用冒泡或隧道路由策略时,Handled属性用于停止事件向下或向上UI元素树的传播。

现在,当您将Handled标记为KeyDown时,为什么没有KeyDown事件停止传播?因为Handled事件使用冒泡策略。这意味着文本框已经处理了KeyDown事件,然后才能进入Window处理程序,并将true设置为Handled

出于这个原因,你应该使用PreviewKeyDown使用隧道策略。您的窗口处理程序检查事件,如果需要,将其标记为Handled。如果它被标记为PreviewX,它将不会在UI树中触发到事件目标。

您可以将其视为.NET框架中的约定。 X是使用隧道策略的事件,与使用bubbling策略的{{1}}事件相对应。

To learn more about Routed Events visit this MSDN page.您会发现MSDN是有关WPF的良好信息来源。

答案 2 :(得分:0)

将Focusable设为false:

<Button Focusable="False" Click="Button_Click" />