当我们覆盖OnPaint时,我们什么时候应该调用base.OnPaint()?

时间:2012-02-11 08:38:19

标签: c# winforms

我想知道在windows窗体程序中覆盖OnPaint时应该何时调用base.OnPaint?

我正在做的是:

  private void Form1_Paint(object sender, PaintEventArgs e)
        {
            // If there is an image and it has a location, 
            // paint it when the Form is repainted.
            base.OnPaint(e);

        }

我得到stackoerflowexception,为什么?

3 个答案:

答案 0 :(得分:7)

您没有覆盖OnPaint()方法。您只是订阅Paint个活动,因此不应致电base.OnPaint()
您应该(只能)在覆盖表单的base.OnPaint()方法时调用OnPaint()

protected override OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);

    // ... other drawing commands
}

Windows窗体控件上的OnPaint方法实际上会引发控件的Paint事件并绘制控件界面。通过在OnPaint事件处理程序中调用基本表单的Paint方法,您实际上是在告诉表单一次又一次地调用Paint处理程序,因此您将陷入无限循环,因此StackOverflowException

当你覆盖控件的OnPaint方法时,通常你应该调用基本方法,让控件自己绘制并调用订阅Paint事件的事件处理程序。如果不调用基本方法,则不会绘制某些控件方面,也不会调用任何事件处理程序。

答案 1 :(得分:3)

base.OnPaint(e)方法会引发Paint事件,因此您的Form1_Paint方法会在base.OnPaint内调用。这导致无限循环,最终导致StackOverflowException

正确的做法是覆盖OnPaint方法:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    //custom painting here...
}

有关详细信息,请参阅此MSDN link

答案 2 :(得分:2)

从上面的代码你没有覆盖OnPaint方法,你实际上是在处理paint事件,当然,如果你试图在处理程序中再次绘制它,你会得到一个无限循环。