键盘事件(KeyUp / KeyPress / KeyDown)#
来源:
D:\study\C#1\WinForm\stu0804\练习、stu0811\stu0811、0804-作业\猜数游戏
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()创建的是新的独立窗体,不是刷新当前窗体。刷新数据应该重置变量而不是重建窗体。
相关笔记#
- 事件的基本使用 — 事件基础
- 焦点与 KeyPreview — KeyPreview