C# 自繪 Bootstrap 風格 WinForms 按鈕

有關 WinForms 控件自繪的文章,百度一下有很多,GitHub 上也有開源的控件,如 MaterialSkin for .NET WinForms
本文通過實現一個 Bootstrap 風格的按鈕控件,向大家展示 WinForms 控件自繪的基本方法。

Bootstrap 風格按鈕如下:
在這裏插入圖片描述

創建 WinForms 控件庫

啓動 Visual Studio,新建 Windows 窗體控件庫。
在這裏插入圖片描述
刪除自動添加的 UserControl1 控件。

添加自定義控件

從【項目】菜單中選擇【添加新項】,打開【添加新項】對話框,添加一個自定義控件。
在這裏插入圖片描述
在開始實現自繪按鈕之前,先要做一些準備工作。

添加繪製圓角矩形的函數

Bootstrap 按鈕都是圓角的,但 GDI+ 裏並沒有繪製圓角矩形的方法,我們需要自己編寫一個。
添加一個名爲 DrawHelper 的靜態類,並添加一個名爲 CreateRoundRect 的方法。

using System.Drawing.Drawing2D;

namespace BootstrapButton
{
    static class DrawHelper
    {
        public static GraphicsPath CreateRoundRect(float x, float y, float width, float height, float radius)
        {
            var gp = new GraphicsPath();
            gp.AddLine(x + radius, y, x + width - (radius * 2), y);
            gp.AddArc(x + width - (radius * 2), y, radius * 2, radius * 2, 270, 90);
            gp.AddLine(x + width, y + radius, x + width, y + height - (radius * 2));
            gp.AddArc(x + width - (radius * 2), y + height - (radius * 2), radius * 2, radius * 2, 0, 90);
            gp.AddLine(x + width - (radius * 2), y + height, x + radius, y + height);
            gp.AddArc(x, y + height - (radius * 2), radius * 2, radius * 2, 90, 90);
            gp.AddLine(x, y + height - (radius * 2), x, y + radius);
            gp.AddArc(x, y, radius * 2, radius * 2, 180, 90);
            gp.CloseFigure();
            return gp;
        }
    }
}

定義 Bootstrap 按鈕顏色

Bootstrap 按鈕有 8 種顏色風格,先把這些顏色定義出來。

using System.Drawing;

namespace BootstrapButton
{
    class ButtonColor
    {
        private static int _disabledOpacity = 165;
        public Color BackgroundColor, BorderColor, TextColor, ShadowColor, HoverBackgroundColor, HoverTextColor, DisabledColor, ActiveColor;

        public static ButtonColor Primary, Secondary, Success, Danger, Warning, Info, Light, Dark;
        public static ButtonColor OutlinePrimary, OutlineSecondary, OutlineSuccess, OutlineDanger, OutlineWarning, OutlineInfo, OutlineLight, OutlineDark;

