WinForms切换开关控制 [英] WinForms Toggle Switch Control

查看:81
本文介绍了WinForms切换开关控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人知道winforms有一个好的,免费的(最好是)拨动开关式控制器? (例如iOS中的开关控制)。

Does anyone here know of a good, free (preferably) toggle switch style control for winforms? (e.g. like the switch control in iOS).

推荐答案

我已经为我的地铁ui外观创建了一个自定义控件,来自windows 8 pc设置的切换控件/>


创建一个usercontrol并添加1个标签



i have created a custom control for my metro ui look, the toggle control from the windows 8 pc settings

create a usercontrol and add 1 label

public partial class ToggleSwitch : UserControl
   {
       public Color ColorToggleOn { get; set; }
       public bool istoggleStatus { get; set; }

       public ToggleSwitch()
       {
           InitializeComponent();
       }

       private void ToggleSwitch_Load(object sender, EventArgs e)
       {
           if (istoggleStatus) {
               isON();
           }
           else {
               isOFF();
           }
       }

       protected override void OnMouseDown(MouseEventArgs e)
       {
           base.OnMouseDown(e);
           SetToggleControlStatus(istoggleStatus);
       }

       private void SetToggleControlStatus(bool isToggle)
       {
           if (isToggle) {
               isToggle = false;
               this.BackColor = Color.Silver;
               this.label1.Dock = DockStyle.Left;
           }
           else {
               isToggle = true;
               this.BackColor = this.ColorToggleOn;
               this.label1.Dock = DockStyle.Right;
           }
           istoggleStatus = isToggle;
       }

       private void isOFF()
       {
           this.BackColor = Color.Silver;
           this.label1.Dock = DockStyle.Left;
       }

       private void isON()
       {
           this.BackColor = ColorToggleOn;
           this.label1.Dock = DockStyle.Right;
       }

       protected override void OnPaint(PaintEventArgs e)
       {
            if (istoggleStatus) {
               isON();
           }
           else {
               isOFF();
           }
           base.OnPaint(e);
        }


   }







i know这需要更多的清理,但它的工作原理:D这就是它的样子



http://www.computerperformance.co.uk/images/win8/pc_settings_sync.jpg [ ^ ]


这是我的快速贡献。这是TheCardinal代码的更完整版本。这完全在代码中,因此您可以将其添加到项目中,它将显示在设计器的工具箱中(没有命名空间 - 它将位于顶部)。设置默认事件,以便您可以双击该控件,它将为您填写CheckChanged事件处理程序。颜色,边框和ON / OFF标签可自定义。它公开了一个名为Checked的属性,就像一个复选框控件。





Here's my quick contribution. This is a far more complete version of TheCardinal's code. This is all in code so you can add it to your project and it will show up in the designer's toolbox (no namespace - it'll be at the top). The default event is set so you can double-click the control and it will fill out a CheckChanged event handler for you. Colors, borders, and the ON/OFF label are customizable. It exposes a property called Checked just like a checkbox control.


using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;


//data for a change event. the current implementation
//guarantees OldValue and NewValue are always different,
//but the change event is built this way so you could change
//internal behavior if you wanted.

public class CheckChangedEventArgs : EventArgs
{
    public bool OldValue { get; set; }
    public bool NewValue { get; set; }

    public CheckChangedEventArgs(bool old_value, bool new_value)
    {
        NewValue = new_value;
        OldValue = old_value;
    }
}


//event handler
public delegate void CheckChangedEventHandler(object sender, CheckChangedEventArgs e);



[DefaultEvent("CheckChanged")]
public class ToggleSwitch : UserControl
{
    //internal variables and their defaults.
    private Color _ColorToggleOn = Color.Green;
    private Color _ColorToggleOff = Color.Red;
    private Color _ColorButtonOn = Color.Honeydew;
    private Color _ColorButtonOff = Color.Snow;
    private string _TextON = "ON";
    private string _TextOFF = "OFF";
    private bool _checked = false;
    private bool _BorderExtraThin = true;
    private bool _BorderForButton = true;
    private int _ButtonWidthPercentage = 30;

