在除 Form 之外的 class 上接收和读取 KeyEventArgs 事件
Receiving and reading out KeyEventArgs event on a class other than a Form
我目前正在开发一个小游戏作为 WinForms 项目。游戏场由玩家(一个单独的 class)可以继续前进的瓷砖网格构建而成。我想让玩家用箭头键移动并为它设置了一个事件处理程序,但它似乎从未被调用过。
(最小化)播放器 class,实现了 KeyEventArgs 的 System.Windows.Forms 包:
public class Player : MovableObject
{
public Player(Playtile position) : base(position)
{
EntityColor = ElementColors.PlayerColor;
PostConstructor(position);
}
/// <summary>
/// Reads keypress via eventhandler KeyEventArgs (key down).
/// </summary>
private void ReadKeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Up:
// move up.
break;
case Keys.Right:
// move right.
break;
case Keys.Down:
// move down.
break;
case Keys.Left:
// move left.
break;
}
}
}
目前,ReadKeyDown 从未被调用。我如何实际将 KeyEventDown 事件分配/绑定到播放器,以便它实际上在按键按下时调用该方法?
KeyEventArgs in C# 似乎只是说 this.KeyDown += ReadKeyDown;
,但它不会将 KeyDown 识别为任何东西,也不会给我可能缺少的程序集引用。
KeyDown
是 Control
的成员,因此在您的情况下,您可以在 Form
.
中订阅该活动
喜欢以下内容:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
textBox1.KeyDown += TextBox1_KeyDown;
}
private void TextBox1_KeyDown(object sender, KeyEventArgs e)
{
}
}
完整示例见官方文档:
现在您可以做的是在收到此类事件后在目标 class 中调用一个方法:
public class MyClass
{
public void OnKeyDown(KeyEventArgs e)
{
// ...
}
}
public partial class Form2 : Form
{
MyClass _instance = new MyClass();
public Form2()
{
InitializeComponent();
textBox1.KeyDown += TextBox1_KeyDown;
}
private void TextBox1_KeyDown(object sender, KeyEventArgs e)
{
_instance.OnKeyDown(e);
}
}
您可以直接在 class 中订阅 KeyDown
活动:
public Player(Playtile position, Form form) : base(position) // <--- form parameter
{
EntityColor = ElementColors.PlayerColor;
PostConstructor(position);
form.KeyDown += ReadKeyDown; // <--- subscribing to the event
}
但是有一个问题。现在表单持有对 Player
对象的引用,并且在关闭表单之前不会对对象进行垃圾回收。如果 Player 的生命周期与 form 的生命周期相同,这不是问题。但是,如果您创建了许多短命的玩家,那么当您不再需要它们时,您应该取消订阅表单的事件,方法是向玩家添加如下方法:
public void Dispose(Form form)
{
form.KeyDown -= ReadKeyDown;
}
...并在处理播放器对象时调用 Dispose
。
我目前正在开发一个小游戏作为 WinForms 项目。游戏场由玩家(一个单独的 class)可以继续前进的瓷砖网格构建而成。我想让玩家用箭头键移动并为它设置了一个事件处理程序,但它似乎从未被调用过。
(最小化)播放器 class,实现了 KeyEventArgs 的 System.Windows.Forms 包:
public class Player : MovableObject
{
public Player(Playtile position) : base(position)
{
EntityColor = ElementColors.PlayerColor;
PostConstructor(position);
}
/// <summary>
/// Reads keypress via eventhandler KeyEventArgs (key down).
/// </summary>
private void ReadKeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Up:
// move up.
break;
case Keys.Right:
// move right.
break;
case Keys.Down:
// move down.
break;
case Keys.Left:
// move left.
break;
}
}
}
目前,ReadKeyDown 从未被调用。我如何实际将 KeyEventDown 事件分配/绑定到播放器,以便它实际上在按键按下时调用该方法?
KeyEventArgs in C# 似乎只是说 this.KeyDown += ReadKeyDown;
,但它不会将 KeyDown 识别为任何东西,也不会给我可能缺少的程序集引用。
KeyDown
是 Control
的成员,因此在您的情况下,您可以在 Form
.
喜欢以下内容:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
textBox1.KeyDown += TextBox1_KeyDown;
}
private void TextBox1_KeyDown(object sender, KeyEventArgs e)
{
}
}
完整示例见官方文档:
现在您可以做的是在收到此类事件后在目标 class 中调用一个方法:
public class MyClass
{
public void OnKeyDown(KeyEventArgs e)
{
// ...
}
}
public partial class Form2 : Form
{
MyClass _instance = new MyClass();
public Form2()
{
InitializeComponent();
textBox1.KeyDown += TextBox1_KeyDown;
}
private void TextBox1_KeyDown(object sender, KeyEventArgs e)
{
_instance.OnKeyDown(e);
}
}
您可以直接在 class 中订阅 KeyDown
活动:
public Player(Playtile position, Form form) : base(position) // <--- form parameter
{
EntityColor = ElementColors.PlayerColor;
PostConstructor(position);
form.KeyDown += ReadKeyDown; // <--- subscribing to the event
}
但是有一个问题。现在表单持有对 Player
对象的引用,并且在关闭表单之前不会对对象进行垃圾回收。如果 Player 的生命周期与 form 的生命周期相同,这不是问题。但是,如果您创建了许多短命的玩家,那么当您不再需要它们时,您应该取消订阅表单的事件,方法是向玩家添加如下方法:
public void Dispose(Form form)
{
form.KeyDown -= ReadKeyDown;
}
...并在处理播放器对象时调用 Dispose
。