Jason Bayldon
Jason Bayldon

Reputation: 1296

Slow Paints On Panel Controls

I have created a custom class that uses an inherited panel, a picturebox and two labels that act as "icons" on a form for users to click and navigate throughout an application. I have done this because it gives a better graphical impression and is more customizable than just a button alone.

I have included a class to draw rounded rectangles from the following codeproject (they draw over the panel to make the panel look like it has rounded corners): http://www.codeproject.com/Articles/5649/Extended-Graphics-An-implementation-of-Rounded-Rec

In regards to painting, I have wired my MouseEnter and MouseLeave event to toggle a boolean and then call me.invalidate() to redraw the panel background based on the boolean set by the event. My code to redraw looks like:

 If mouseoverBool Then 'class variable mouseoverBool set by mouseenter/mouseleave to true/false

        Dim g As Graphics = e.Graphics
        g.SmoothingMode = SmoothingMode.AntiAlias
        Dim brush As New LinearGradientBrush(New Point(Me.Width / 2, 0), New Point(Me.Width / 2, Me.Height), Color.LightSteelBlue, Color.LightBlue)
        g.FillRoundedRectangle(brush, 0, 0, Me.Width - 1, Me.Height, 10)
        g.FillRoundedRectangle(New SolidBrush(Color.FromArgb(100, 118, 173, 218)), 0, 0, Me.Width, Me.Height, 10)
        g.DrawRoundedRectangle(New Pen(ControlPaint.Light(SystemColors.InactiveBorder, 0.0F)), 0, 0, Me.Width - 1, Me.Height - 1, 10)

    Else

        Dim g As Graphics = e.Graphics
        g.SmoothingMode = SmoothingMode.AntiAlias
        Dim brush As New LinearGradientBrush(New Point(Me.Width / 2, 0), New Point(Me.Width / 2, Me.Height), SystemColors.GradientInactiveCaption, ControlPaint.Dark(SystemColors.GradientActiveCaption, 0.5F))
        g.FillRoundedRectangle(brush, 0, 0, Me.Width - 1, Me.Height, 10)
        g.FillRoundedRectangle(New SolidBrush(Color.FromArgb(100, 118, 173, 218)), 0, 0, Me.Width, Me.Height, 10)
        g.DrawRoundedRectangle(New Pen(ControlPaint.Light(SystemColors.InactiveBorder, 0.0F)), 0, 0, Me.Width - 1, Me.Height - 1, 10)

       End If

Alternatively in C#:

if (mouseoverBool) {

Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
LinearGradientBrush brush = new LinearGradientBrush(new Point(this.Width / 2, 0), new Point(this.Width / 2, this.Height), Color.LightSteelBlue, Color.LightBlue);
g.FillRoundedRectangle(brush, 0, 0, this.Width - 1, this.Height, 10);
g.FillRoundedRectangle(new SolidBrush(Color.FromArgb(100, 118, 173, 218)), 0, 0, this.Width, this.Height, 10);
g.DrawRoundedRectangle(new Pen(ControlPaint.Light(SystemColors.InactiveBorder, 0f)), 0, 0, this.Width - 1, this.Height - 1, 10);

} else {

Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
LinearGradientBrush brush = new LinearGradientBrush(new Point(this.Width / 2, 0), new Point(this.Width / 2, this.Height), SystemColors.GradientInactiveCaption, ControlPaint.Dark(SystemColors.GradientActiveCaption, 0.5f));
g.FillRoundedRectangle(brush, 0, 0, this.Width - 1, this.Height, 10);
g.FillRoundedRectangle(new SolidBrush(Color.FromArgb(100, 118, 173, 218)), 0, 0, this.Width, this.Height, 10);
g.DrawRoundedRectangle(new Pen(ControlPaint.Light(SystemColors.InactiveBorder, 0f)), 0, 0, this.Width - 1, this.Height - 1, 10);

}

The problem occuring is that the labels and picturebox inside the panel (all controls set to transparent background) are slow to refresh their backgrounds the first time any of the custom "icon" panels paint the background. The panel paints, then like half a second later, the backgrounds on the labels and picturebox finally updates. I assume that this is occuring because calling .invalidate() forces the custom panel to repaint, and then subsequently all the controls thereafter. I am after a 'seamless' paint where the entire control paints at once, including the labels and picturebox. How should I be attempting to achieve this?

Upvotes: 1

Views: 874

Answers (1)

Jason Bayldon
Jason Bayldon

Reputation: 1296

I was using 2 labels and a picturebox in my custom panel to display text and a picture. As pointed out in the comments, you could easily just draw these items yourself (which not only is faster, but makes better sense since you have to handle all your controls mouseEnter/mouseLeave events by using controls in the first place) which stops the flicker from occuring.

Since I already have properties created to hold the image and label text (which was used with the former controls), it wass pretty easy to transition this into a paint event for my custom panel.

    e.Graphics.DrawString(Me.txtHeaderDescription, New Font("Calibri", 12, FontStyle.Italic), Brushes.White, New Point(105, 15))

    Dim sf As New StringFormat
    sf.Alignment = StringAlignment.Near
    Dim Rectf As RectangleF = New Rectangle(105, 35, 200, 75)
    e.Graphics.DrawString(Me.txtDescription, New Font("Calibri", 8, FontStyle.Regular), Brushes.White, Rectf, sf)

    e.Graphics.DrawImage(Me.MyImage, 5, 3, 96, 96)

Upvotes: 0

Related Questions