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.
3,537 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Jiale Xue - MSFT 41,736 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.


  2. FMMM 0 Reputation points
    2023-06-04T17:52:07.8133333+00:00

    Reviewing code I found a code that redesigned the form. delete and solved


  3. FMMM 0 Reputation points
    2023-06-05T10:37:20.6666667+00:00

    This code caused me to freeze the entire application once the form was loaded. This led to looping redesign of the components.

    
        Protected Overrides ReadOnly Property CreateParams() As CreateParams
            Get
                Dim cp As CreateParams = MyBase.CreateParams
                cp.ExStyle = cp.ExStyle Or &H2000000
                ' Turn on WS_EX_COMPOSITED
                Return cp
            End Get
        End Property