C#Invalidate不调用paint方法
我有OnPaint方法覆盖在屏幕上绘制一个椭圆。
protected override void OnPaint(PaintEventArgs e) { MessageBox.Show("Paint"); if (debugStarted) { int y = rtbLogicCode.PlaceToPoint(new Place(0, debugLine)).Y; if (rtbLogicCode.GetVisibleState(debugLine).ToString() == "Visible") { e.Graphics.FillEllipse(new LinearGradientBrush(new Rectangle(0, y, 15, 15), Color.LightPink, Color.Red, 45), 0, y, 15, 15); } base.OnPaint(e); } } private void rtbLogicCode_Scroll(object sender, ScrollEventArgs e) { this.Invalidate(); }
滚动事件(在Richtextbox上)被正确处理,但即使我使表单无效,它也没有调用OnPaint函数(消息框未显示)。
可能的原因是什么?
编辑:我忘了提到我的子窗体的初始化函数(使用MDI属性添加为主窗体的控件),我设置以下样式:
private void LogicCodeInit() { this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.UserPaint, true); }
Edit2:我也忘了提到子窗体是作为TabControl的控件添加的。 然后将TabControl添加为主窗体的控件。
Invalidate
后调用Update
。 Invalidate
只有在具有焦点时重新绘制表单,它可能无法获得焦点,因为它被添加为TabControl
子TabControl
。
从MSDN文档 :
调用Invalidate方法不会强制执行同步绘制; 要强制执行同步绘制, 请在调用Invalidate方法后调用Update方法 。 如果在没有参数的情况下调用此方法,则会将整个客户端区域添加到更新区域。
在控件上调用Invalidate
将导致部分或全部失效,表明需要“某个时间”更新,但不会导致更新立即发生。 调用Update
将导致控件的任何已失效的部分立即重绘。 调用Refresh
将结合上述效果。 每当系统空闲时,它将调用具有任何无效区域的控件的进程更新。
Invalidate
方法在按顺序执行许多更改控件上应显示内容的方法的情况下非常有用。 在改变控件的每个方法之后,不必重新绘制控件,可以使用更改控件的方法使那些需要重绘的部分无效。 一旦完成了可能更改控件的所有方法,就可以使用Update
重新绘制已失效的控件部分(如果有)。 如果重新绘制控件需要1/100秒,并且需要对其执行50次操作,则推迟和合并更新可能会使控件看起来立即更新,而控制则需要半秒。
如果您的ControlStyle
不包含UserPaint
则可能无法调用OnPaint
UserPaint
。 如果你确实设置了我,我本以为你会提到这个,所以我假设你没有。 在这种情况下,在构造函数中添加对SetStyle
的调用。