        static ButtonColor()
        {
            Primary = new ButtonColor();
            Primary.BackgroundColor = ToColor((int)BackgroundColorEnum.Primary);
            Primary.BorderColor = Primary.BackgroundColor;
            Primary.TextColor = Color.White;
            Primary.ShadowColor = ToColor((int)ShadowColorEnum.Primary);
            Primary.HoverBackgroundColor = ToColor((int)HoverBackgroundColorEnum.Primary);
            Primary.HoverTextColor = Primary.TextColor;
            Primary.DisabledColor = Color.FromArgb(_disabledOpacity, Primary.BackgroundColor);
            Primary.ActiveColor = Primary.HoverBackgroundColor;

            Secondary = new ButtonColor();
            Secondary.BackgroundColor = ToColor((int)BackgroundColorEnum.Secondary);
            Secondary.BorderColor = Secondary.BackgroundColor;
            Secondary.TextColor = Color.White;
            Secondary.ShadowColor = ToColor((int)ShadowColorEnum.Secondary);
            Secondary.HoverBackgroundColor = ToColor((int)HoverBackgroundColorEnum.Secondary);
            Secondary.HoverTextColor = Secondary.TextColor;
            Secondary.DisabledColor = Color.FromArgb(_disabledOpacity, Secondary.BackgroundColor);
            Secondary.ActiveColor = Secondary.HoverBackgroundColor;

            Success = new ButtonColor();
            Success.BackgroundColor = ToColor((int)BackgroundColorEnum.Success);
            Success.BorderColor = Success.BackgroundColor;
            Success.TextColor = Color.White;
            Success.ShadowColor = ToColor((int)ShadowColorEnum.Success);
            Success.HoverBackgroundColor = ToColor((int)HoverBackgroundColorEnum.Success);
            Success.HoverTextColor = Success.TextColor;
            Success.DisabledColor = Color.FromArgb(_disabledOpacity, Success.BackgroundColor);
            Success.ActiveColor = Success.HoverBackgroundColor;

            Danger = new ButtonColor();
            Danger.BackgroundColor = ToColor((int)BackgroundColorEnum.Danger);
            Danger.BorderColor = Danger.BackgroundColor;
            Danger.TextColor = Color.White;
            Danger.ShadowColor = ToColor((int)ShadowColorEnum.Danger);
            Danger.HoverBackgroundColor = ToColor((int)HoverBackgroundColorEnum.Danger);
            Danger.HoverTextColor = Danger.TextColor;
            Danger.DisabledColor = Color.FromArgb(_disabledOpacity, Danger.BackgroundColor);
            Danger.ActiveColor = Danger.HoverBackgroundColor;

            Warning = new ButtonColor();
            Warning.BackgroundColor = ToColor((int)BackgroundColorEnum.Warning);
            Warning.BorderColor = Warning.BackgroundColor;
            Warning.TextColor = Color.Black;
            Warning.ShadowColor = ToColor((int)ShadowColorEnum.Warning);
            Warning.HoverBackgroundColor = ToColor((int)HoverBackgroundColorEnum.Warning);
            Warning.HoverTextColor = Warning.TextColor;
            Warning.DisabledColor = Color.FromArgb(_disabledOpacity, Warning.BackgroundColor);
            Warning.ActiveColor = Warning.HoverBackgroundColor;

            Info = new ButtonColor();
            Info.BackgroundColor = ToColor((int)BackgroundColorEnum.Info);
            Info.BorderColor = Info.BackgroundColor;
            Info.TextColor = Color.White;
            Info.ShadowColor = ToColor((int)ShadowColorEnum.Info);
            Info.HoverBackgroundColor = ToColor((int)HoverBackgroundColorEnum.Info);
            Info.HoverTextColor = Info.TextColor;
            Info.DisabledColor = Color.FromArgb(_disabledOpacity, Info.BackgroundColor);
            Info.ActiveColor = Info.HoverBackgroundColor;

            Light = new ButtonColor();
            Light.BackgroundColor = ToColor((int)BackgroundColorEnum.Light);
            Light.BorderColor = Light.BackgroundColor;
            Light.TextColor = Color.Black;
            Light.ShadowColor = ToColor((int)ShadowColorEnum.Light);
            Light.HoverBackgroundColor = ToColor((int)HoverBackgroundColorEnum.Light);
            Light.HoverTextColor = Light.TextColor;
            Light.DisabledColor = Color.FromArgb(_disabledOpacity, Light.BackgroundColor);
            Light.ActiveColor = Light.HoverBackgroundColor;

            Dark = new ButtonColor();
            Dark.BackgroundColor = ToColor((int)BackgroundColorEnum.Dark);
            Dark.BorderColor = Dark.BackgroundColor;
            Dark.TextColor = Color.White;
            Dark.ShadowColor = ToColor((int)ShadowColorEnum.Dark);
            Dark.HoverBackgroundColor = ToColor((int)HoverBackgroundColorEnum.Dark);
            Dark.HoverTextColor = Dark.TextColor;
            Dark.DisabledColor = Color.FromArgb(_disabledOpacity, Dark.BackgroundColor);
            Dark.ActiveColor = Dark.HoverBackgroundColor;

            OutlinePrimary = new ButtonColor();
            OutlinePrimary.BackgroundColor = Color.White;
            OutlinePrimary.BorderColor = ToColor((int)BackgroundColorEnum.Primary);
            OutlinePrimary.TextColor = OutlinePrimary.BorderColor;
            OutlinePrimary.ShadowColor = ToColor((int)OutlineShadowColorEnum.Primary);
            OutlinePrimary.HoverBackgroundColor = OutlinePrimary.BorderColor;
            OutlinePrimary.HoverTextColor = Color.White;
            OutlinePrimary.DisabledColor = Color.FromArgb(_disabledOpacity, OutlinePrimary.TextColor);
            OutlinePrimary.ActiveColor = ToColor((int)HoverBackgroundColorEnum.Primary);

            OutlineSecondary = new ButtonColor();
            OutlineSecondary.BackgroundColor = Color.White;
            OutlineSecondary.BorderColor = ToColor((int)BackgroundColorEnum.Secondary);
            OutlineSecondary.TextColor = OutlineSecondary.BorderColor;
            OutlineSecondary.ShadowColor = ToColor((int)OutlineShadowColorEnum.Secondary);
            OutlineSecondary.HoverBackgroundColor = OutlineSecondary.BorderColor;
            OutlineSecondary.HoverTextColor = Color.White;
            OutlineSecondary.DisabledColor = Color.FromArgb(_disabledOpacity, OutlineSecondary.TextColor);
            OutlineSecondary.ActiveColor = ToColor((int)HoverBackgroundColorEnum.Secondary);

            OutlineSuccess = new ButtonColor();
            OutlineSuccess.BackgroundColor = Color.White;
            OutlineSuccess.BorderColor = ToColor((int)BackgroundColorEnum.Success);
            OutlineSuccess.TextColor = OutlineSuccess.BorderColor;
            OutlineSuccess.ShadowColor = ToColor((int)OutlineShadowColorEnum.Success);
            OutlineSuccess.HoverBackgroundColor = OutlineSuccess.BorderColor;
            OutlineSuccess.HoverTextColor = Color.White;
            OutlineSuccess.DisabledColor = Color.FromArgb(_disabledOpacity, OutlineSuccess.TextColor);
            OutlineSuccess.ActiveColor = ToColor((int)HoverBackgroundColorEnum.Success);

            OutlineDanger = new ButtonColor();
            OutlineDanger.BackgroundColor = Color.White;
            OutlineDanger.BorderColor = ToColor((int)BackgroundColorEnum.Danger);
            OutlineDanger.TextColor = OutlineDanger.BorderColor;
            OutlineDanger.ShadowColor = ToColor((int)OutlineShadowColorEnum.Danger);
            OutlineDanger.HoverBackgroundColor = OutlineDanger.BorderColor;
            OutlineDanger.HoverTextColor = Color.White;
            OutlineDanger.DisabledColor = Color.FromArgb(_disabledOpacity, OutlineDanger.TextColor);
            OutlineDanger.ActiveColor = ToColor((int)HoverBackgroundColorEnum.Danger);

            OutlineWarning = new ButtonColor();
            OutlineWarning.BackgroundColor = Color.White;
            OutlineWarning.BorderColor = ToColor((int)BackgroundColorEnum.Warning);
            OutlineWarning.TextColor = OutlineWarning.BorderColor;
            OutlineWarning.ShadowColor = ToColor((int)OutlineShadowColorEnum.Warning);
            OutlineWarning.HoverBackgroundColor = OutlineWarning.BorderColor;
            OutlineWarning.HoverTextColor = Color.Black;
            OutlineWarning.DisabledColor = Color.FromArgb(_disabledOpacity, OutlineWarning.TextColor);
            OutlineWarning.ActiveColor = ToColor((int)HoverBackgroundColorEnum.Warning);

            OutlineInfo = new ButtonColor();
            OutlineInfo.BackgroundColor = Color.White;
            OutlineInfo.BorderColor = ToColor((int)BackgroundColorEnum.Info);
            OutlineInfo.TextColor = OutlineInfo.BorderColor;
            OutlineInfo.ShadowColor = ToColor((int)OutlineShadowColorEnum.Info);
            OutlineInfo.HoverBackgroundColor = OutlineInfo.BorderColor;
            OutlineInfo.HoverTextColor = Color.White;
            OutlineInfo.DisabledColor = Color.FromArgb(_disabledOpacity, OutlineInfo.TextColor);
            OutlineInfo.ActiveColor = ToColor((int)HoverBackgroundColorEnum.Info);

            OutlineLight = new ButtonColor();
            OutlineLight.BackgroundColor = Color.White;
            OutlineLight.BorderColor = ToColor((int)BackgroundColorEnum.Light);
            OutlineLight.TextColor = Color.Black;
            OutlineLight.ShadowColor = ToColor((int)OutlineShadowColorEnum.Light);
            OutlineLight.HoverBackgroundColor = OutlineLight.BorderColor;
            OutlineLight.HoverTextColor = Color.Black;
            OutlineLight.DisabledColor = Color.FromArgb(_disabledOpacity, OutlineLight.TextColor);
            OutlineLight.ActiveColor = ToColor((int)HoverBackgroundColorEnum.Light);

            OutlineDark = new ButtonColor();
            OutlineDark.BackgroundColor = Color.White;
            OutlineDark.BorderColor = ToColor((int)BackgroundColorEnum.Dark);
            OutlineDark.TextColor = OutlineDark.BorderColor;
            OutlineDark.ShadowColor = ToColor((int)OutlineShadowColorEnum.Dark);
            OutlineDark.HoverBackgroundColor = OutlineDark.BorderColor;
            OutlineDark.HoverTextColor = Color.White;
            OutlineDark.DisabledColor = Color.FromArgb(_disabledOpacity, OutlineDark.TextColor);
            OutlineDark.ActiveColor = ToColor((int)HoverBackgroundColorEnum.Dark);
        }

