Steadily painted over (slow application)

FMMM 0 Reputation points
2023-05-16T06:30:35.65+00:00

I am using the following code, but my application becomes quite slow. What I can do?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;

namespace MyControl.Controls_1
{
    public class MyButton : Button
    { 
    //Fields
    private int borderSize = 0;
    private int borderRadius = 0;
    private Color borderColor = Color.PaleVioletRed;

    //Properties
    [Category("MyButton Code Advance")]
    public int BorderSize
    {
        get { return borderSize; }
        set
        {
            borderSize = value;
            this.Invalidate();
        }
    }

    [Category("MyButton Code Advance")]
    public int BorderRadius
    {
        get { return borderRadius; }
        set
        {
            borderRadius = value;
            this.Invalidate();
        }
    }

    [Category("MyButton Code Advance")]
    public Color BorderColor
    {
        get { return borderColor; }
        set
        {
            borderColor = value;
            this.Invalidate();
        }
    }

    [Category("MyButton Code Advance")]
    public Color BackgroundColor
    {
        get { return this.BackColor; }
        set { this.BackColor = value; }
    }

    [Category("MyButton Code Advance")]
    public Color TextColor
    {
        get { return this.ForeColor; }
        set { this.ForeColor = value; }
    }

    //Constructor
    public MyButtonButton()
    {
        this.FlatStyle = FlatStyle.Flat;
        this.FlatAppearance.BorderSize = 0;
        this.Size = new Size(150, 40);
        this.BackColor = Color.MediumSlateBlue;
        this.ForeColor = Color.White;
        this.Resize += new EventHandler(Button_Resize);
    }

    //Methods
    private GraphicsPath GetFigurePath(Rectangle rect, int radius)
    {
        GraphicsPath path = new GraphicsPath();
        float curveSize = radius * 2F;

        path.StartFigure();
        path.AddArc(rect.X, rect.Y, curveSize, curveSize, 180, 90);
        path.AddArc(rect.Right - curveSize, rect.Y, curveSize, curveSize, 270, 90);
        path.AddArc(rect.Right - curveSize, rect.Bottom - curveSize, curveSize, curveSize, 0, 90);
        path.AddArc(rect.X, rect.Bottom - curveSize, curveSize, curveSize, 90, 90);
        path.CloseFigure();
        return path;
    }

    protected override void OnPaint(PaintEventArgs pevent)
    {
        base.OnPaint(pevent);


        Rectangle rectSurface = this.ClientRectangle;
        Rectangle rectBorder = Rectangle.Inflate(rectSurface, -borderSize, -borderSize);
        int smoothSize = 2;
        if (borderSize > 0)
            smoothSize = borderSize;

        if (borderRadius > 2) //Rounded button
        {
            using (GraphicsPath pathSurface = GetFigurePath(rectSurface, borderRadius))
            using (GraphicsPath pathBorder = GetFigurePath(rectBorder, borderRadius - borderSize))
            using (Pen penSurface = new Pen(this.Parent.BackColor, smoothSize))
            using (Pen penBorder = new Pen(borderColor, borderSize))
            {
                pevent.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                //Button surface
                this.Region = new Region(pathSurface);
                //Draw surface border for HD result
                pevent.Graphics.DrawPath(penSurface, pathSurface);

                //Button border                    
                if (borderSize >= 1)
                    //Draw control border
                    pevent.Graphics.DrawPath(penBorder, pathBorder);
            }
        }
        else //Normal button
        {
            pevent.Graphics.SmoothingMode = SmoothingMode.None;
            //Button surface
            this.Region = new Region(rectSurface);
            //Button border
            if (borderSize >= 1)
            {
                using (Pen penBorder = new Pen(borderColor, borderSize))
                {
                    penBorder.Alignment = PenAlignment.Inset;
                    pevent.Graphics.DrawRectangle(penBorder, 0, 0, this.Width - 1, this.Height - 1);
                }
            }
        }
    }
    protected override void OnHandleCreated(EventArgs e)
    {
        base.OnHandleCreated(e);
        this.Parent.BackColorChanged += new EventHandler(Container_BackColorChanged);
    }

