c# - KeyDown 事件未触发?

标签 c# winforms events keydown onkeydown

在编写一个小游戏时,我遇到了一个问题;我的表单的 KeyDownKeyUp 事件根本没有触发。

这是表单的代码:

public class GameForm : Form
{
    private ControllableBlock player;

    public GameForm()
    {
        KeyDown += Game_KeyDown;
        KeyUp += Game_KeyUp;

        player = new ControllableBlock();
        Controls.Add(player);
    }

    private void Game_KeyDown(object sender, KeyEventArgs e)
    {
        player.ReactToKey(e.KeyCode);
    }

    private void Game_KeyUp(object sender, KeyEventArgs e)
    {
        player.ReactToKey(e.KeyCode);
    }
}

还有很多事情要做,但我只粘贴了相关代码。

我已经尝试设置 this.KeyPreview = true; 并调用 this.Focus();,但都不起作用。 问题不在 ReactToKey() 方法中,我已经在那里设置了一个断点,并且该事件从未被触发。


编辑:经过一些测试后,我得出的结论是问题出在我的ControllableBlock 中。 然而,我不知道为什么,但我正在努力。 如果我注释掉与 player 相关的所有内容,事件就会开始触发。


编辑 2: 问题似乎是我从 Control 继承了我的 ControllableBlock。 如果我从 Panel 继承它,它就可以正常工作。 这是为什么? 如果我从控件继承,我不能触发事件吗? ControllableBlock 类目前是空的,所以它除了继承自 Control 之外什么都不做。


编辑 3: 既然我已经开始悬赏,我想澄清一下,我不是在寻找如何触发事件的解决方案,而是在寻找如果我从 Control 继承它们为什么不触发的原因。

最佳答案

我能够重现类似的问题(希望是相关的..)

解释:

  • 返回 CanSelect==true 的控件可选择键盘输入
  • Control() 的空白后代是可选择的,Panel() 之一不是
  • 添加到表单的第一个可选控件将被选中
  • 默认情况下,选定的控件会从其父级窃取键盘事件
  • 用于在窗口内导航的某些键需要额外的步骤才能处理

检查 here了解 Windows 键盘输入的工作原理。

重现代码:

public class GameForm : Form
{
    public GameForm()
    {
        this.KeyDown += Game_KeyDown;
        var tests = new List<Control[]>() { 
            new[] { new Panel() },
            new[] { new Panel(), new Panel() },
            new[] { new Control() },
            new[] { new Control(), new Panel() },
            new[] { new Panel(), new Control() }
        };
        // When test index 2 to 4 used, keyboard input does not reach form level
        Controls.AddRange(tests[0]);            
        // When uncommented, ensures all keyboard input reaches form level
        /*this.KeyPreview = true;              
        // Additional plumbing required along with KeyPreview to allow arrow and other reserved keys
        foreach (Control control in this.Controls)
        {
            control.PreviewKeyDown += control_PreviewKeyDown;
        }*/
    }
    void control_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
        e.IsInputKey = true;
    }
    private void Game_KeyDown(object sender, KeyEventArgs e)
    {
        // breakpoint here
        Debug.WriteLine(e.KeyCode);
    }
}

关于c# - KeyDown 事件未触发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15091283/

相关文章:

c# - 如何使数据库更新为 'score record'?

c# - WinForms 数据绑定(bind) DataGridView 与 ComboBoxColum

c# - 过滤 ListView 中的项目

c# - 使用 .net SDK 暂停和启动 Azure 分析服务

c# - 文本框对象的文本更改事件 : how to perform text change + another action

C# 位图与透明图像旋转

c# - 如何在 winforms 中使用 EF 进行双向数据绑定(bind)?

javascript - 将 javascript 事件获取到被覆盖的对象

actionscript-3 - AS3 阶段 = 空?

javascript - jquery 事件监听器在刷新我的 jquery 数据表后不起作用?