65.9K
CodeProject 正在变化。 阅读更多。
Home

Windows Forms ToggleButton

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.69/5 (10投票s)

2014 年 7 月 8 日

CPOL

3分钟阅读

viewsIcon

71078

downloadIcon

7080

一个具有 Android、Windows 和 iOS 风格的 Windows Forms 切换按钮。

引言

为了自定义 Windows Forms 应用程序的外观和感觉,我们没有很多选择。 尤其是当我们有需要使用控件表示二进制选项时,我们总是使用传统的复选框。 无论我们需要使用控件来表示二进制决策值(例如“是”或“否”),此控件都将更好地帮助满足使用新控件的要求。

在这里,我将描述创建一个自定义控件,以表示具有一些自定义属性和独特 UI 层的二进制决策。

支持什么?

由于自定义是创建此控件的首要关注点,因此我们可以自定义此 ToggleButton 的几乎所有元素。 与控件外观相关的主要属性已在下面列出。

  • 切换样式
  • 切换状态
  • 自定义文本
  • 自定义颜色

这些属性及其对控件的影响将在控件创建后进行描述。

控件绘制

ToggleButton 继承自 System.Windows.FormsControl 类,并重写其 OnPaint 方法以绘制所需的样式。 由于支持不同的样式,因此根据所选样式来处理控件绘制。

protected override void OnPaint(PaintEventArgs e)
        {
            controlBounds = e.ClipRectangle;
            e.Graphics.ResetClip();
            switch (ToggleStyle)
            {
                case ToggleButtonStyle.Android:
                    contentRectangle = e.ClipRectangle;
                    this.BackColor = Color.FromArgb(32, 32, 32);
                    DrawAndroidStyle(e);
                    break;
                case ToggleButtonStyle.Windows:
                    contentRectangle = new Rectangle(e.ClipRectangle.X, e.ClipRectangle.Y, this.Width - 1, this.Height - 1);
                    DrawWindowsStyle(e);
                    break;
                case ToggleButtonStyle.IOS:
                    contentRectangle = new Rectangle(0, 0, this.Width, this.Height);
                    DrawIOSStyle(e);
                    break;
                case ToggleButtonStyle.Custom:
                    contentRectangle = new Rectangle(2, 2, this.Width - 3, this.Height - 3);
                    DrawCustomStyle(e);
                    break;
                case ToggleButtonStyle.Metallic:
                    DrawMetallicStyle(e);
                    break;
            }
            base.OnPaint(e);
        }

对于每种切换样式,将修改控件的客户端矩形,并将更新绘图区域。 更改样式后,现有样式的区域和图形路径将被重置,以便使用新参数进行绘制。

例如,让我们考虑 Android 样式。 控件的区域及其应绘制的点由函数 AndroidPoints() 计算,然后用默认/用户选择的颜色填充。

private void DrawAndroidStyle(PaintEventArgs e)
   {
    ...........
    using (SolidBrush sb = new SolidBrush(clr))
            {
                e.Graphics.FillPolygon(sb, AndroidPoints());
            }
    ...........
   }

     private Point[] AndroidPoints()
        {
            p1 = new Point(padx, contentRectangle.Y);
            if (padx == 0)
                p2 = new Point(padx, contentRectangle.Bottom);
            else
                p2 = new Point(padx - SlidingAngle, contentRectangle.Bottom);

            p4 = new Point(p1.X + (contentRectangle.Width / 2), contentRectangle.Y);

            p3 = new Point(p4.X - SlidingAngle, contentRectangle.Bottom);
            if (p4.X == contentRectangle.Right)
                p3 = new Point(p4.X, contentRectangle.Bottom);

            andPoints[0] = p1;
            andPoints[1] = p2;
            andPoints[2] = p3;
            andPoints[3] = p4;
            return andPoints;

            ///p1 -  p4
            ///|     |
            ///p2 -  p3
        }

与上述类似,对于每种切换样式,都修改了控件的区域和绘制。

鼠标交互

由于此控件的主要用途依赖于用户对切换状态的鼠标交互,因此需要处理根据鼠标手势的绘制,以指示状态已更改/切换。

因此,为了实现这一点,处理了 OnMouseMoveOnMouseDown 事件,以便在按下鼠标按钮并同时移动时更新控件的绘制。

protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (!this.DesignMode)
            {
                isMouseDown = true;
                downpos = e.Location;
            }
            this.Invalidate();
        }

protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (!this.DesignMode)
            {
                isMouseDown = true;
                downpos = e.Location;
            }
            this.Invalidate();
        }

        protected override void OnMouseMove(MouseEventArgs e)
       {
           if (e.Button == MouseButtons.Left && !this.DesignMode)
            {
                sliderPoint = e.Location;
                isMouseMoved = true;
                if (this.ToggleStyle == ToggleButtonStyle.Android)
                {

                    padx = e.X;
                    if (padx <= contentRectangle.Left + SlidingAngle)
                    {
                        padx = contentRectangle.Left;
                        this.ToggleState = ToggleButtonState.OFF;
                    }

                    if (padx >= contentRectangle.Right - (contentRectangle.Width / 2))
                    {
                        padx = contentRectangle.Right - (contentRectangle.Width / 2);
                        this.ToggleState = ToggleButtonState.ON;
                    }
                }
            }
        }

使用代码

要在应用程序中使用此控件,要么从工具箱中拖放,要么按照简单的代码步骤操作即可。

     ToggleButton  toggleButton1 = new ToggleButton();
     this.toggleButton1.ToggleStyle = ToggleButton.ToggleButtonStyle.Android;
     this.Controls.Add(this.toggleButton1);

自定义属性

切换样式

Togglebutton 支持五种样式,即 Android、Windows、iOS、Metallic 和 Custom。 默认情况下,控件使用 Android 样式外观,我们可以通过 ToggleStyle 属性更改样式。

this.toggleButton1.ToggleStyle = ToggleButton.ToggleButtonStyle.Windows;

切换状态

您可以使用属性“ToggleState”更改按钮的切换状态,该属性类似于传统复选框中的 CheckedState

this.toggleButton1.ToggleState = ToggleButton.ToggleButtonState.OFF;

this.toggleButton1.ToggleState = ToggleButton.ToggleButtonState.ON;

自定义文本

我们还可以通过“ActiveText”和“InActiveText”属性修改切换状态的默认文本值。 默认情况下,它使用“ON”和“OFF”作为默认值。

this.toggleButton1.ActiveText = "Yes";

this.toggleButton1.ActiveText = "No";

自定义颜色

与文本值类似,我们也可以更改控件的活动和非活动颜色。

this.toggleButton1.ActiveColor = Color.Red

this.toggleButton1.InActiveColor = Color.Blue

结论

使用在 OnPaint() 函数中使用的上述方法,我们可以为此 ToggleButton 创建和应用新样式。 :)

© . All rights reserved.