2012-02-11 117 views
4

我想知道什么时候应该调用base.OnPaint,当我们重写OnPaint在Windows窗体程序中?什么时候应该调用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,为什么呢?

回答

6

您不是重写OnPaint()方法。您只订阅Paint事件,所以您不应该请致电base.OnPaint()
你应该(可能)只调用base.OnPaint()当您覆盖形式的OnPaint()方法:

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

    // ... other drawing commands 
} 

OnPaint方法在Windows窗体控件实际上提高了Paint事件的控制,也借鉴了控制面。通过调用Paint事件处理程序中的基本表单OnPaint方法,您实际上是在告诉表单一次又一次调用Paint处理函数,因此您将陷入无限循环,因此将陷入StackOverflowException

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

+0

如果您希望在重写方法的“其他绘图命令”之后引发Paint事件,该怎么办? – mbeckish 2013-01-18 18:43:09

+0

@mbeckish你可以在你自己的图纸之后轻松调用base方法,但是结果取决于控件的类型以及它在OnPaint方法中的作用。你应该知道,控制可以绘制你刚刚绘制的内容。希望擦除背景不会发生在'OnPaint'方法中,而是'OnPaintBackground'方法中。 – 2013-01-19 06:19:21

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

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

相关问题