/******************************************************************************
* 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);
}
}
}
}
}