从类中按下Form1上的Catch键

本文关键字:上的 Catch Form1 | 更新日期: 2023-09-27 18:18:51

这是我的类与事件处理程序:

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();
    }
}

在我的表单1中,我有这个代码:(编辑)

KeyEvent ke = new KeyEvent();
private void button1_Click(object sender, EventArgs e)
{
    MessageBox.Show(ke.key);
}

当我运行表单并按键盘上的键,然后单击按钮,它弹出空消息框。我想要的是,每次我按键盘上的一个键,一个消息框弹出,告诉我我按了哪个键。这段代码只是为了测试,我不想只是弹出消息框,我需要其他事情的关键。

注意:要处理Form1上的事件不是解决方案,我需要处理类中的事件。

从类中按下Form1上的Catch键

您不可能创建一个能够自动侦听其父类生成的事件的类。这怎么可能呢?如果您使用非Form且不引发事件的东西创建新的KeyEvent类,会发生什么?

你需要给你的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);
}

你可以这样做:

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,您将接收到所有的keydown,甚至是放置在窗体上的控件。如果你把它设为false,你只会在窗体有焦点时得到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);