WinForm 控件事件处理程序顺序

WinForm Control event handlers order

我想知道谁会先打电话:

我想覆盖标准控件的操作,但我不确定何时在我的代码之后或之前调用基本方法 base.OnMouseClick(e)

有人可以帮助阐明控件的事件处理程序顺序以做出正确的决定吗?

public class MyTextBox : TextBox
{
    protected override void OnMouseClick(MouseEventArgs e)
    {
        base.OnMouseClick(e);
        BackColor = Color.Red;
    }
}

现在鼠标点击文本框的背景颜色将变为红色。现在我们想要更改此行为,我们希望鼠标单击时显示绿色。

public class MyTextBox1 : MyTextBox
{
    protected override void OnMouseClick(MouseEventArgs e)
    {            
        base.OnMouseClick(e);
        BackColor = Color.Green;
    }
}

如果您致电 base.OnMouseClick(e),这里是您问题的答案;首先,您想要的结果将是绿色,如果您调用 base.OnMouseClick(e);最后你的最终结果将是红色,如基础 class.

protected override void OnMouseClick(MouseEventArgs e)
{
     BackColor = Color.Green;
     base.OnMouseClick(e);

}

Control.OnMouseClick 调用事件处理程序。实际上,正如您从文档中看到的那样,它没有做任何其他事情:

Raises the MouseClick event.

因此,您应该能够以相对直接的方式控制执行顺序:

protected override void OnMouseClick(MouseEventArgs e)
{
    Console.WriteLine("Before handlers");
    base.OnMouseClick(e);
    Console.WriteLine("After handlers");
}

void TextBox_MouseClick(object sender, EventArgs e)
{
    Console.WriteLine("Handler");
}    

如果您的父控件之一违反了 OnMouseDown 的约定(例如,在不调用基本方法的情况下覆盖它),这可能不起作用。

OnMouseDown 基本上只负责引发 MouseDown 事件。这就是 OnMouseDown 方法 Control class:

中所做的
protected virtual void OnMouseDown(MouseEventArgs e) {
    Contract.Requires(e != null);
    MouseEventHandler handler = (MouseEventHandler)Events[EventMouseDown];
    if (handler != null) handler(this, e);
}

然后根据要求,子控件会覆盖 OnMouseDown 以执行某些操作。例如:

  • DataGridView 覆盖它并首先调用 base.OnMouseDown ad 然后 hit-tests 检查鼠标是否已在单元格上完成,然后调用 OnCellMouseDown.
  • ToolStrip 覆盖它并首先 hit-tests 鼠标位置以检查它是否在引发 ToolStripItemMouseDown 事件的项目上。 否则调用base.OnMouseDown.

重要说明:请记住,如果您不调用 base.OnMouseDown 覆盖 OnMouseDown,那么 [=11] 中存在的自定义逻辑=] 基本控件的方法不会 运行。另外,MouseDown事件不会引发!