SunnyUI/SunnyUI/Controls/UIControl.cs

994 lines
29 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/******************************************************************************
* SunnyUI 开源控件库、工具类库、扩展类库、多页面开发框架。
* CopyRight (C) 2012-2022 ShenYongHua(沈永华).
* QQ群56829229 QQ17612584 EMailSunnyUI@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.
* 如果您使用此代码,请保留此说明。
******************************************************************************
* 文件名称: UIControl.cs
* 文件说明: 控件基类
* 当前版本: V3.1
* 创建日期: 2020-01-01
*
* 2020-01-01: V2.2.0 增加文件说明
* 2020-04-25: V2.2.4 更新主题配置类
* 2021-12-13: V3.0.9 边框线宽可设置1或者2
* 2022-01-10: V3.1.0 调整边框和圆角的绘制
* 2022-02-16: V3.1.1 基类增加只读颜色设置
* 2022-03-19: V3.1.1 重构主题配色
******************************************************************************/
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Sunny.UI
{
/// <summary>
/// 控件基类
/// </summary>
[ToolboxItem(false)]
public class UIControl : Control, IStyleInterface, IZoomScale
{
/// <summary>
/// 构造函数
/// </summary>
public UIControl()
{
Version = UIGlobal.Version;
base.Font = UIFontColor.Font();
Size = new Size(100, 35);
base.MinimumSize = new Size(1, 1);
}
public bool Disabled => !Enabled;
/// <summary>
/// 禁止控件跟随窗体缩放
/// </summary>
[DefaultValue(false), Category("SunnyUI"), Description("禁止控件跟随窗体缩放")]
public bool ZoomScaleDisabled { get; set; }
/// <summary>
/// 控件缩放前在其容器里的位置
/// </summary>
[Browsable(false)]
public Rectangle ZoomScaleRect { get; set; }
/// <summary>
/// 设置控件缩放比例
/// </summary>
/// <param name="scale">缩放比例</param>
public virtual void SetZoomScale(float scale)
{
radius = UIZoomScale.Calc(baseRadius, scale);
}
protected bool selected;
[Browsable(false), DefaultValue(false)]
public bool IsScaled { get; set; }
public virtual void SetDPIScale()
{
if (!IsScaled)
{
this.SetDPIScaleFont();
IsScaled = true;
}
}
protected void SetStyleFlags(bool supportTransparent = true, bool selectable = true, bool resizeRedraw = false)
{
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
if (supportTransparent) SetStyle(ControlStyles.SupportsTransparentBackColor, true);
if (selectable) SetStyle(ControlStyles.Selectable, true);
if (resizeRedraw) SetStyle(ControlStyles.ResizeRedraw, true);
base.DoubleBuffered = true;
UpdateStyles();
}
/// <summary>
/// 重载控件尺寸变更
/// </summary>
/// <param name="e">参数</param>
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
Invalidate();
}
/// <summary>
/// Tag字符串
/// </summary>
[DefaultValue(null)]
[Description("获取或设置包含有关控件的数据的对象字符串"), Category("SunnyUI")]
public string TagString
{
get; set;
}
/// <summary>
/// 是否在设计期
/// </summary>
protected bool IsDesignMode
{
get
{
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
{
return true;
}
if (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv")
{
return true;
}
return false;
}
}
private ToolStripStatusLabelBorderSides _rectSides = ToolStripStatusLabelBorderSides.All;
/// <summary>
/// 边框显示位置
/// </summary>
[DefaultValue(ToolStripStatusLabelBorderSides.All), Description("边框显示位置"), Category("SunnyUI")]
public ToolStripStatusLabelBorderSides RectSides
{
get => _rectSides;
set
{
_rectSides = value;
OnRectSidesChange();
Invalidate();
}
}
protected virtual void OnRadiusSidesChange()
{
}
protected virtual void OnRectSidesChange()
{
}
private UICornerRadiusSides _radiusSides = UICornerRadiusSides.All;
/// <summary>
/// 圆角显示位置
/// </summary>
[DefaultValue(UICornerRadiusSides.All), Description("圆角显示位置"), Category("SunnyUI")]
public UICornerRadiusSides RadiusSides
{
get => _radiusSides;
set
{
_radiusSides = value;
OnRadiusSidesChange();
Invalidate();
}
}
private int radius = 5;
private int baseRadius = 5;
/// <summary>
/// 圆角角度
/// </summary>
[Description("圆角角度"), Category("SunnyUI")]
[DefaultValue(5)]
public int Radius
{
get => radius;
set
{
if (radius != value)
{
baseRadius = radius = Math.Max(0, value);
Invalidate();
}
}
}
private bool showText = true;
/// <summary>
/// 是否显示文字
/// </summary>
[Description("是否显示文字"), Category("SunnyUI")]
[DefaultValue(true)]
protected bool ShowText
{
get => showText;
set
{
if (showText != value)
{
showText = value;
Invalidate();
}
}
}
private bool showRect = true;
/// <summary>
/// 是否显示边框
/// </summary>
protected bool ShowRect
{
get => showRect;
set
{
if (showRect != value)
{
showRect = value;
Invalidate();
}
}
}
private bool showFill = true;
/// <summary>
/// 是否显示填充
/// </summary>
protected bool ShowFill
{
get => showFill;
set
{
if (showFill != value)
{
showFill = value;
Invalidate();
}
}
}
/// <summary>
/// 版本
/// </summary>
public string Version
{
get;
}
protected UIStyle _style = UIStyle.Blue;
/// <summary>
/// 主题样式
/// </summary>
[DefaultValue(UIStyle.Blue), Description("主题样式"), Category("SunnyUI")]
public UIStyle Style
{
get => _style;
set => SetStyle(value);
}
protected void SetStyleCustom(bool needRefresh = true)
{
_style = UIStyle.Custom;
if (needRefresh) Invalidate();
}
/// <summary>
/// 设置主题样式
/// </summary>
/// <param name="style">主题样式</param>
public void SetStyle(UIStyle style)
{
if (!style.IsCustom())
{
SetStyleColor(style.Colors());
Invalidate();
}
_style = style;
}
/// <summary>
/// 自定义主题风格
/// </summary>
[DefaultValue(false)]
[Description("获取或设置可以自定义主题风格"), Category("SunnyUI")]
public bool StyleCustomMode { get; set; }
/// <summary>
/// 设置主题样式颜色
/// </summary>
/// <param name="uiColor"></param>
public virtual void SetStyleColor(UIBaseStyle uiColor)
{
fillColor = uiColor.ButtonFillColor;
fillColor2 = uiColor.ButtonFillColor2;
foreColor = uiColor.ButtonForeColor;
rectColor = uiColor.ButtonRectColor;
fillDisableColor = uiColor.FillDisableColor;
foreDisableColor = uiColor.ForeDisableColor;
rectDisableColor = uiColor.RectDisableColor;
fillReadOnlyColor = uiColor.FillDisableColor;
rectReadOnlyColor = uiColor.RectDisableColor;
foreReadOnlyColor = uiColor.ForeDisableColor;
fillHoverColor = fillColor;
foreHoverColor = foreColor;
rectHoverColor = rectColor;
fillPressColor = fillColor;
forePressColor = foreColor;
rectPressColor = rectColor;
fillSelectedColor = fillColor;
foreSelectedColor = foreColor;
rectSelectedColor = rectColor;
}
/// <summary>
/// 是否鼠标移上
/// </summary>
[Browsable(false)]
public bool IsHover;
/// <summary>
/// 是否鼠标按下
/// </summary>
[Browsable(false)]
public bool IsPress;
private ContentAlignment textAlign = ContentAlignment.MiddleCenter;
/// <summary>
/// 文字对齐方向
/// </summary>
[Description("文字对齐方向"), Category("SunnyUI")]
[DefaultValue(ContentAlignment.MiddleCenter)]
public ContentAlignment TextAlign
{
get => textAlign;
set
{
if (textAlign != value)
{
textAlign = value;
Invalidate();
}
}
}
private bool useDoubleClick;
[Description("是否启用双击事件"), Category("SunnyUI")]
[DefaultValue(false)]
public bool UseDoubleClick
{
get
{
return useDoubleClick;
}
set
{
if (useDoubleClick != value)
{
useDoubleClick = value;
SetStyle(ControlStyles.StandardDoubleClick, useDoubleClick);
//Invalidate();
}
}
}
protected bool lightStyle;
/// <summary>
/// 重载绘图
/// </summary>
/// <param name="e">绘图参数</param>
protected override void OnPaint(PaintEventArgs e)
{
if (!Visible || Width <= 0 || Height <= 0) return;
if (IsDisposed) return;
Rectangle rect = new Rectangle(0, 0, Width - 1, Height - 1);
GraphicsPath path = rect.CreateRoundedRectanglePath(radius, RadiusSides, RectSize);
//填充背景色
if (ShowFill && fillColor.IsValid())
{
OnPaintFill(e.Graphics, path);
}
//填充边框色
if (ShowRect)
{
OnPaintRect(e.Graphics, path);
}
//填充文字
if (ShowText)
{
OnPaintFore(e.Graphics, path);
}
path.Dispose();
base.OnPaint(e);
}
/// <summary>
/// 获取边框颜色
/// </summary>
/// <returns>颜色</returns>
protected Color GetRectColor()
{
//边框
Color color = rectColor;
if (IsHover)
color = rectHoverColor;
if (IsPress)
color = rectPressColor;
if (selected)
color = rectSelectedColor;
if (ShowFocusColor && Focused)
color = rectHoverColor;
if (isReadOnly)
color = rectReadOnlyColor;
return Enabled ? color : rectDisableColor;
}
[Description("是否显示激活状态颜色"), Category("SunnyUI")]
[DefaultValue(false)]
public bool ShowFocusColor
{
get;
set;
}
protected bool isReadOnly;
/// <summary>
/// 获取字体颜色
/// </summary>
/// <returns>颜色</returns>
protected Color GetForeColor()
{
//文字
Color color = lightStyle ? _style.Colors().ButtonForeLightColor : foreColor;
if (IsHover)
color = foreHoverColor;
if (IsPress)
color = forePressColor;
if (selected)
color = foreSelectedColor;
if (ShowFocusColor && Focused)
color = foreHoverColor;
if (isReadOnly)
color = foreReadOnlyColor;
return Enabled ? color : foreDisableColor;
}
/// <summary>
/// 获取填充颜色
/// </summary>
/// <returns>颜色</returns>
protected Color GetFillColor()
{
//填充
Color color = lightStyle ? _style.Colors().ButtonFillLightColor : fillColor;
if (IsHover)
color = fillHoverColor;
if (IsPress)
color = fillPressColor;
if (selected)
color = fillSelectedColor;
if (ShowFocusColor && Focused)
color = fillHoverColor;
if (isReadOnly)
color = fillReadOnlyColor;
return Enabled ? color : fillDisableColor;
}
/// <summary>
/// 绘制填充
/// </summary>
/// <param name="g">GDI绘图图面</param>
/// <param name="path">路径</param>
protected virtual void OnPaintFill(Graphics g, GraphicsPath path)
{
Color color = GetFillColor();
g.FillPath(color, path);
}
private int rectSize = 1;
/// <summary>
/// 边框颜色
/// </summary>
[Description("边框宽度"), Category("SunnyUI")]
[DefaultValue(1)]
public int RectSize
{
get => rectSize;
set
{
int v = value;
if (v > 2) v = 2;
if (v < 1) v = 1;
if (rectSize != v)
{
rectSize = v;
Invalidate();
}
}
}
private void PaintRectDisableSides(Graphics g)
{
//IsRadius为False时显示左侧边线
bool ShowRectLeft = RectSides.GetValue(ToolStripStatusLabelBorderSides.Left);
//IsRadius为False时显示上侧边线
bool ShowRectTop = RectSides.GetValue(ToolStripStatusLabelBorderSides.Top);
//IsRadius为False时显示右侧边线
bool ShowRectRight = RectSides.GetValue(ToolStripStatusLabelBorderSides.Right);
//IsRadius为False时显示下侧边线
bool ShowRectBottom = RectSides.GetValue(ToolStripStatusLabelBorderSides.Bottom);
//IsRadius为True时显示左上圆角
bool RadiusLeftTop = RadiusSides.GetValue(UICornerRadiusSides.LeftTop);
//IsRadius为True时显示左下圆角
bool RadiusLeftBottom = RadiusSides.GetValue(UICornerRadiusSides.LeftBottom);
//IsRadius为True时显示右上圆角
bool RadiusRightTop = RadiusSides.GetValue(UICornerRadiusSides.RightTop);
//IsRadius为True时显示右下圆角
bool RadiusRightBottom = RadiusSides.GetValue(UICornerRadiusSides.RightBottom);
var ShowRadius = RadiusSides > 0 && Radius > 0;//肯定少有一个角显示圆角
if (!ShowRadius) return;
if (!ShowRectLeft && !RadiusLeftBottom && !RadiusLeftTop)
{
g.DrawLine(GetFillColor(), RectSize - 1, 0, RectSize - 1, Height, false, RectSize);
}
if (!ShowRectTop && !RadiusRightTop && !RadiusLeftTop)
{
g.DrawLine(GetFillColor(), 0, RectSize - 1, Width, RectSize - 1, false, RectSize);
}
if (!ShowRectRight && !RadiusRightTop && !RadiusRightBottom)
{
g.DrawLine(GetFillColor(), Width - 1, 0, Width - 1, Height, false, RectSize);
}
if (!ShowRectBottom && !RadiusLeftBottom && !RadiusRightBottom)
{
g.DrawLine(GetFillColor(), 0, Height - 1, Width, Height - 1, false, RectSize);
}
}
/// <summary>
/// 绘制边框颜色
/// </summary>
/// <param name="g">绘图图面</param>
/// <param name="path">绘图路径</param>
protected virtual void OnPaintRect(Graphics g, GraphicsPath path)
{
radius = Math.Min(radius, Math.Min(Width, Height));
if (RadiusSides == UICornerRadiusSides.None || Radius == 0)
{
//IsRadius为False时显示左侧边线
bool ShowRectLeft = RectSides.GetValue(ToolStripStatusLabelBorderSides.Left);
//IsRadius为False时显示上侧边线
bool ShowRectTop = RectSides.GetValue(ToolStripStatusLabelBorderSides.Top);
//IsRadius为False时显示右侧边线
bool ShowRectRight = RectSides.GetValue(ToolStripStatusLabelBorderSides.Right);
//IsRadius为False时显示下侧边线
bool ShowRectBottom = RectSides.GetValue(ToolStripStatusLabelBorderSides.Bottom);
if (ShowRectLeft)
g.DrawLine(GetRectColor(), RectSize - 1, 0, RectSize - 1, Height, false, RectSize);
if (ShowRectTop)
g.DrawLine(GetRectColor(), 0, RectSize - 1, Width, RectSize - 1, false, RectSize);
if (ShowRectRight)
g.DrawLine(GetRectColor(), Width - 1, 0, Width - 1, Height, false, RectSize);
if (ShowRectBottom)
g.DrawLine(GetRectColor(), 0, Height - 1, Width, Height - 1, false, RectSize);
}
else
{
g.DrawPath(GetRectColor(), path, true, RectSize);
PaintRectDisableSides(g);
}
}
/// <summary>
/// 绘制字体
/// </summary>
/// <param name="g">GDI绘图图面</param>
/// <param name="path">路径</param>
protected virtual void OnPaintFore(Graphics g, GraphicsPath path)
{
Color color = GetForeColor();
g.DrawString(Text, Font, color, Size, Padding, TextAlign);
}
protected override void OnTextChanged(EventArgs e)
{
base.OnTextChanged(e);
Invalidate();
}
/// <summary>
/// 填充颜色
/// </summary>
protected Color fillColor = UIStyles.Blue.ButtonFillColor;
/// <summary>
/// 填充鼠标移上颜色
/// </summary>
protected Color fillHoverColor = UIStyles.Blue.ButtonFillColor;
/// <summary>
/// 填充鼠标按下颜色
/// </summary>
protected Color fillPressColor = UIStyles.Blue.ButtonFillColor;
/// <summary>
/// 选中颜色
/// </summary>
protected Color fillSelectedColor = UIStyles.Blue.ButtonFillColor;
/// <summary>
/// 填充不可用颜色
/// </summary>
protected Color fillDisableColor = UIStyles.Blue.FillDisableColor;
/// <summary>
/// 填充只读颜色
/// </summary>
protected Color fillReadOnlyColor = UIStyles.Blue.FillDisableColor;
/// <summary>
/// 填充颜色
/// </summary>
protected Color fillColor2 = UIStyles.Blue.ButtonFillColor2;
protected bool fillColorGradient = false;
/// <summary>
/// 边框颜色
/// </summary>
protected Color rectColor = UIStyles.Blue.ButtonRectColor;
/// <summary>
/// 边框鼠标移上颜色
/// </summary>
protected Color rectHoverColor = UIStyles.Blue.ButtonRectColor;
/// <summary>
/// 边框鼠标按下颜色
/// </summary>
protected Color rectPressColor = UIStyles.Blue.ButtonRectColor;
/// <summary>
/// 边框选中颜色
/// </summary>
protected Color rectSelectedColor = UIStyles.Blue.ButtonRectColor;
/// <summary>
/// 边框不可用颜色
/// </summary>
protected Color rectDisableColor = UIStyles.Blue.RectDisableColor;
/// <summary>
/// 边框只读颜色
/// </summary>
protected Color rectReadOnlyColor = UIStyles.Blue.RectDisableColor;
/// <summary>
/// 字体颜色
/// </summary>
protected Color foreColor = UIStyles.Blue.ButtonForeColor;
/// <summary>
/// 字体鼠标移上颜色
/// </summary>
protected Color foreHoverColor = UIStyles.Blue.ButtonForeColor;
/// <summary>
/// 字体鼠标按下颜色
/// </summary>
protected Color forePressColor = UIStyles.Blue.ButtonForeColor;
/// <summary>
/// 字体选中颜色
/// </summary>
protected Color foreSelectedColor = UIStyles.Blue.ButtonForeColor;
/// <summary>
/// 字体不可用颜色
/// </summary>
protected Color foreDisableColor = UIStyles.Blue.ForeDisableColor;
/// <summary>
/// 字体只读颜色
/// </summary>
protected Color foreReadOnlyColor = UIStyles.Blue.ForeDisableColor;
/// <summary>
/// 设置选中颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetFillSelectedColor(Color color)
{
if (fillSelectedColor != color)
{
fillSelectedColor = color;
SetStyleCustom();
}
}
/// <summary>
/// 设置选中颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetForeSelectedColor(Color color)
{
if (foreSelectedColor != color)
{
foreSelectedColor = color;
SetStyleCustom();
}
}
/// <summary>
/// 设置选中颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetRectSelectedColor(Color color)
{
if (rectSelectedColor != color)
{
rectSelectedColor = color;
SetStyleCustom();
}
}
/// <summary>
/// 设置填充鼠标移上颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetFillHoverColor(Color color)
{
if (fillHoverColor != color)
{
fillHoverColor = color;
SetStyleCustom(false);
}
}
/// <summary>
/// 设置填充鼠标按下颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetFillPressColor(Color color)
{
if (fillPressColor != color)
{
fillPressColor = color;
SetStyleCustom(false);
}
}
/// <summary>
/// 设置填充不可用颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetFillDisableColor(Color color)
{
if (fillDisableColor != color)
{
fillDisableColor = color;
SetStyleCustom();
}
}
/// <summary>
/// 设置填充只读颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetFillReadOnlyColor(Color color)
{
if (fillReadOnlyColor != color)
{
fillReadOnlyColor = color;
SetStyleCustom();
}
}
/// <summary>
/// 设备边框鼠标移上颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetRectHoverColor(Color color)
{
if (rectHoverColor != color)
{
rectHoverColor = color;
SetStyleCustom(false);
}
}
/// <summary>
/// 设置边框鼠标按下颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetRectPressColor(Color color)
{
if (rectPressColor != color)
{
rectPressColor = color;
SetStyleCustom(false);
}
}
/// <summary>
/// 设置边框不可用颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetRectDisableColor(Color color)
{
if (rectDisableColor != color)
{
rectDisableColor = color;
SetStyleCustom();
}
}
/// <summary>
/// 设置边框只读颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetRectReadOnlyColor(Color color)
{
if (rectReadOnlyColor != color)
{
rectReadOnlyColor = color;
SetStyleCustom();
}
}
/// <summary>
/// 设置字体鼠标移上颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetForeHoverColor(Color color)
{
if (foreHoverColor != color)
{
foreHoverColor = color;
SetStyleCustom(false);
}
}
/// <summary>
/// 设置字体鼠标按下颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetForePressColor(Color color)
{
if (forePressColor != color)
{
forePressColor = color;
SetStyleCustom(false);
}
}
/// <summary>
/// 设置字体不可用颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetForeDisableColor(Color color)
{
if (foreDisableColor != color)
{
foreDisableColor = color;
SetStyleCustom();
}
}
/// <summary>
/// 设置字体只读颜色
/// </summary>
/// <param name="color">颜色</param>
protected void SetForeReadonlyColor(Color color)
{
if (foreReadOnlyColor != color)
{
foreReadOnlyColor = color;
SetStyleCustom();
}
}
/// <summary>
/// 设置边框颜色
/// </summary>
/// <param name="value">颜色</param>
protected void SetRectColor(Color value)
{
if (rectColor != value)
{
rectColor = value;
SetStyleCustom();
}
}
/// <summary>
/// 设置填充颜色
/// </summary>
/// <param name="value">颜色</param>
protected void SetFillColor(Color value)
{
if (fillColor != value)
{
fillColor = value;
SetStyleCustom();
}
}
/// <summary>
/// 设置填充颜色
/// </summary>
/// <param name="value">颜色</param>
protected void SetFillColor2(Color value)
{
if (fillColor2 != value)
{
fillColor2 = value;
SetStyleCustom();
}
}
/// <summary>
/// 设置字体颜色
/// </summary>
/// <param name="value">颜色</param>
protected void SetForeColor(Color value)
{
if (foreColor != value)
{
foreColor = value;
SetStyleCustom();
}
}
/// <summary>引发 <see cref="E:System.Windows.Forms.Control.GotFocus" /> 事件。</summary>
/// <param name="e">包含事件数据的 <see cref="T:System.EventArgs" />。</param>
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
this.Invalidate();
}
/// <summary>引发 <see cref="M:System.Windows.Forms.ButtonBase.OnLostFocus(System.EventArgs)" /> 事件。</summary>
/// <param name="e">包含事件数据的 <see cref="T:System.EventArgs" />。</param>
protected override void OnLostFocus(EventArgs e)
{
base.OnLostFocus(e);
this.Invalidate();
}
}
}