        public static Color GetDisabledColor(Color color)
        {
            return Color.FromArgb(_disabledOpacity, color);
        }

        public static ButtonColor GetButtonColor(ButtonType buttonType, bool outlineStyle)
        {
            ButtonColor buttonColor = ButtonColor.Primary;
            if (false == outlineStyle)
            {
                if (buttonType == ButtonType.Primary)
                {
                    buttonColor = ButtonColor.Primary;
                }
                else if (buttonType == ButtonType.Secondary)
                {
                    buttonColor = ButtonColor.Secondary;
                }
                else if (buttonType == ButtonType.Success)
                {
                    buttonColor = ButtonColor.Success;
                }
                else if (buttonType == ButtonType.Danger)
                {
                    buttonColor = ButtonColor.Danger;
                }
                else if (buttonType == ButtonType.Warning)
                {
                    buttonColor = ButtonColor.Warning;
                }
                else if (buttonType == ButtonType.Info)
                {
                    buttonColor = ButtonColor.Info;
                }
                else if (buttonType == ButtonType.Light)
                {
                    buttonColor = ButtonColor.Light;
                }
                else if (buttonType == ButtonType.Dark)
                {
                    buttonColor = ButtonColor.Dark;
                }
            }
            else
            {
                if (buttonType == ButtonType.Primary)
                {
                    buttonColor = ButtonColor.OutlinePrimary;
                }
                else if (buttonType == ButtonType.Secondary)
                {
                    buttonColor = ButtonColor.OutlineSecondary;
                }
                else if (buttonType == ButtonType.Success)
                {
                    buttonColor = ButtonColor.OutlineSuccess;
                }
                else if (buttonType == ButtonType.Danger)
                {
                    buttonColor = ButtonColor.OutlineDanger;
                }
                else if (buttonType == ButtonType.Warning)
                {
                    buttonColor = ButtonColor.OutlineWarning;
                }
                else if (buttonType == ButtonType.Info)
                {
                    buttonColor = ButtonColor.OutlineInfo;
                }
                else if (buttonType == ButtonType.Light)
                {
                    buttonColor = ButtonColor.OutlineLight;
                }
                else if (buttonType == ButtonType.Dark)
                {
                    buttonColor = ButtonColor.OutlineDark;
                }
            }
            return buttonColor;
        }

