5

我注意到在 C# 中我可以覆盖 Form() 父类中的方法,如下所示:

    protected override void OnPaint(PaintEventArgs e)
    {

    }

我不明白如何PaintEventArgs生成以及如何/何时将其传递给此函数。我必须假设OnPaint()每次表单需要重新绘制时都会调用它。

此外,当我创建按钮按下事件时,它们看起来像这样:

    private void button1_Click(object sender, EventArgs e)
    {

    }

再一次,我不明白在激活按钮单击时如何/为什么传递这些参数。

4

3 回答 3

12

它没有什么特别之处。定义Paint事件的基类包含道德上与此等效的代码:

protected virtual void OnPaint(PaintEventArgs e)
{    
    var paintHandlers = this.Paint;
    if (paintHandlers != null)
    {
        paintHandlers(this, e);
    }
}

OnPaint有两个作用:

  1. 引发Paint事件,以便通知外部订阅者(这就是form1_Paint最终调用假设的方式)。
  2. 让派生类直接响应绘制事件,而无需涉及事件处理程序——只需重写方法(但派生类不能忘记调用基实现!)。

当需要引发Paint事件时,基类中的其他一些代码会PaintEventArgs根据手头的信息创建一个实例并调用OnPaint

// ...somewhere in the class...
OnPaint(new PaintEventArgs(...));

EventArgs在不需要创建新实例而键入事件参数的特殊情况下,您可以直接将EventArgs.Empty静态成员传递给OnSomething方法。

至于何时发生:每当从应用程序的消息泵中提取消息并进行处理时,它都表明应该引发该事件。您可能还想阅读了解 C# 中的事件和事件处理程序

于 2013-09-12T18:16:36.360 回答
1

最好的起点是(重新?)熟悉.Net“代表”:

例如,如果您查看 C# 表单的代码,您可能会看到如下内容:

private void btnGo_Click(object sender, EventArgs e)
{
    // My code goes here...

现在,如果您查看相应的自动生成的 .Design 代码,您会看到如下内容:

private void InitializeComponent()
{
    this.btnGo.Click += new System.EventHandler(this.btnGo_Click);
    ....

"+=" 语法将您的自定义事件处理程序分配给按钮。任何有关“代表”的教程(包括我上面引用的链接)都会为您提供有关其工作方式和原因的更多详细信息。

我希望这有帮助.. PSM

于 2013-09-12T18:16:44.507 回答
1

在按钮单击事件处理程序的情况下,object sender, EventArgs e语法允许将多个按钮连接到单个事件处理程序。这是可能的,因为sender是启动事件的对象,因此您可以区分是 button1、button2 还是 button3 启动了事件。

并且由于senderobject,那么您可以想象有一个单击处理程序来处理所有可单击的页面元素,并在处理程序中有一堆条件逻辑来根据启动事件的控制类型进行切换;不建议这样做。

于 2013-09-12T18:21:28.443 回答