使用C#/WPF监听按键事件

3

我正在尝试监听C#应用程序中按下箭头键的事件。

我已经在XAML文件的C#文件中添加了以下方法来监听按下箭头键并报告每个按键:

private void Grid_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Left)
    {
        Console.WriteLine("left");
    }
    if (e.Key == Key.Right)
    {
        Console.WriteLine("Right");
    }
    if (e.Key == Key.Up)
    {
        Console.WriteLine("Up");
    }
    if (e.Key == Key.Down)
    {
        Console.WriteLine("Down");
    }
}

在相应的XAML中,Grid元素如下所示:
<Grid Background="Black" MouseWheel="Grid_MouseWheel"
    MouseDown="Grid_MouseDown" MouseUp="Grid_MouseUp"
    MouseMove="Grid_MouseMove" KeyDown="Grid_KeyDown">

目前,与鼠标相关的监听器正在运行,但键盘监听器(KeyDown="Grid_KeyDown")无法工作。我需要添加其他内容才能使其正常工作吗?


尝试访问http://stackoverflow.com/questions/18171396或https://dev59.com/yXRC5IYBdhLWcg3wSu97。 - Moby Disk
我想知道如何在WpfApplication中显示Console窗口?除非您正在运行控制台应用程序并尝试显示Wpf窗口,否则看起来这就是问题所在。如果这是一个测试,请尝试使用System.Diagnostics.Debug.Print而不是Console.WriteLine - King King
King,使用调试/控制台打印的两种方法似乎产生了相同的结果,但也许写入debug.print更有意义。 - Jake
2个回答

5

你的处理程序从未被调用的原因是Grid本身处理了KeyDown事件,并设置了标志以阻止事件进一步冒泡(到你的应用程序处理程序)。你可以处理PreviewKeyDown事件,而不是KeyDown事件。这会在Grid之前给你一个响应按键事件的机会。

在XAML文件中,将你的Grid元素修改为如下:

<Grid Background="Black" MouseWheel="Grid_MouseWheel"
    MouseDown="Grid_MouseDown" MouseUp="Grid_MouseUp"
    MouseMove="Grid_MouseMove" PreviewKeyDown="Grid_PreviewKeyDown">

实际的事件处理程序代码基本相同:
private void Grid_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if(e.Key == Key.Left)
       Console.WriteLine("left");
    //  and whatever else you want to do here..
}

注意:同样重要的是确保网格是逻辑焦点范围的一部分。否则,如果某些其他元素在不同的树中具有键盘焦点,则网格将不会接收任何事件。有关详细信息,请参见此处:http://msdn.microsoft.com/zh-cn/library/aa969768(v=vs.110).aspx


Mike,感谢您的快速回复。然而,我尝试了这些更改,但我仍然没有看到按箭头键时控制台上的任何输出。 - Jake
@Jake,如果你仍然没有收到事件,请确保网格处于焦点状态。如果另一个控件拥有键盘焦点,则该网格将无法接收键盘事件。我刚在我的电脑上尝试了一个快速解决方案,它可以正常工作。 - Mike Dinescu
我想补充一点,如果你正在连接到KeyPreview事件,并且想要做更多的事情(例如,如果按下Key.Left键),那么如果你处理了这个动作,你可能需要设置e.Handled = true - GEEF

0
你需要将Grid的Focusable属性设置为"true",因为它默认值是"false"。
<Grid Background="Black" MouseWheel="Grid_MouseWheel"
MouseDown="Grid_MouseDown" MouseUp="Grid_MouseUp"
MouseMove="Grid_MouseMove" KeyDown="Grid_KeyDown"
Focusable="true">

此外,如果您在初始化后将焦点放在网格上,则每次启动应用程序时都不必单击窗口。
public MainWindow()
    {
        InitializeComponent();

        GridWindow.Focus();           
    }

我将网格命名为“GridWindow”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接