        public static Color ToColor(int argb)
        {
            return Color.FromArgb(
                (argb & 0xff0000) >> 16,
                (argb & 0xff00) >> 8,
                 argb & 0xff);
        }
    }

    public enum BackgroundColorEnum
    {
        Primary = 0x007bff,
        Secondary = 0x6c757d,
        Success = 0x28a745,
        Danger = 0xdc3545,
        Warning = 0xffc107,
        Info = 0x17a2b8,
        Light = 0xf8f9fa,
        Dark = 0x343a40
    }

    public enum HoverBackgroundColorEnum
    {
        Primary = 0x0069d9,
        Secondary = 0x5a6268,
        Success = 0x218838,
        Danger = 0xc82333,
        Warning = 0xe0a800,
        Info = 0x138496,
        Light = 0xe2e6ea,
        Dark = 0x23272b
    }

    public enum ShadowColorEnum
    {
        Primary = 0x92C7FF,
        Secondary = 0xC0C4C8,
        Success = 0xA3D9B0,
        Danger = 0xF0A9B0,
        Warning = 0xEED485,
        Info = 0x9CD7E1,
        Light = 0xEBECED,
        Dark = 0xA8ABAE
    }

    public enum OutlineShadowColorEnum
    {
        Primary = 0x7FBDFF,
        Secondary = 0xB5BABE,
        Success = 0x93D3A2,
        Danger = 0xED9AA2,
        Warning = 0xFFE083,
        Info = 0x8BD0DB,
        Light = 0xFBFCFC,
        Dark = 0x999C9F
    }

