跳转至

键盘事件(KeyUp / KeyPress / KeyDown)#

来源D:\study\C#1\WinForm\stu0804\练习stu0811\stu08110804-作业\猜数游戏


1. 三种键盘事件对比#

事件 参数类型 获取内容 触发时机 特点
KeyDown KeyEventArgs e.KeyCode 按键按下 按住连续触发
KeyUp KeyEventArgs e.KeyCode 按键松开 只触发一次
KeyPress KeyPressEventArgs e.KeyChar 字符输入时 输入法相关,返回字符

2. KeyEventArgs 常用属性#

private void Form1_KeyUp(object sender, KeyEventArgs e)
{
    e.KeyCode    // 按键码(如 Keys.Up、Keys.A)— 最常用
    e.KeyValue   // 按键的整数编码
    e.Modifiers  // 组合键(Shift、Ctrl、Alt)

    // 判断具体按键
    if (e.KeyCode == Keys.Up)    { /* 上 */ }
    if (e.KeyCode == Keys.Down)  { /* 下 */ }
    if (e.KeyCode == Keys.Left)  { /* 左 */ }
    if (e.KeyCode == Keys.Right) { /* 右 */ }
    if (e.KeyCode == Keys.W)     { /* W 键 */ }
    if (e.KeyCode == Keys.R)     { /* R 键 */ }
}

3. KeyUp 实战:方向键移动方块#

public partial class Form1 : Form
{
    int x = 0, y = 0;           // 当前坐标
    int boxWidth, boxHeight;     // 方块大小
    int pW, pH;                  // 面板大小

    public Form1()
    {
        InitializeComponent();
        boxWidth = box.Size.Width;
        boxHeight = box.Size.Height;
        pW = panel1.Size.Width;
        pH = panel1.Size.Height;
    }

    private void box_KeyUp(object sender, KeyEventArgs e)
    {
        switch (e.KeyCode)
        {
            case Keys.Left:
                if (x > 0)
                    box.Location = new Point(x -= boxWidth, y);
                break;
            case Keys.Right:
                if (x < pW - boxWidth)
                    box.Location = new Point(x += boxWidth, y);
                break;
            case Keys.Up:
                if (y > 0)
                    box.Location = new Point(x, y -= boxHeight);
                break;
            case Keys.Down:
                if (y < pH - boxHeight)
                    box.Location = new Point(x, y += boxHeight);
                break;
        }
    }
}

边界判断公式#

上边界:box.Location.Y > 0
下边界:box.Location.Y < panel1.Height - box.Height
左边界:box.Location.X > 0
右边界:box.Location.X < panel1.Width - box.Width

💡 要点panel1.Height - box.Height 表示方块左上角能到达的最大 Y 值。详见 01-WinForm基础/03-坐标系统与控件定位

4. 键盘事件的绑定位置(新手最易困惑)#

键盘事件需要控件获得焦点才会触发。点击了其他按钮,焦点就会丢失,键盘事件就不触发了。

绑定方式 优点 缺点
绑定在控件上(如 button3) 简单直接 点击其他控件后焦点丢失,键盘失效
绑定在窗体上 + KeyPreview = true 推荐,不依赖焦点 需要在构造函数或设计器中设置
重写 ProcessCmdKey 最底层,一定能收到 写法稍复杂

推荐方案:绑定在窗体上#

public Form1()
{
    InitializeComponent();
    this.KeyPreview = true;    // 让窗体先于子控件收到键盘事件
    this.KeyUp += new KeyEventHandler(Form1_KeyUp);
}

💡 KeyPreview = true 是推荐做法:窗体先于所有子控件接收到键盘事件,不依赖焦点。

5. 小技巧:按键触发新窗口 / 重新开始#

// 猜数游戏中:按 R 键重新开始
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
    switch (e.KeyCode)
    {
        case Keys.R:
            new Form1().Show();   // 打开一个新窗体
            break;
    }
}

⚠️ 注意:new Form1() 创建的是新的独立窗体,不是刷新当前窗体。刷新数据应该重置变量而不是重建窗体。


相关笔记#