/****************************************************************************** * SunnyUI 开源控件库、工具类库、扩展类库、多页面开发框架。 * CopyRight (C) 2012-2022 ShenYongHua(沈永华). * QQ群:56829229 QQ:17612584 EMail:SunnyUI@QQ.Com * * Blog: https://www.cnblogs.com/yhuse * Gitee: https://gitee.com/yhuse/SunnyUI * GitHub: https://github.com/yhuse/SunnyUI * * SunnyUI.dll can be used for free under the GPL-3.0 license. * If you use this code, please keep this note. * 如果您使用此代码,请保留此说明。 ****************************************************************************** * 文件名称: UISwitch.cs * 文件说明: 开关 * 当前版本: V3.0 * 创建日期: 2020-01-01 * * 2020-01-01: V2.2.0 增加文件说明 * 2020-04-25: V2.2.4 更新主题配置类 * 2021-05-06: V3.0.3 更新Active状态改变时触发ValueChanged事件 * 2021-09-14: V3.0.7 增加Disabled颜色 * 2022-01-02: V3.0.9 增加是否只读属性 ******************************************************************************/ using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; namespace Sunny.UI { [DefaultEvent("ValueChanged")] [DefaultProperty("Active")] [ToolboxItem(true)] public sealed class UISwitch : UIControl { /// /// /// /// 对象 /// 开关值 public delegate void OnValueChanged(object sender, bool value); public enum UISwitchShape { Round, Square } public UISwitch() { SetStyleFlags(); Height = 29; Width = 75; ShowText = false; ShowRect = false; foreColor = Color.White; inActiveColor = Color.Gray; fillColor = Color.White; } [DefaultValue(false)] [Description("是否只读"), Category("SunnyUI")] public bool ReadOnly { get; set; } private UISwitchShape switchShape = UISwitchShape.Round; [Description("开关形状"), Category("SunnyUI")] [DefaultValue(UISwitchShape.Round)] public UISwitchShape SwitchShape { get => switchShape; set { switchShape = value; Invalidate(); } } public event OnValueChanged ValueChanged; public event EventHandler ActiveChanged; /// /// 字体颜色 /// [Description("字体颜色"), Category("SunnyUI")] [DefaultValue(typeof(Color), "White")] public override Color ForeColor { get => foreColor; set => SetForeColor(value); } private bool activeValue; [DefaultValue(false)] [Description("是否打开"), Category("SunnyUI")] public bool Active { get => activeValue; set { if (activeValue != value) { activeValue = value; ValueChanged?.Invoke(this, value); ActiveChanged?.Invoke(this, new EventArgs()); Invalidate(); } } } private string activeText = "开"; [DefaultValue("开")] [Description("打开文字"), Category("SunnyUI")] public string ActiveText { get => activeText; set { activeText = value; Invalidate(); } } private string inActiveText = "关"; [DefaultValue("关")] [Description("关闭文字"), Category("SunnyUI")] public string InActiveText { get => inActiveText; set { inActiveText = value; Invalidate(); } } private Color inActiveColor; [DefaultValue(typeof(Color), "Gray")] [Description("关闭颜色"), Category("SunnyUI")] public Color InActiveColor { get => inActiveColor; set { inActiveColor = value; Invalidate(); } } /// /// 填充颜色,当值为背景色或透明色或空值则不填充 /// [Description("填充颜色"), Category("SunnyUI")] [DefaultValue(typeof(Color), "White")] public Color ButtonColor { get => fillColor; set => SetFillColor(value); } /// /// 边框颜色 /// [Description("打开颜色"), Category("SunnyUI")] [DefaultValue(typeof(Color), "80, 160, 255")] public Color ActiveColor { get => rectColor; set => SetRectColor(value); } protected override void OnClick(EventArgs e) { if (!ReadOnly) Active = !Active; base.OnClick(e); } protected override void OnDoubleClick(EventArgs e) { if (!UseDoubleClick) { Active = !Active; base.OnClick(e); } else { base.OnDoubleClick(e); } } public override void SetStyleColor(UIBaseStyle uiColor) { base.SetStyleColor(uiColor); rectColor = uiColor.SwitchActiveColor; fillColor = uiColor.SwitchFillColor; inActiveColor = uiColor.SwitchInActiveColor; rectDisableColor = uiColor.RectDisableColor; Invalidate(); } [Description("不可用颜色"), Category("SunnyUI")] [DefaultValue(typeof(Color), "173, 178, 181")] public Color DisabledColor { get => rectDisableColor; set => SetRectDisableColor(value); } protected override void OnEnabledChanged(EventArgs e) { base.OnEnabledChanged(e); Invalidate(); } protected override void OnPaintFill(Graphics g, GraphicsPath path) { Color color = Active ? ActiveColor : InActiveColor; if (!Enabled) color = rectDisableColor; if (SwitchShape == UISwitchShape.Round) { Rectangle rect = new Rectangle(0, 0, Width - 1, Height - 1); g.FillRoundRectangle(color, rect, rect.Height); int width = Width - 3 - 1 - 3 - (rect.Height - 6); if (!Active) { g.FillEllipse(fillColor.IsValid() ? fillColor : Color.White, 3, 3, rect.Height - 6, rect.Height - 6); SizeF sf = g.MeasureString(InActiveText, Font); g.DrawString(InActiveText, Font, fillColor.IsValid() ? fillColor : Color.White, 3 + rect.Height - 6 + (width - sf.Width) / 2, 3 + (rect.Height - 6 - sf.Height) / 2); } else { g.FillEllipse(fillColor.IsValid() ? fillColor : Color.White, Width - 3 - 1 - (rect.Height - 6), 3, rect.Height - 6, rect.Height - 6); SizeF sf = g.MeasureString(ActiveText, Font); g.DrawString(ActiveText, Font, fillColor.IsValid() ? fillColor : Color.White, 3 + (width - sf.Width) / 2, 3 + (rect.Height - 6 - sf.Height) / 2); } } if (SwitchShape == UISwitchShape.Square) { Rectangle rect = new Rectangle(0, 0, Width - 1, Height - 1); g.FillRoundRectangle(color, rect, Radius); int width = Width - 3 - 1 - 3 - (rect.Height - 6); if (!Active) { g.FillRoundRectangle(fillColor.IsValid() ? fillColor : Color.White, 3, 3, rect.Height - 6, rect.Height - 6, Radius); SizeF sf = g.MeasureString(InActiveText, Font); g.DrawString(InActiveText, Font, fillColor.IsValid() ? fillColor : Color.White, 3 + rect.Height - 6 + (width - sf.Width) / 2, 3 + (rect.Height - 6 - sf.Height) / 2); } else { g.FillRoundRectangle(fillColor.IsValid() ? fillColor : Color.White, Width - 3 - 1 - (rect.Height - 6), 3, rect.Height - 6, rect.Height - 6, Radius); SizeF sf = g.MeasureString(ActiveText, Font); g.DrawString(ActiveText, Font, fillColor.IsValid() ? fillColor : Color.White, 3 + (width - sf.Width) / 2, 3 + (rect.Height - 6 - sf.Height) / 2); } } } } }