添加项目文件。
This commit is contained in:
@@ -0,0 +1,280 @@
|
||||
using AntdUI;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user