Как правильно до делать кнопку, чтобы избавить от бага?

Доброго времени суток.
Столкнулся с такой проблемой, что после добавление в кнопку фотографии она перестаёт правильно работать, и появляются своеобразные баги, я считаю что это связанно с прорисовкой этой самой кнопки, но, не получается решить данную проблему в одиночку, буду очень благодарен любой помощи.
Чтобы было нагляднее я сделал для вас видео, посмотрите его пожалуйста, в замедленной форме, и вы увидите что на левой форме появляется баг, а вот в правой кнопке не какого бага нет...
Ссылка на видео

using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
 
namespace Test_Project.SupportClass
{
    [DesignerCategory("Code")]
    public class button_check : Control
    {
        private int m_BorderSize = 2;
        private int m_ButtonRoundRadius = 15;
 
        private bool IsHighlighted = false;
        private bool IsPressed = false;
 
        private Image _image;
        private ImageLayout LautsCallBack { get; set; }
 
        public button_check()
        {
            SetStyle(ControlStyles.Opaque |
                     ControlStyles.AllPaintingInWmPaint |
                     ControlStyles.ResizeRedraw |
                     ControlStyles.UserPaint, true);
            // To be explicit...
            SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
            this.DoubleBuffered = false;
            InitializeComponent();
        }
 
        private void InitializeComponent()
        {
            Size = new Size(100, 40);
            BackColor = Color.Tomato;
            BackColor2 = Color.Tomato;
            ButtonBorderColor = Color.Black;
            ButtonHighlightColor = Color.Orange;
            ButtonHighlightColor2 = Color.OrangeRed;
            ButtonHighlightForeColor = Color.Black;
 
            ButtonPressedColor = Color.Red;
            ButtonPressedColor2 = Color.Maroon;
            ButtonPressedForeColor = Color.White;
        }
        public ImageLayout LayoutImage
        {
            get
            {
                return LautsCallBack;
            }
            set
            {
                LautsCallBack = value;
                RecreateHandle();
            }
        }
        public Image ImageButtom
        {
            get
            {
                return _image;
            }
            set
            {
                _image = value;
                RecreateHandle();
            }
        }
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT
                return cp;
            }
        }
 
        // Invalidate(rect) in Design-Mode to refresh the view
        public int BorderSize
        {
            get => m_BorderSize;
            set
            {
                m_BorderSize = Math.Max(Math.Min(value, 6), 1);
                RepaintControl();
            }
        }
 
        // Set Max = 44, Min = 1 to avoid quirks and exceptions
        public int ButtonRoundRadius
        {
            get => m_ButtonRoundRadius;
            set
            {
                m_ButtonRoundRadius = Math.Max(Math.Min(value, 44), 1);
                RepaintControl();
            }
        }
 
        public override string Text
        {
            get => base.Text;
            set
            {
                base.Text = value;
                RepaintControl();
            }
        }
 
        // You should Invalidate the Parent also when these change
        public Color BorderColor { get; set; } = Color.Tomato;
        public Color BackColor2 { get; set; } = Color.Tomato;
 
        public Color ButtonBorderColor { get; set; }
        public Color ButtonHighlightColor { get; set; }
        public Color ButtonHighlightColor2 { get; set; }
        public Color ButtonHighlightForeColor { get; set; }
        public Color ButtonPressedColor { get; set; }
        public Color ButtonPressedColor2 { get; set; }
        public Color ButtonPressedForeColor { get; set; }
 
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
 
            var foreColor = IsPressed ? ButtonPressedForeColor : IsHighlighted ? ButtonHighlightForeColor : ForeColor;
            var backColor = IsPressed ? ButtonPressedColor : IsHighlighted ? ButtonHighlightColor : BackColor;
            var backColor2 = IsPressed ? ButtonPressedColor2 : IsHighlighted ? ButtonHighlightColor2 : BackColor2;
            var rect = Path.GetBounds();
            using (var pen = new Pen(ButtonBorderColor, m_BorderSize))
            using (var pathBrush = new LinearGradientBrush(rect, backColor, backColor2, LinearGradientMode.Vertical))
            using (var textBrush = new SolidBrush(foreColor))
            using (var sf = new StringFormat())
            {
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;
 
                e.Graphics.FillPath(pathBrush, Path);
                if (m_BorderSize > 0) e.Graphics.DrawPath(pen, Path);
 
                if (_image != null)
                {
                    switch (LayoutImage)
                    {
                        case ImageLayout.Stretch:
                            e.Graphics.DrawImage(_image, this.ClientRectangle);
                            break;
                        case ImageLayout.Center:
                            int left = (this.ClientSize.Width - _image.Width) / 2;
                            int top = (this.ClientSize.Height - _image.Height) / 2;
                            e.Graphics.DrawImage(_image, left, top);
                            break;
                        case ImageLayout.Tile:
                            using (var texture = new TextureBrush(_image))
                            {
                                e.Graphics.FillRectangle(texture, this.ClientRectangle);
                            }
                            break;
                        case ImageLayout.Zoom:
                            double xr = (double)this.ClientSize.Width / _image.Width;
                            double yr = (double)this.ClientSize.Height / _image.Height;
                            if (xr > yr)
                            {
                                rect.Width = (int)(_image.Width * yr);
                                rect.X = (this.ClientSize.Width - rect.Width) / 2;
                            }
                            else
                            {
                                rect.Height = (int)(_image.Height * xr);
                                rect.Y = (this.ClientSize.Height - rect.Height) / 2;
                            }
                            e.Graphics.DrawImage(_image, rect);
                            break;
                    }
                }
 
 
                rect.Inflate(-4, -4);
                e.Graphics.DrawString(Text, Font, textBrush, rect, sf);
            }
        }
 
        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            IsHighlighted = true;
            RepaintControl();
        }
 
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            IsHighlighted = false;
            IsPressed = false;
            RepaintControl();
        }
 
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            IsPressed = true;
            RepaintControl();
        }
 
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            IsPressed = false;
            RepaintControl();
        }
 
        private void RepaintControl()
        {
            Parent?.Invalidate(this.Bounds, true);
            Invalidate();
        }
 
        private GraphicsPath Path
        {
            get
            {
                var rect = ClientRectangle;
                int scaleOnBorder = -((m_BorderSize / 2) + 2);
                rect.Inflate(scaleOnBorder, scaleOnBorder);
                return GetRoundedRectangle(rect, m_ButtonRoundRadius);
            }
        }
 
        private GraphicsPath GetRoundedRectangle(Rectangle rect, int d)
        {
            var gp = new GraphicsPath();
            gp.StartFigure();
            gp.AddArc(rect.X, rect.Y, d, d, 180, 90);
            gp.AddArc(rect.X + rect.Width - d, rect.Y, d, d, 270, 90);
            gp.AddArc(rect.X + rect.Width - d, rect.Y + rect.Height - d, d, d, 0, 90);
            gp.AddArc(rect.X, rect.Y + rect.Height - d, d, d, 90, 90);
            gp.CloseFigure();
            return gp;
        }
    }
}
  • Вопрос задан
  • 145 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы