Search code examples
c#onpaint

Panel onPaint render artefacts


I created Panel class "GpanelBorder" which draw border in custom panel with code:

namespace GetterControlsLibary
{
    public class GpanelBorder : Panel
    {
        private Color colorBorder;
        public GpanelBorder()
        {
            SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.DrawRectangle(
                new Pen(
                    new SolidBrush(colorBorder), 8),
                    e.ClipRectangle);
        }

        public Color BorderColor
        {
            get
            {
                return colorBorder;
            }
            set
            {
                colorBorder = value;
            }
        }
    }
}

Works fine but when i in design mode, mouse click inside panel and move mouse or drag other control over this panel, artifacts are created (picture below)

enter image description here

How to fix it?


Solution

  • The .ClipRectangle parameter does NOT necessarily represent the entire area of your control to be painted within. It may represent a SMALLER portion of your control indicating just that portion needs to be repainted. You can use the "clip rectangle" to redraw only a portion of your control in situations where it would be too costly to compute and repaint the entire control. If that situation doesn't apply to you, then use the ClientRectangle to get the bounds of your entire control and use that to draw your border. Also, you are LEAKING a PEN and a SOLIDBRUSH. You need to .Dispose() of those resources when you're done with them. This is best done with a using block:

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        using (SolidBrush sb = new SolidBrush(colorBorder), 8))
        {
            using (Pen p = new Pen(sb))
            {
                e.Graphics.DrawRectangle(p, this.ClientRectangle);
            }
        }
    }
    

    You may need to create a new Rectangle based on ClientRectangle and adjust that to your liking before drawing.