using AntdUI.Theme; using AntdUI; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing.Drawing2D; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace JinYuan.ControlLib { public partial class CustomComboBox : ComboBox { private Color darkBackColor = Color.FromArgb(30, 30, 30); private Color lightBackColor = Color.White; private Color darkForeColor = Color.White; private Color lightForeColor = Color.Black; private Color darkBorderColor = Color.FromArgb(64, 64, 64); private Color lightBorderColor = Color.FromArgb(217, 217, 217); private Color darkArrowColor = Color.White; private Color lightArrowColor = Color.Black; private Color darkWatermarkColor = Color.Gray; private Color lightWatermarkColor = Color.LightGray; private string watermarkText = string.Empty; [Category("行为")] public string WatermarkText { get { return watermarkText; } set { watermarkText = value; Invalidate(); } } private int cornerRadius = 5; // 新增:控制圆角半径的字段 [Category("外观")] [DefaultValue(5)] public int CornerRadius { get { return cornerRadius; } set { if (cornerRadius != value) { cornerRadius = value; Invalidate(); } } } public CustomComboBox() { SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); DrawMode = DrawMode.OwnerDrawFixed; DropDownStyle = ComboBoxStyle.DropDownList; UpdateTheme(Config.IsDark); } public void UpdateTheme(bool isDark) { BackColor = isDark ? darkBackColor : lightBackColor; ForeColor = isDark ? darkForeColor : lightForeColor; Invalidate(); } protected override void OnPaint(PaintEventArgs e) { using (var path = CreateRoundedRectangle(new Rectangle(0, 0, Width - 1, Height - 1), cornerRadius)) { var g = e.Graphics; g.SmoothingMode = SmoothingMode.AntiAlias; var rect = new Rectangle(0, 0, Width - 1, Height - 1); var borderColor = Config.IsDark ? darkBorderColor : lightBorderColor; var arrowColor = Config.IsDark ? darkArrowColor : lightArrowColor; // Draw background using (var brush = new SolidBrush(BackColor)) { g.FillPath(brush, path); } // Draw border using (var pen = new Pen(borderColor)) { g.DrawPath(pen, path); } // Draw text or watermark var textRect = new Rectangle(cornerRadius, 2, Width - 20 - cornerRadius, Height - 4); var flags = TextFormatFlags.VerticalCenter | TextFormatFlags.Left; if (SelectedItem != null) { string displayText = GetCustomItemText(SelectedItem); using (var brush = new SolidBrush(ForeColor)) { TextRenderer.DrawText(g, displayText, Font, textRect, ForeColor, flags); } } else if (!string.IsNullOrEmpty(watermarkText)) { var watermarkColor = Config.IsDark ? darkWatermarkColor : lightWatermarkColor; TextRenderer.DrawText(g, watermarkText, Font, textRect, watermarkColor, flags); } // Draw arrow var arrowSize = 8; var arrowRect = new Rectangle(Width - arrowSize - 8 - cornerRadius, (Height - arrowSize) / 2, arrowSize, arrowSize); using (var brush = new SolidBrush(arrowColor)) { Point[] arrow = { new Point(arrowRect.Left, arrowRect.Top), new Point(arrowRect.Right, arrowRect.Top), new Point(arrowRect.Left + arrowRect.Width / 2, arrowRect.Bottom) }; g.FillPolygon(brush, arrow); } } } protected override void OnDrawItem(DrawItemEventArgs e) { if (e.Index < 0) return; // 设置下拉项的背景色 Color backColor; Color textColor; if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { // 选中项的颜色 backColor = Config.IsDark ? Color.FromArgb(45, 45, 45) : Color.FromArgb(230, 230, 230); textColor = Config.IsDark ? darkForeColor : lightForeColor; } else { // 未选中项的颜色 backColor = Config.IsDark ? darkBackColor : lightBackColor; textColor = Config.IsDark ? darkForeColor : lightForeColor; } // 使用新的背景色绘制背景 using (var backBrush = new SolidBrush(backColor)) { e.Graphics.FillRectangle(backBrush, e.Bounds); } // 绘制文本 if (e.Index >= 0) { string itemText = GetCustomItemText(Items[e.Index]); // 设置文本边距 Rectangle textBounds = new Rectangle( e.Bounds.X + 5, // 左边距 e.Bounds.Y, e.Bounds.Width - 10, // 右边距 e.Bounds.Height ); // 使用TextRenderer绘制文本以获得更好的文本渲染效果 TextRenderer.DrawText( e.Graphics, itemText, Font, textBounds, textColor, TextFormatFlags.VerticalCenter | TextFormatFlags.Left ); } // 如果有焦点,绘制焦点矩形 if ((e.State & DrawItemState.Focus) == DrawItemState.Focus) { using (Pen focusPen = new Pen(Config.IsDark ? Color.FromArgb(70, 70, 70) : Color.FromArgb(180, 180, 180))) { e.Graphics.DrawRectangle(focusPen, new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width - 1, e.Bounds.Height - 1)); } } } // 添加这个方法来处理下拉列表的外观 protected override void WndProc(ref System.Windows.Forms.Message m) { if (m.Msg == 0x204E) // WM_CTLCOLORLISTBOX { // 获取下拉列表的句柄 var hDC = m.WParam; var hListBox = m.LParam; using (Graphics g = Graphics.FromHdc(hDC)) { // 设置下拉列表的背景色 using (SolidBrush backBrush = new SolidBrush(Config.IsDark ? darkBackColor : lightBackColor)) { g.FillRectangle(backBrush, this.DropDownRectangle); } } } base.WndProc(ref m); } // 获取下拉列表的矩形区域 private Rectangle DropDownRectangle { get { return new Rectangle(0, 0, DropDownWidth, ItemHeight * Math.Max(Items.Count, 1)); } } private string GetCustomItemText(object item) { if (item == null) return string.Empty; if (string.IsNullOrEmpty(DisplayMember)) return item.ToString(); PropertyDescriptor descriptor = TypeDescriptor.GetProperties(item).Find(DisplayMember, true); if (descriptor != null) return descriptor.GetValue(item)?.ToString() ?? string.Empty; return item.ToString(); } public object GetSelectedValue() { if (SelectedItem == null) return null; if (string.IsNullOrEmpty(ValueMember)) return SelectedItem; PropertyDescriptor descriptor = TypeDescriptor.GetProperties(SelectedItem).Find(ValueMember, true); if (descriptor != null) return descriptor.GetValue(SelectedItem); return null; } private GraphicsPath CreateRoundedRectangle(Rectangle bounds, int radius) { int diameter = radius * 2; Size size = new Size(diameter, diameter); Rectangle arc = new Rectangle(bounds.Location, size); GraphicsPath path = new GraphicsPath(); if (radius == 0) { path.AddRectangle(bounds); return path; } // 左上角 path.AddArc(arc, 180, 90); // 右上角 arc.X = bounds.Right - diameter; path.AddArc(arc, 270, 90); // 右下角 arc.Y = bounds.Bottom - diameter; path.AddArc(arc, 0, 90); // 左下角 arc.X = bounds.Left; path.AddArc(arc, 90, 90); path.CloseFigure(); return path; } } }