    public enum ButtonType
    {
        Primary,
        Secondary,
        Success,
        Danger,
        Warning,
        Info,
        Light,
        Dark
    }
}

實現自繪按鈕

自定義繪製按鈕,有兩個要點:

  • System.Windows.Forms.Button 繼承
  • 重寫 OnPaint 方法
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;

namespace BootstrapButton
{
    public partial class BootstrapButton : Button
    {
        private const float _fontSize = 16f;
        private const int _borderWidth = 1;
        private const int _shadowWidth = 3;

        private bool _isHover = false;

        private ButtonSize _buttonSize = ButtonSize.Default;
        private ButtonType _buttonType = ButtonType.Primary;
        private bool _outlineStyle = false;
        private bool _activeState = false;

        [
        Category("Bootstrap"),
        DefaultValue(ButtonSize.Default),
        Description("按鈕尺寸。Bootstrap 按鈕有大、中、小三種尺寸,缺省尺寸爲 中。")
        ]
        public ButtonSize ButtonSize
        {
            get
            {
                return _buttonSize;
            }
            set
            {
                _buttonSize = value;
                SetFont();
                SetButtonSize();
                Invalidate();
            }
        }

        [
        Category("Bootstrap"),
        DefaultValue(ButtonType.Primary),
        Description("按鈕類型。Bootstrap 按鈕有八種類型,即八種不同顏色。")
        ]
        public ButtonType ButtonType
        {
            get
            {
                return _buttonType;
            }
            set
            {
                _buttonType = value;
                SetButtonColor();
                Invalidate();
            }
        }

        [
        Category("Bootstrap"),
        DefaultValue(false),
        Description("Outline 風格按鈕。")
        ]
        public bool OutlineStyle
        {
            get
            {
                return _outlineStyle;
            }
            set
            {
                _outlineStyle = value;
                SetButtonColor();
                Invalidate();
            }
        }
        