    private void Container_BackColorChanged(object sender, EventArgs e)
    {
        this.Invalidate();
    }
    private void Button_Resize(object sender, EventArgs e)
    {
        if (borderRadius > this.Height)
            borderRadius = this.Height;
    }
}
}
.NET
.NET
Microsoft Technologies based on the .NET software framework.
1,136 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Jiale Xue - MSFT 3,766 Reputation points Microsoft Vendor
    2023-05-16T09:41:13.1633333+00:00

    Hi @FMMM , Welcome to Microsoft Q&A.

    I tried to simplify your code to see if it works.

    using System;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Windows.Forms;
    
    namespace WindowsFormsControlLibrary3
    {
        public partial class MyButton : Button
        {
            private int borderSize = 0;
            private int borderRadius = 0;
            private Color borderColor = Color.PaleVioletRed;
            private Color backgroundColor = Color.MediumSlateBlue;
            private Color textColor = Color.White;
    
            public int BorderSize
            {
                get { return borderSize; }
                set
                {
                    borderSize = value;
                    Invalidate();
                }
            }
    
            public int BorderRadius
            {
                get { return borderRadius; }
                set
                {
                    borderRadius = value;
                    Invalidate();
                }
            }
    
            public Color BorderColor
            {
                get { return borderColor; }
                set
                {
                    borderColor = value;
                    Invalidate();
                }
            }
    
            public Color BackgroundColor
            {
                get { return backgroundColor; }
                set
                {
                    backgroundColor = value;
                    Invalidate();
                }
            }
    
            public Color TextColor
            {
                get { return textColor; }
                set
                {
                    textColor = value;
                    Invalidate();
                }
            }
    
            public MyButton()
            {
                FlatStyle = FlatStyle.Flat;
                FlatAppearance.BorderSize = 0;
                Size = new Size(150, 40);
                BackColor = backgroundColor;
                ForeColor = textColor;
                Resize += Button_Resize;
            }
    
            private GraphicsPath GetFigurePath(Rectangle rect, int radius)
            {
                GraphicsPath path = new GraphicsPath();
    
                if (radius == 0)
                {
                    path.AddRectangle(rect);
                }
                else
                {
                    int curveSize = radius * 2;
    
                    path.AddArc(rect.X, rect.Y, curveSize, curveSize, 180, 90);
                    path.AddArc(rect.Right - curveSize, rect.Y, curveSize, curveSize, 270, 90);
                    path.AddArc(rect.Right - curveSize, rect.Bottom - curveSize, curveSize, curveSize, 0, 90);
                    path.AddArc(rect.X, rect.Bottom - curveSize, curveSize, curveSize, 90, 90);
                }
    
                path.CloseFigure();
                return path;
            }
    
            protected override void OnPaint(PaintEventArgs pevent)
            {
                base.OnPaint(pevent);
    
                var rectSurface = ClientRectangle;
                var rectBorder = Rectangle.Inflate(rectSurface, -borderSize, -borderSize);
                int smoothSize = Math.Min(borderSize, 2);
    
                using (var pathSurface = GetFigurePath(rectSurface, borderRadius))
                using (var pathBorder = GetFigurePath(rectBorder, borderRadius - borderSize))
                using (var penSurface = new Pen(backgroundColor, smoothSize))
                using (var penBorder = new Pen(borderColor, borderSize))
                {
                    pevent.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    
                    Region = new Region(pathSurface);
                    pevent.Graphics.DrawPath(penSurface, pathSurface);
    
                    if (borderSize >= 1)
                        pevent.Graphics.DrawPath(penBorder, pathBorder);
                }
            }
    
            protected override void OnHandleCreated(EventArgs e)
            {
                base.OnHandleCreated(e);
                Parent.BackColorChanged += Container_BackColorChanged;
            }
    
            private void Container_BackColorChanged(object sender, EventArgs e)
            {
                Invalidate();
            }
    
            private void Button_Resize(object sender, EventArgs e)
            {
                if (borderRadius > Height)
                    borderRadius = Height;
            }
        }
    }
    

    Best Regards,

    Jiale


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.