C#自定义控件(开关式选择按钮)

目录

前言

一、创建一个自定义控件项目

二、关键技术

1.添加控件属性

2.控件初始化

3.开关按钮的类型

4.重绘事件

5.效果展示

 三、总结


前言

C#Form窗体中自带的选择按钮控件外观单一,已不适合现在的窗体设计,所以我们需要自定义制作一个选择按钮控件,这个选择按钮有三种形态分别为椭圆,矩形,线性,如图所示:

  


一、创建一个自定义控件项目

在VS中新建项目,选择Windows窗体控件库,并创建,如下图所示:

 设计窗口如下图所示:

二、关键技术

1.添加控件属性

添加控件控件属性,“选择时改变事件”,"是否选中","当选中true时显示的文本","当选中flase时显示的文本","选择为true时的颜色","选择为flase时的颜色","选择为true时的文本颜色","选择为flase时的文本颜色","开关的外框显示类型","显示文本的字体",代码如下:

[Description("选择时改变事件"), Category("自定义")]
        public event EventHandler CheckedChanged;

        private bool myChecked;
        [Description("是否选中"), Category("自定义")]
        public bool Checked
        {
            get { return myChecked; }
            set
            {
                myChecked = value;
                Refresh();
                if (CheckedChanged != null)
                {
                    CheckedChanged(this, null);
                }
            }
        }

        private string myTrueText;
        [Description("当选中true时显示的文本"), Category("自定义")]
        public string TrueText
        {
            get { return myTrueText; }
            set
            {
                myTrueText = value;
                Refresh();
            }
        }

        private string myFlaseText;
        [Description("当选中flase时显示的文本"), Category("自定义")]
        public string FlaseText
        {
            get { return myFlaseText; }
            set
            {
                myFlaseText = value;
                Refresh();
            }
        }

        [Description("选择为true时的颜色"), Category("自定义")]
        private Color myCheckedTrueColor = Color.Green;
        public Color CheckedTrueColor
        {
            get { return myCheckedTrueColor; }
            set
            {
                myCheckedTrueColor = value;
                Refresh();
            }
        }

        [Description("选择为flase时的颜色"), Category("自定义")]
        private Color myCheckedFlaseColor = Color.Gray;
        public Color CheckedFlaseColor
        {
            get { return myCheckedFlaseColor; }
            set
            {
                myCheckedFlaseColor = value;
                Refresh();
            }
        }


        [Description("选择为true时的文本颜色"), Category("自定义")]
        private Color myCheckedTrueTextColor = Color.Blue;
        public Color CheckedTrueTextColor
        {
            get { return myCheckedTrueTextColor; }
            set
            {
                myCheckedTrueTextColor = value;
                Refresh();
            }
        }

        [Description("选择为flase时的文本颜色"), Category("自定义")]
        private Color myCheckedFlaseTextColor = Color.Black;
        public Color CheckedFlaseTextColor
        {
            get { return myCheckedFlaseTextColor; }
            set
            {
                myCheckedFlaseTextColor = value;
                Refresh();
            }
        }

        private SwitchType mySwitchType = SwitchType.Ellipse;
        [Description("开关的外框显示类型"), Category("自定义")]
        public SwitchType SwitchType
        {
            get { return mySwitchType; }
            set
            {
                mySwitchType = value;
                Refresh();
            }
        }

        [Description("显示文本的字体"), Category("自定义")]
        public override Font Font
        {
            get
            {
                return base.Font;
            }
            set
            {
                base.Font = value;
                Refresh();
            }
        }

2.控件初始化

需要添加鼠标按下事件,代码如下:

        public UserControl1()
        {
            InitializeComponent();

            this.MouseDown += Switch_MouseDown;
        }

        void Switch_MouseDown(object sender, MouseEventArgs e)
        {
            Checked = !Checked;
        }

3.开关按钮的类型

需要写一个开关按钮显示类型的枚举,代码如下:

    /// <summary>
    /// Enum SwitchType
    /// </summary>
    public enum SwitchType
    {
        /// <summary>
        /// 椭圆
        /// </summary>
        Ellipse,
        /// <summary>
        /// 四边形
        /// </summary>
        Quadrilateral,
        /// <summary>
        /// 横线
        /// </summary>
        Line
    }

4.重绘事件

