这是我的带有事件处理程序的类:
public delegate void MyKeyEventHandler(object sender, KeyEventArgs e);
public class KeyEvent
{
public event MyKeyEventHandler keyEvent;
public string key = "";
protected virtual void KeyPressed(KeyEventArgs e)
{
MyKeyEventHandler handler = keyEvent;
if (handler != null)
handler(this, e);
}
public KeyEvent()
{
keyEvent += new MyKeyEventHandler(keyPressed);
}
private void keyPressed(object sender, KeyEventArgs e)
{
key = e.KeyCode.ToString();
}
}
在我的Form1中我有这段代码:(已编辑)
KeyEvent ke = new KeyEvent();
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(ke.key);
}
当我运行表单并按键盘上的键然后单击按钮时,它会弹出空的MessageBox。我想要的是每次我按下键盘上的一个键,弹出一个MessageBox并显示我按下了哪个键。这段代码只是用于测试,我不想只是弹出消息框,我需要其他东西的密钥。
注意:要处理Form1上的事件不是解决方案,我需要处理类中的事件。我制作了一个图书馆。
答案 0 :(得分:0)
您可以这样做:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 f = new Form1();
f.KeyPreview = true;
f.KeyDown += f_KeyDown;
Application.Run(f);
}
static void f_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show(e.KeyValue.ToString());
}
}
如果启用KeyPreview,即使是表单上的控件,您也将收到所有keyDowns。如果将其设置为false,则只有在Form具有焦点时才能获得KeyDown。
正如您在代码中看到的,您可以将任何类中的任何KeyDownEventHandler方法连接到Form。
在哪里还有问题:
public class FormKeyListener
{
private Form formToListen = null;
public void SetFormToListen(Form form)
{
if (formToListen != null)
formToListen.KeyDown -= formToListen_KeyDown; // Unregister from old form if present
formToListen = form;
formToListen.KeyDown += formToListen_KeyDown; // Attach to new form
}
void formToListen_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show(e.KeyValue.ToString());
}
}
可以在代码中的某处调用:
FormKeyListener fkl = new FormKeyListener();
Form1 f = new Form1();
f.KeyPreview = true;
fkl.SetFormToListen(f);
答案 1 :(得分:0)
您无法创建一个能够自动侦听其父级生成的事件的类。那会怎么样?如果您使用非KeyEvent
并且未引发事件的内容创建新的Form
课程,会发生什么?
您需要为KeyEvent
课程提供您想要监控关键事件的任何内容。我意识到您的目的是创建一些第三方库,因此您希望尽可能保持通用,以便最大限度地重用它。由于您依赖于KeyDown
事件,因此使用Control
是最常用的。这是因为它是实际定义KeyDown
事件的地方。
让我告诉你我的意思......
1)修改KeyEvent
类的构造函数以接受Control
的实例
public class KeyEvent
{
// You don't need to declare an internal event
public string key = "";
private Control _control;
public KeyEvent(Control control)
{
// Here is where we save the reference of Control that was passed to the class.
// This will enable you to access the instance of the Form or whatever else
// you want to use, which is helpful for unregistering events during cleanup
_control = control;
// Wire up your event handler to this SPECIFIC instance of Control.
// This will cause your `keyPressed` method to execute whenever
// the control raises the KeyDown event. All of the middleman
// event handling you are doing is unnecessary.
_control.KeyDown += keyPressed;
}
private void keyPressed(object sender, KeyEventArgs e)
{
key = e.KeyCode.ToString();
}
}
2)修改您在其中创建此KeyEvent
的父级,将其自身传递到KeyEvent
// Now you pass 'this' into the constructor. This can be a Form, or any other
// Winforms control that may inherit from Control (which is all of them)
KeyEvent ke = new KeyEvent(this);
private void button1_Click(object sender, EventArgs e)
{
// At this point, ke.Key will always display the last
// key pressed in the Form when the button is clicked.
MessageBox.Show(ke.key);
}