C# 键盘输入返回键
我正在用C#编写一个计算器,并试图在其中添加键盘输入。问题是,如果我单击GUI上的一个按钮,则Enter/Return键将集中于此。当按下return键时,它会再次单击该键,而不是由我的KeyDown事件处理程序处理。我怎样才能解决这个问题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:
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之后出现,可能会把你搞砸!