自定义绘制下拉框
一、OwnerDrawComboBox类实现
/// <summary> /// 自定义绘制下拉框(绘制项,绘制边框(未解决下拉框边框的绘制)) /// </summary> public class OwnerDrawComboBox : ComboBox { private const int WM_PAINT = 0xF; private Color _selectedBackColor = Color.Blue; /// <summary> /// 边框颜色 /// </summary> [Description("边框颜色"), Category("外观")] public Color SelectedBackColor { get => _selectedBackColor; set => _selectedBackColor = value; } public OwnerDrawComboBox() : base() { this.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable; } /// <summary> /// 自定义绘制下拉框项 /// </summary> /// <param name="e"></param> protected override void OnDrawItem(DrawItemEventArgs e) { this.DrawItemInternal(e); } private void DrawItemInternal(DrawItemEventArgs e) { if (e.Index < 0) { return; } //// Draw the background of the item. //e.DrawBackground(); // 绘制背景色 var color = e.BackColor; var foreColor = e.ForeColor; if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { color = this.SelectedBackColor; } e.Graphics.FillRectangle(new SolidBrush(color), e.Bounds); // Draw each string in the array, using a different size, color, e.Graphics.DrawString(this.GetItemString(this.Items[e.Index]), e.Font, new SolidBrush(foreColor), e.Bounds); // Draw the focus rectangle if the mouse hovers over an item. e.DrawFocusRectangle(); } /// <summary> /// 重绘,绘制边框 /// </summary> /// <param name="m"></param> protected override void WndProc(ref Message m) { base.WndProc(ref m); if ((m.Msg == WM_PAINT)) { using (var g = Graphics.FromHwnd(this.Handle)) { //using (var pen = new Pen(this.BorderColor, 2)) //{ // //g.DrawRectangle(pen, this.ClientRectangle); //} System.Windows.Forms.ControlPaint.DrawBorder(g, this.ClientRectangle, this.SelectedBackColor, ButtonBorderStyle.Solid); } } } private string GetItemString(object item) { if (!this.DisplayMember.IsNullOrEmpty()) { var value = item.GetObjectValue(this.DisplayMember); if (null != value) { return $"{value}"; } } return $"{item}"; } }
二、扩展方法ExtendUnity类相关实现
public static class ExtendUnity { /// <summary> /// 字符串判空 /// </summary> /// <param name="value"></param> /// <returns></returns> public static bool IsNullOrEmpty(this string value) { if (string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value)) { return true; } return false; } /// <summary> /// object类型通过反射加载字段值 /// </summary> /// <param name="obj">对象</param> /// <param name="fieldName">属性名称</param> /// <returns></returns> public static object GetObjectValue(this object obj, string fieldName) { var value = obj; string[] fields = fieldName.Split('.'); foreach (string field in fields) { if (value == null) { break; } Type type = value.GetType(); if (type.GetProperty(field) == null) { value = null; break; } else { value = type.GetProperty(field).GetValue(value, null); } } return value; } }
三、效果图
四、存在问题
自定义绘制下拉框(绘制项,绘制边框(未解决下拉框边框的绘制))
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)