问题
I have OnPaint method overrided to draw an Ellipse on the screen.
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();
}
The scroll event (On the Richtextbox) is handled properly but even though I am invalidating the form, it isn't calling the OnPaint function (The messagebox isn't showing).
What could be the possible cause of this?
Edit: I have forgot to mention that on my initialization function of the child form (added as a control of the main form using MDI property), I set the following styles:
private void LogicCodeInit()
{
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.UserPaint, true);
}
Edit2: I've also forgot to mention that the child form is added as a control of TabControl. The TabControl then is added as a control of the main form.
回答1:
Call Update
after Invalidate
. Invalidate
repaints the form only if it has focus, it's probably not getting focus since it's being added as a TabControl
child.
From MSDN documentation:
Calling the Invalidate method does not force a synchronous paint; to force a synchronous paint, call the Update method after calling the Invalidate method. When this method is called with no parameters, the entire client area is added to the update region.
回答2:
Calling Invalidate
on a control will cause invalidate some or all of it, indicating that it needs to be updated "sometime", but will not cause that update to occur immediately. Calling Update
will cause any parts of a control which have been invalidated to be redrawn immediately. Calling Refresh
will combine the above effects. Whenever the system is idle, it will call process updates for controls which have any invalidated regions.
The Invalidate
method is useful in situations where many methods that change what should appear on a control are executed in sequence. Rather than having to redraw the control after every method that changes it, one can have the methods which change the control invalidate those parts which need redrawing. Once all the methods that might change the control have been completed, one may then use Update
to redraw those parts of the control (if any) which have been invalidated. If redrawing the control would take 1/100 second, and one needs to perform fifty operations upon it, deferring and consolidating the updates may make the difference between a control which seems to update instantaneously, and one which takes a half-second.
回答3:
The main reason why OnPaint
might not be called is if your ControlStyle
doesn't include UserPaint
. I would have expected you to mention this if you did set it, so I am assuming you didn't. In that case, add a call to SetStyle
in your constructor.
来源:https://stackoverflow.com/questions/11389850/c-sharp-invalidate-is-not-calling-paint-method