    //public properties that will show in the designer
    public Color ColorToggleOn { get { return _ColorToggleOn; } set { _ColorToggleOn = value;  UpdateColors(); } }
    public Color ColorToggleOff { get { return _ColorToggleOff; } set { _ColorToggleOff = value; UpdateColors(); } }    
    public Color ColorButtonOn { get { return _ColorButtonOn; } set { _ColorButtonOn = value; UpdateColors(); } }
    public Color ColorButtonOff { get { return _ColorButtonOff; } set { _ColorButtonOff = value; UpdateColors(); } }
    public string TextON { get { return _TextON; } set { _TextON = value; UpdateColors(); } }
    public string TextOFF { get { return _TextOFF; } set { _TextOFF = value; UpdateColors(); } }
    public bool BorderExtraThin { get { return _BorderExtraThin; } set { _BorderExtraThin = value; UpdateBorders(); UpdateColors(); Refresh(); } }
    public bool BorderForButton { get { return _BorderForButton; } set { _BorderForButton = value; UpdateBorders(); UpdateColors(); Refresh(); } }
    public int ButtonWidthPercentage { get { return _ButtonWidthPercentage; } set { _ButtonWidthPercentage = value; UpdateBorders(); UpdateColors(); Refresh(); } }

    public bool Checked
    {
        get { return _checked; }

        set
        {
            //This is set up so change events don't even occur unless the value is really changing.
            //This behavior could be modified if for some reason you want a change event without
            //  the value actually changing; which explains the CheckChangedEventArgs having a
            //  old value and a new value, even though the current implementation guarantees
            //  they are actually different.

            if (Checked == value)
                return;

            _checked = value;
            UpdateColors();

            CheckChanged(this, new CheckChangedEventArgs(!Checked, Checked));
        }
    }
    
    //we use a floating label control as the "button" and optional text.
    private Label label1;

    //CheckChanged is the default event for this control, and the only custom one we need.
    [Category("Action")]
    [Description("Fires when the switch is toggled, just like a checkbox")]
    public event CheckChangedEventHandler CheckChanged;

    void _CheckChangedDoNothing(object sender, CheckChangedEventArgs e)
    {
    }

    public ToggleSwitch()
    {
        CheckChanged = new CheckChangedEventHandler(_CheckChangedDoNothing);

        label1 = new Label();
        label1.ForeColor = this.ForeColor;
        label1.Visible = true;
        label1.TextAlign = ContentAlignment.MiddleCenter;
        label1.BorderStyle = BorderStyle.FixedSingle;
        label1.MouseDown += new MouseEventHandler(label1_MouseDown);
            
        this.Controls.Add(label1);

        UpdateColors();
    }

    void label1_MouseDown(object sender, EventArgs e)
    {
        Clicked();
    }

    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        Clicked();
    }

    private void Clicked()
    {
        Checked = !Checked;
    }

    private void UpdateBorders()
    {
        if (BorderExtraThin)
        {
            BorderStyle = System.Windows.Forms.BorderStyle.None;
        }

        if (BorderForButton)
        {
            label1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
        }
    }

    private void UpdateColors()
    {
        if (Checked)
        {
            this.BackColor = ColorToggleOn;
            this.label1.Dock = DockStyle.Right;
            label1.Width = (ClientRectangle.Width * ButtonWidthPercentage) / 100;
            this.label1.Text = TextON;
            this.label1.BackColor = ColorButtonOn;

            //not sure why but it seems to need a 1-px offset to look correct
            this.label1.Padding = new Padding(1, 0, 0, 0);


            this.Refresh();
        }
        else
        {
            this.BackColor = ColorToggleOff;
            this.label1.Dock = DockStyle.Left;
            label1.Width = (ClientRectangle.Width * ButtonWidthPercentage) / 100;
            this.label1.Text = TextOFF;
            this.label1.BackColor = ColorButtonOff;

            this.Refresh();
        }
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        int BORDER_SIZE = 1;

        if (BorderExtraThin)
        {
            ControlPaint.DrawBorder(e.Graphics, ClientRectangle,
                Color.Black, BORDER_SIZE, ButtonBorderStyle.Inset,
                Color.Black, BORDER_SIZE, ButtonBorderStyle.Inset,
                Color.Black, BORDER_SIZE, ButtonBorderStyle.Inset,
                Color.Black, BORDER_SIZE, ButtonBorderStyle.Inset);
        }
    }
}


我最终使用带有开关状态图像的自定义图片框。这是一个快速而肮脏的黑客,但它的工作原理。我最终可能会修改它以添加其他图像。
I simply ended up using a customized picture box with on and off switch state images. It's a quick and dirty hack, but it works. I may eventually end up modifying it to add other images.


这篇关于WinForms切换开关控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