Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Invalidate is not calling paint method

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.

like image 461
l46kok Avatar asked Jul 09 '12 06:07

l46kok


2 Answers

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.

like image 97
Jcl Avatar answered Sep 17 '22 18:09

Jcl


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.

like image 23
supercat Avatar answered Sep 17 '22 18:09

supercat