需要重写绘制事件,代码如下:

        /// <summary>
        /// 重写绘制事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            var g = e.Graphics;
            g.SmoothingMode = SmoothingMode.AntiAlias;  //使绘图质量最高
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = CompositingQuality.HighQuality;
            Color color;
            if (myChecked)
            {
                color = myCheckedTrueColor;
            }
            else
            {
                color = myCheckedFlaseColor;
            }
            if (mySwitchType == SwitchType.Ellipse)
            {
                GraphicsPath path = new GraphicsPath();
                path.AddArc(new Rectangle(this.Width - this.Height - 1, 1, this.Height - 2, this.Height - 2), -90, 180);
                path.AddArc(new Rectangle(1, 1, this.Height - 2, this.Height - 2), 90, 180);
                g.FillPath(new SolidBrush(color), path);
                if (myChecked)
                {
                    g.FillEllipse(Brushes.White, new Rectangle(this.Width - this.Height - 1 + 2, 1 + 2, this.Height - 2 - 4, this.Height - 2 - 4));
                    if (string.IsNullOrEmpty(myTrueText))
                    {
                        g.DrawEllipse(new Pen(Color.White, 2), new Rectangle((this.Height - 2 - 4) / 2 - ((this.Height - 2 - 4) / 2) / 2, (this.Height - 2 - (this.Height - 2 - 4) / 2) / 2 + 1, (this.Height - 2 - 4) / 2, (this.Height - 2 - 4) / 2));
                    }
                    else
                    {
                        System.Drawing.SizeF sizeF = g.MeasureString(myTrueText, Font);
                        int intTextY = (this.Height - (int)sizeF.Height) / 2 + 2;
                        g.DrawString(myTrueText, Font, new SolidBrush(myCheckedTrueTextColor), new Point((this.Height - 2 - 4) / 2, intTextY));
                    }
                }
                else
                {
                    g.FillEllipse(Brushes.White, new Rectangle(1 + 2, 1 + 2, this.Height - 2 - 4, this.Height - 2 - 4));
                    if (string.IsNullOrEmpty(myFlaseText))
                    {
                        g.DrawEllipse(new Pen(Color.White, 2), new Rectangle(this.Width - 2 - (this.Height - 2 - 4) / 2 - ((this.Height - 2 - 4) / 2) / 2, (this.Height - 2 - (this.Height - 2 - 4) / 2) / 2 + 1, (this.Height - 2 - 4) / 2, (this.Height - 2 - 4) / 2));
                    }
                    else
                    {
                        System.Drawing.SizeF sizeF = g.MeasureString(myFlaseText, Font);
                        int intTextY = (this.Height - (int)sizeF.Height) / 2 + 2;
                        g.DrawString(myFlaseText, Font, new SolidBrush(myCheckedFlaseTextColor), new Point(this.Width - 2 - (this.Height - 2 - 4) / 2 - ((this.Height - 2 - 4) / 2) / 2 - (int)sizeF.Width / 2, intTextY));
                    }
                }
            }
            else if (mySwitchType == SwitchType.Quadrilateral)
            {
                GraphicsPath path = new GraphicsPath();
                int intRadius = 5;
                path.AddArc(0, 0, intRadius, intRadius, 180f, 90f);
                path.AddArc(this.Width - intRadius - 1, 0, intRadius, intRadius, 270f, 90f);
                path.AddArc(this.Width - intRadius - 1, this.Height - intRadius - 1, intRadius, intRadius, 0f, 90f);
                path.AddArc(0, this.Height - intRadius - 1, intRadius, intRadius, 90f, 90f);

                g.FillPath(new SolidBrush(color), path);


                if (myChecked)
                {
                    GraphicsPath path2 = new GraphicsPath();
                    path2.AddArc(this.Width - this.Height - 1 + 2, 1 + 2, intRadius, intRadius, 180f, 90f);
                    path2.AddArc(this.Width - 1 - 2 - intRadius, 1 + 2, intRadius, intRadius, 270f, 90f);
                    path2.AddArc(this.Width - 1 - 2 - intRadius, this.Height - 2 - intRadius - 1, intRadius, intRadius, 0f, 90f);
                    path2.AddArc(this.Width - this.Height - 1 + 2, this.Height - 2 - intRadius - 1, intRadius, intRadius, 90f, 90f);
                    g.FillPath(Brushes.White, path2);

                    if (string.IsNullOrEmpty(myTrueText))
                    {
                        g.DrawEllipse(new Pen(Color.White, 2), new Rectangle((this.Height - 2 - 4) / 2 - ((this.Height - 2 - 4) / 2) / 2, (this.Height - 2 - (this.Height - 2 - 4) / 2) / 2 + 1, (this.Height - 2 - 4) / 2, (this.Height - 2 - 4) / 2));
                    }
                    else
                    {
                        System.Drawing.SizeF sizeF = g.MeasureString(myTrueText, Font);
                        int intTextY = (this.Height - (int)sizeF.Height) / 2 + 2;
                        g.DrawString(myTrueText, Font, new SolidBrush(myCheckedTrueTextColor), new Point((this.Height - 2 - 4) / 2, intTextY));
                    }
                }
                else 
                {
                    GraphicsPath path2 = new GraphicsPath();
                    path2.AddArc(1 + 2, 1 + 2, intRadius, intRadius, 180f, 90f);
                    path2.AddArc(this.Height - 2 - intRadius, 1 + 2, intRadius, intRadius, 270f, 90f);
                    path2.AddArc(this.Height - 2 - intRadius, this.Height - 2 - intRadius - 1, intRadius, intRadius, 0f, 90f);
                    path2.AddArc(1 + 2, this.Height - 2 - intRadius - 1, intRadius, intRadius, 90f, 90f);
                    g.FillPath(Brushes.White, path2);

                    g.FillEllipse(Brushes.White, new Rectangle(1 + 2, 1 + 2, this.Height - 2 - 4, this.Height - 2 - 4));
                    if (string.IsNullOrEmpty(myFlaseText))
                    {
                        g.DrawEllipse(new Pen(Color.White, 2), new Rectangle(this.Width - 2 - (this.Height - 2 - 4) / 2 - ((this.Height - 2 - 4) / 2) / 2, (this.Height - 2 - (this.Height - 2 - 4) / 2) / 2 + 1, (this.Height - 2 - 4) / 2, (this.Height - 2 - 4) / 2));
                    }
                    else
                    {
                        System.Drawing.SizeF sizeF = g.MeasureString(myFlaseText, Font);
                        int intTextY = (this.Height - (int)sizeF.Height) / 2 + 2;
                        g.DrawString(myFlaseText, Font, new SolidBrush(myCheckedFlaseTextColor), new Point(this.Width - 2 - (this.Height - 2 - 4) / 2 - ((this.Height - 2 - 4) / 2) / 2 - (int)sizeF.Width / 2, intTextY));
                    }
                }
            }
            else if (mySwitchType == SwitchType.Line)
            {
           
                int intLineHeight = (this.Height - 2 - 4) / 2;

                GraphicsPath path = new GraphicsPath();
                path.AddArc(new Rectangle(this.Width - this.Height / 2 - intLineHeight - 1, (this.Height - intLineHeight) / 2, intLineHeight, intLineHeight), -90, 180);//右圆弧
                path.AddArc(new Rectangle(this.Height / 2, (this.Height - intLineHeight) / 2, intLineHeight, intLineHeight), 90, 180);
                g.FillPath(new SolidBrush(color), path);//左圆弧

                if (myChecked)
                {
                    g.FillEllipse(new SolidBrush(color), new Rectangle(this.Width - this.Height - 1 + 2, 1 + 2, this.Height - 2 - 4, this.Height - 2 - 4));//外圆
                    g.FillEllipse(Brushes.White, new Rectangle(this.Width - 2 - (this.Height - 2 - 4) / 2 - ((this.Height - 2 - 4) / 2) / 2 - 4, (this.Height - 2 - (this.Height - 2 - 4) / 2) / 2 + 1, (this.Height - 2 - 4) / 2, (this.Height - 2 - 4) / 2));//内圆
                }
                else
                {
                    g.FillEllipse(new SolidBrush(color), new Rectangle(1 + 2, 1 + 2, this.Height - 2 - 4, this.Height - 2 - 4));
                    g.FillEllipse(Brushes.White, new Rectangle((this.Height - 2 - 4) / 2 - ((this.Height - 2 - 4) / 2) / 2 + 4, (this.Height - 2 - (this.Height - 2 - 4) / 2) / 2 + 1, (this.Height - 2 - 4) / 2, (this.Height - 2 - 4) / 2));
                }
            }
        }

5.效果展示

实际效果展示如下:

 三、

这样我就用C#做了一个开关式的选择按钮,拥有三种样式,可以各区域的颜色,可以添加要显示的文字,可以更改文字的字体,颜色等。

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值