【问题标题】:How Catch Keyup Event In User Control?如何在用户控制中捕获 Keyup 事件?
【发布时间】:2025-12-26 02:45:11
【问题描述】:

我想在用户控件中捕捉父窗体的 keyup 事件。我使用 ProcessCmdKey 但它只是给了我 keydown 事件并且它不会在 keyup 事件中引发。我该怎么做?

更新:我想捕捉表单的 keyup 事件。因为 Control.KeyUp 在控制集中时引发。

public partial class ExtendedButton : Button
{
    const int WM_KEYDOWN = 0x100;

    public ExtendedButton()
    {
        InitializeComponent();
    }

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (msg.Msg == WM_KEYUP && keyData == (Keys.NumPad0))
        {
            MessageBox.Show("hi");
        }
        return base.ProcessCmdKey(ref msg, keyData);
    }
}

【问题讨论】:

  • 为什么这么复杂?见*.com/questions/18604633/…
  • @user2864740 我想在 usercontrol 中使用 keyup 事件,而不是在表单中
  • Control.KeyUp .. 仍然不确定并发症是什么。
  • @user2864740 我想捕捉表单的 keyup 事件。因为 Control.KeyUp 在控制集中时引发。
  • 你可能已经保留了一个你想要冒泡到的控件列表。有点像程序如何保持所有 Windows 的标题栏处于活动状态,无论哪个有焦点。

标签: c# winforms events keyup


【解决方案1】:

您可以在 UserControl 的 OnHandleCreated 覆盖方法中为父窗体 KeyUp 创建处理程序。

试试这个代码

Form parentForm = null;
private void ParentForm_KeyUp(object sender, KeyEventArgs e)
{
    MessageBox.Show("HI");
}

protected override void OnHandleCreated(EventArgs e)
{
    if (DesignMode)
        return;

    base.OnHandleCreated(e);
    object parent = this;
    while (true)
    {
        parent = ((Control)parent).Parent;
        if (parent.GetType().BaseType.Name == "Form")
            break;
    }
    parentForm = (Form)parent;
    parentForm.KeyUp -= new KeyEventHandler(this.ParentForm_KeyUp);
    parentForm.KeyUp += new KeyEventHandler(this.ParentForm_KeyUp);
}

【讨论】:

  • 发生了什么?得到任何错误?您是否将父表单的 KeyPreview 属性设置为 true?
  • 是的,我设置了 KeyPreview 属性。没有错误,但没有引发 keyup 事件。
  • 你试过调试代码吗? OnHandleCreated 事件是否被触发?用户控件无法为父表单键向上事件创建处理程序,那么它将不会被触发。尝试在parentForm = (Form)parent; 行上放置断点并调试它在parent 对象中存储的值。
  • OnHandleCreated 被触发并且 parentForm 的值为 true。但事件不会触发。