C# 键盘输入返回键

C# 键盘输入返回键,c#,wpf,input,keyboard,C#,Wpf,Input,Keyboard,我正在用C#编写一个计算器,并试图在其中添加键盘输入。问题是,如果我单击GUI上的一个按钮,则Enter/Return键将集中于此。当按下return键时,它会再次单击该键,而不是由我的KeyDown事件处理程序处理。我怎样才能解决这个问题 private void Window_KeyDown(object sender, KeyEventArgs e) { switch (e.Key) { case Key.NumPad1:

我正在用C#编写一个计算器,并试图在其中添加键盘输入。问题是,如果我单击GUI上的一个按钮,则Enter/Return键将集中于此。当按下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;
        }
    }
试试这个:

    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;
        }
    }
private void Window\u KeyDown(对象发送方,KeyEventArgs e)
{
开关(电子钥匙)
{
case Key.NumPad1:
案例关键点D1:
附加输入(“1”);
MyTextBox.Focus();//您需要处理窗体的事件。然后检查是否要处理该事件,如果要处理,请在处理后将事件的属性设置为
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元素上触发,触发方式取决于其“路由策略”。当事件处理程序将
Handled
设置为
true
时,该事件的可见性将仅限于其他UI元素。很快,它将不会在其他UI元素中触发。若要了解上述解决方案的详细信息,请阅读下面的其余答案


如果要在WPF中正确使用事件,需要了解一些事情。事件附加到UI元素(文本框、按钮等),事件处理程序可以连接到这些UI元素。此外,UI元素以树状结构组织。每个元素都有其父元素,直到根UI元素。如前所述,事件根据其“路由策略”在多个元素上触发。此处的多个元素表示事件的目标元素及其父元素,直到根元素。事件路由策略可以如下所示:

  • 冒泡:首先为事件目标元素激发事件。然后,为其父元素激发事件,然后为其父元素的父元素激发事件,依此类推,直到根元素(通常是窗口)
  • 隧道:首先为根UI元素触发事件,然后沿着指向目标元素的路径向下触发UI元素树
  • Direct:仅为目标元素触发事件

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

现在,当您将事件标记为
Handled
时,为什么事件没有停止传播?因为
KeyDown
事件使用冒泡策略。这意味着文本框在到达窗口处理程序之前已经处理了KeyDown事件,您可以将
Handled
设置为
true

因此,您应该使用which使用隧道策略。您的窗口处理程序检查事件,如果需要,将其标记为
Handled
。如果将其标记为
Handled
,则不会在UI树下触发事件目标

您可以在.NET framework中将其视为约定。
PreviewX
是使用隧道策略的事件,是使用
冒泡策略的
X
事件的对应项


您会发现MSDN是一个很好的WPF信息源。

将Focusable设置为false:

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


向我们展示您尝试使用的事件处理程序代码。我已编辑了您的标题。请参阅“”,其中一致意见是“不,他们不应该”。我添加了该代码。没有更改。仍然执行以前的操作。我现在通过WPF窗口的事件属性处理了按键。通过编程设置它会有什么好处?您没有注意到您正在将WPF用于UI。请查看我更新的答案以了解详细信息。WPF的事件比WinForms的事件更棘手。谢谢。这就解释了为什么它不起作用了。我将尝试一下这段新代码。在按钮单击处理程序中,我添加了这个。Focus()尝试将主窗口设置为焦点。没有更改。@Emrys90:为什么尝试将焦点设置为窗口而不是输入的文本框?您能处理文本框中的按键吗?文本框是只读的。如果字符是有效输入,我通过按钮或按键附加字符来处理输入。@Emrys90:我想您实际上需要来处理keypup消息。它在keypdown之后出现,可能会把你搞砸!