using JinYuan.ControlLib.UCHelper; using System; using System.ComponentModel; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace JinYuan.ControlLib { public partial class ControlBase : UserControl { /// /// The is radius /// private bool _isRadius = false; /// /// The corner radius /// private int _cornerRadius = 24; /// /// The is show rect /// private bool _isShowRect = false; /// /// The rect color /// private Color _rectColor = Color.FromArgb(220, 220, 220); /// /// The rect width /// private int _rectWidth = 1; /// /// The fill color /// private Color _fillColor = Color.Transparent; // 缓存绘图对象,避免重复创建(线程安全:UI线程单例) private SolidBrush _fillBrush; private Pen _rectPen; private bool _isRegionDirty = true; // 标记区域是否需要重新计算 #region 公共属性(替换Refresh为Invalidate) [Description("是否圆角"), Category("自定义")] public virtual bool IsRadius { get => _isRadius; set { if (_isRadius == value) return; _isRadius = value; _isRegionDirty = true; Invalidate(); } } /// /// 圆角角度 /// /// The coner radius. [Description("圆角角度"), Category("自定义")] public virtual int ConerRadius { get => _cornerRadius; set { value = Math.Max(value, 1); if (_cornerRadius == value) return; _cornerRadius = value; _isRegionDirty = true; Invalidate(); } } /// /// 是否显示边框 /// /// true if this instance is show rect; otherwise, false. [Description("是否显示边框"), Category("自定义")] public virtual bool IsShowRect { get => _isShowRect; set { if (_isShowRect == value) return; _isShowRect = value; Invalidate(); } } /// /// 边框颜色 /// /// The color of the rect. [Description("边框颜色"), Category("自定义")] public virtual Color RectColor { get => _rectColor; set { if (_rectColor == value) return; _rectColor = value; // 重置画笔,下次使用时创建 _rectPen?.Dispose(); _rectPen = null; Invalidate(); } } /// /// 边框宽度 /// /// The width of the rect. [Description("边框宽度"), Category("自定义")] public virtual int RectWidth { get => _rectWidth; set { if (_rectWidth == value) return; _rectWidth = value; // 重置画笔,下次使用时创建 _rectPen?.Dispose(); _rectPen = null; Invalidate(); } } /// /// 当使用边框时填充颜色,当值为背景色或透明色或空值则不填充 /// /// The color of the fill. [Description("当使用边框时填充颜色,当值为背景色或透明色或空值则不填充"), Category("自定义")] public virtual Color FillColor { get => _fillColor; set { if (_fillColor == value) return; _fillColor = value; // 重置画刷,下次使用时创建 _fillBrush?.Dispose(); _fillBrush = null; Invalidate(); } } #endregion /// /// Initializes a new instance of the class. /// public ControlBase() { InitializeComponent(); // 优化双缓冲设置 SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.Selectable | ControlStyles.SupportsTransparentBackColor | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true); UpdateStyles(); // 应用样式设置 } #region 核心优化:重写OnPaint protected override void OnPaint(PaintEventArgs e) { if (!Visible) return; // 1. 仅在区域脏时更新Region if (_isRegionDirty) { UpdateWindowRegion(); _isRegionDirty = false; } // 2. 优化绘图质量 e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; e.Graphics.CompositingQuality = CompositingQuality.HighQuality; e.Graphics.Clear(BackColor); // 统一背景清除,避免闪烁 // 3. 绘制逻辑:仅在需要时创建GraphicsPath if (_isShowRect || (_fillColor != Color.Empty && _fillColor != Color.Transparent && _fillColor != BackColor)) { using (var graphicsPath = CreateRoundedRectPath(ClientRectangle)) { // 绘制填充 if (_fillColor != Color.Empty && _fillColor != Color.Transparent && _fillColor != BackColor) { if (_fillBrush == null) { _fillBrush = new SolidBrush(_fillColor); } e.Graphics.FillPath(_fillBrush, graphicsPath); } // 绘制边框 if (_isShowRect) { if (_rectPen == null) { _rectPen = new Pen(_rectColor, Math.Max(1, _rectWidth)); // 避免宽度为0 } e.Graphics.DrawPath(_rectPen, graphicsPath); } } } base.OnPaint(e); } #endregion #region 辅助方法(优化逻辑+释放资源) /// /// 仅在区域脏时更新WindowRegion /// private void UpdateWindowRegion() { if (_isRadius) { using (var path = CreateRoundedRectPath(new Rectangle(-1, -1, Width + 1, Height))) { Region = new Region(path); } } else { // 恢复矩形区域 using (var path = new GraphicsPath()) { path.AddRectangle(ClientRectangle); Region = new Region(path); } } } /// /// 创建圆角路径 /// /// 绘制矩形 /// GraphicsPath private GraphicsPath CreateRoundedRectPath(Rectangle rect) { var path = new GraphicsPath(); if (_isRadius && _cornerRadius > 0) { // 优化圆角计算:避免偏移错误 int radius = Math.Min(_cornerRadius, Math.Min(rect.Width, rect.Height) / 2); path.AddArc(rect.X, rect.Y, radius, radius, 180f, 90f); path.AddArc(rect.Right - radius, rect.Y, radius, radius, 270f, 90f); path.AddArc(rect.Right - radius, rect.Bottom - radius, radius, radius, 0f, 90f); path.AddArc(rect.X, rect.Bottom - radius, radius, radius, 90f, 90f); path.CloseFigure(); } else { path.AddRectangle(rect); } return path; } /// /// 释放非托管资源 /// /// 是否手动释放 protected override void Dispose(bool disposing) { if (disposing) { // 释放绘图对象 _fillBrush?.Dispose(); _rectPen?.Dispose(); components?.Dispose(); } base.Dispose(disposing); } /// /// 控件大小变化时标记区域脏 /// /// 尺寸参数 protected override void OnSizeChanged(EventArgs e) { base.OnSizeChanged(e); _isRegionDirty = true; Invalidate(); } #endregion /// /// 屏蔽不必要的消息 /// /// Windows消息 protected override void WndProc(ref Message m) { if (m.Msg != 20) { base.WndProc(ref m); } } } }