        [
        Category("Bootstrap"),
        DefaultValue(false),
        Description("Active 風格按鈕。")
        ]
        public bool ActiveState
        {
            get
            {
                return _activeState;
            }
            set
            {
                _activeState = value;
                SetButtonColor();
                Invalidate();
            }
        }

        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                base.Text = value;
                SetButtonSize();
                Invalidate();
            }
        }

        public BootstrapButton()
        {
            InitializeComponent();
        }

        protected override void OnCreateControl()
        {
            base.OnCreateControl();
            
            if (DesignMode)
            {
                return;
            }

            if (this.Enabled == true)
            {
                this.Cursor = Cursors.Hand;
            }
            else
            {
                this.Cursor = Cursors.Default;
            }

            MouseEnter += (sender, args) =>
            {
                this._isHover = true;
                Invalidate();
            };
            MouseLeave += (sender, args) =>
            {
                this._isHover = false;
                Invalidate();
            };
            Enter += (sender, args) =>
            {
                int buttonX = this.Location.X - _shadowWidth;
                int buttonY = this.Location.Y - _shadowWidth;
                this.Location = new Point(buttonX, buttonY);
                this.Width += _shadowWidth * 2;
                this.Height += _shadowWidth * 2;
                Invalidate();
            };
            Leave += (sender, args) =>
            {
                int buttonX = this.Location.X + _shadowWidth;
                int buttonY = this.Location.Y + _shadowWidth;
                this.Location = new Point(buttonX, buttonY);
                this.Width -= _shadowWidth * 2;
                this.Height -= _shadowWidth * 2;
                Invalidate();
            };
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            var g = pe.Graphics;

            g.SmoothingMode = SmoothingMode.AntiAlias;
            if (this.ButtonSize == ButtonSize.Large)
            {
                g.TextRenderingHint = TextRenderingHint.AntiAlias;
            }

            // clear the control
            g.Clear(Parent.BackColor);

            SetFont();
            SetButtonSize();

            Brush whiteBrush = new SolidBrush(Color.White);

            //獲取顏色
            ButtonColor buttonColor = ButtonColor.GetButtonColor(this.ButtonType, this.OutlineStyle);
            Color backgroundColor = buttonColor.BackgroundColor;
            Color textColor = buttonColor.TextColor;
            Color borderColor = buttonColor.BorderColor;

            if (this._activeState == true)
            {
                if (this._outlineStyle == false)
                {
                    backgroundColor = buttonColor.ActiveColor;
                }
                else
                {
                    textColor = buttonColor.ActiveColor;
                    borderColor = buttonColor.ActiveColor;
                }
            }
            if (this._isHover == true)
            {
                backgroundColor = buttonColor.HoverBackgroundColor;
                textColor = buttonColor.HoverTextColor;
                if (this._activeState == true)
                {
                    if (this._outlineStyle == true)
                    {
                        backgroundColor = buttonColor.ActiveColor;
                    }
                }
            }
            if (this.Enabled == false)
            {
                borderColor = ButtonColor.GetDisabledColor(backgroundColor);
                if (false == this._outlineStyle)
                {
                    backgroundColor = ButtonColor.GetDisabledColor(backgroundColor);
                }
                if (true == this._outlineStyle)
                {
                    textColor = ButtonColor.GetDisabledColor(textColor);
                }
            }

            float borderRadius = this.GetBorderRadius();

            //繪製焦點框
            if (true == this.Focused)
            {
                using (Brush shadowBrush = new SolidBrush(buttonColor.ShadowColor))
                {
                    using (var shadowPath = DrawHelper.CreateRoundRect(0, 0, this.Width - 1, this.Height - 1, borderRadius))
                    {
                        g.FillPath(shadowBrush, shadowPath);
                    }
                }
            }

            if (this._outlineStyle)
            {
                //繪製邊框
                RectangleF borderRect = new RectangleF();
                borderRect.X = 0;
                borderRect.Y = 0;
                borderRect.Width = this.Width;
                borderRect.Height = this.Height;

                if (true == this.Focused)  //有焦點的時候,最外圈是焦點框
                {
                    borderRect.X += _shadowWidth;
                    borderRect.Y += _shadowWidth;

                    borderRect.Width = this.Width - _shadowWidth * 2;
                    borderRect.Height = this.Height - _shadowWidth * 2;
                }

                using (Brush borderBrush = new SolidBrush(borderColor))
                {
                    using (var borderPath = DrawHelper.CreateRoundRect(borderRect.X, borderRect.Y, borderRect.Width - 1, borderRect.Height - 1, borderRadius))
                    {
                        g.FillPath(whiteBrush, borderPath);
                        g.FillPath(borderBrush, borderPath);
                    }
                }

                //繪製背景
                RectangleF backgroundRect = new RectangleF();
                backgroundRect.X = borderRect.X + _borderWidth;
                backgroundRect.Y = borderRect.Y + _borderWidth;
                backgroundRect.Width = borderRect.Width - _borderWidth * 2;
                backgroundRect.Height = borderRect.Height - _borderWidth * 2;

                using (Brush backgroundBrush = new SolidBrush(backgroundColor))
                {
                    using (var backgroundPath = DrawHelper.CreateRoundRect(backgroundRect.X, backgroundRect.Y, backgroundRect.Width - 1, backgroundRect.Height - 1, borderRadius))
                    {
                        g.FillPath(whiteBrush, backgroundPath);
                        g.FillPath(backgroundBrush, backgroundPath);
                    }
                }
            }
            else
            {
                //繪製背景
                RectangleF backgroundRect = new RectangleF();
                backgroundRect.X = 0;
                backgroundRect.Y = 0;
                backgroundRect.Width = this.Width;
                backgroundRect.Height = this.Height;

                if (true == this.Focused)
                {
                    backgroundRect.X += _shadowWidth;
                    backgroundRect.Y += _shadowWidth;
                    backgroundRect.Width = this.Width - _shadowWidth * 2;
                    backgroundRect.Height = this.Height - _shadowWidth * 2;
                }

                using (Brush backgroundBrush = new SolidBrush(backgroundColor))
                {
                    using (var backgroundPath = DrawHelper.CreateRoundRect(backgroundRect.X, backgroundRect.Y, backgroundRect.Width - 1, backgroundRect.Height - 1, borderRadius))
                    {
                        g.FillPath(whiteBrush, backgroundPath);
                        g.FillPath(backgroundBrush, backgroundPath);
                    }
                }
            }

            whiteBrush.Dispose();

            //繪製文字
            Size textSize = CalcTextSize();
            
            float textY = this.Height / 2 - textSize.Height / 2;
            float textX = this.Width / 2 - textSize.Width / 2;

            using (Brush textBrush = new SolidBrush(textColor))
            {
                StringFormat sf = StringFormat.GenericTypographic;
                sf.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
                g.DrawString(this.Text, this.Font, textBrush, textX, textY, sf);
            }
        }

        private void SetFont()
        {
            float fontSize = GetFontSize();
            this.Font = new Font("微軟雅黑", fontSize, GraphicsUnit.Pixel);
        }

        private void SetButtonColor()
        {
            ButtonColor buttonStyle = ButtonColor.GetButtonColor(this.ButtonType, this.OutlineStyle);
            this.BackColor = buttonStyle.BackgroundColor;
            this.ForeColor = buttonStyle.TextColor;
            if (this._activeState)
            {
                if (this.OutlineStyle == false)
                {
                    this.BackColor = buttonStyle.ActiveColor;
                }
                else
                {
                    this.ForeColor = buttonStyle.ActiveColor;
                }
            }
        }

        private void SetButtonSize()
        {
            //計算文字尺寸
            Size textSize = CalcTextSize();

            SizeF padding = this.GetPadding();

            int buttonWidth = textSize.Width + Convert.ToInt32(padding.Width) * 2;
            int buttonHeight = textSize.Height + Convert.ToInt32(padding.Height) * 2;
            if (true == this.Focused)
            {
                buttonWidth += _shadowWidth * 2;
                buttonHeight += _shadowWidth * 2;
            }
            this.Width = buttonWidth;
            this.Height = buttonHeight;
        }

        private Size CalcTextSize()
        {
            Graphics g = this.CreateGraphics();
            StringFormat sf = StringFormat.GenericTypographic;
            sf.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
            SizeF textSize_F = g.MeasureString(this.Text, this.Font, PointF.Empty, sf);
            Size textSize = new Size((int)Math.Ceiling(textSize_F.Width), (int)Math.Ceiling(textSize_F.Height));
            return textSize;
        }

        private float GetFontSize()
        {
            float fontSize = _fontSize;
            if (this.ButtonSize == ButtonSize.Large)
            {
                fontSize *= 1.25f;
            }
            else if (this.ButtonSize == ButtonSize.Small)
            {
                fontSize *= 0.875f;
            }
            return fontSize;
        }

        private SizeF GetPadding()
        {
            float paddingX = _fontSize * 0.75f;
            float paddingY = _fontSize * 0.5f;

            if (this.ButtonSize == ButtonSize.Large)
            {
                paddingX = _fontSize * 0.75f;
                paddingY = _fontSize * 0.75f;
            }
            else if (this.ButtonSize == ButtonSize.Small)
            {
                paddingX = _fontSize * 0.35f;
                paddingY = _fontSize * 0.45f;
            }
            return new SizeF(paddingX, paddingY);
        }

        private float GetBorderRadius()
        {
            float borderRadius = _fontSize * 0.25f;
            if (this.ButtonSize == ButtonSize.Large)
            {
                borderRadius = _fontSize * 0.3f;
            }
            else if (this.ButtonSize == ButtonSize.Small)
            {
                borderRadius = _fontSize * 0.2f;
            }
            return borderRadius;
        }
    }

    public enum ButtonSize
    {
        Default,
        Large,
        Small
    }
}

創建示例程序

新建一個 BootstrapButtonExample 示例程序,演示 BootstrapButton 按鈕的使用效果。
設置窗體背景色爲白色,然後添加一些示例按鈕。
在這裏插入圖片描述
在這裏插入圖片描述

源碼下載

https://download.csdn.net/download/blackwoodcliff/11959768

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章