我正在使用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;
}
}
答案 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;在多个元素上触发的。这里的多个元素表示事件被定位的元素及其父元素,直到根元素为止。事件路由策略可以遵循:
这与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" />