ListBox控件扩展内容高度自适应,添加图标
在Winform中对Listbox控件,进行扩展,支持根据内容自适应高度,添加图标

注意点:
- 图标这里使用的是图片,默认大小设置为20*20,可根据实际情况更改。
- 消息根据类型,显示不同的图标和字体颜色。
项目结构

MessaegItem.cs
// 消息项类public class MessageItem{public string Text { get; set; }public MessageType MessageType { get; set; }public DateTime Timestamp { get; set; }public override string ToString(){return $"[{Timestamp:yyyy-MM-dd HH:mm:ss}] {Text}";}}
MessageType.cs
public enum MessageType{Success,Warning,Error,Info,Tip}
ListBoxAutoHeight
/// <summary>/// 高度自定义/// </summary>public partial class ListBoxAutoHeight : ListBox{// 存储消息的队列,限制为20条private Queue<MessageItem> messageQueue = new Queue<MessageItem>(20);public ListBoxAutoHeight(){InitializeComponent();this.SetStyle(ControlStyles.AllPaintingInWmPaint |ControlStyles.OptimizedDoubleBuffer |ControlStyles.ResizeRedraw |ControlStyles.Selectable |ControlStyles.SupportsTransparentBackColor, true);this.DrawMode = DrawMode.OwnerDrawVariable;// 设置ListBox的项高度,确保能容纳图标和文本//this.ItemHeight = 20;this.DrawItem += ListBoxEx_DrawItem;this.MeasureItem += ListBoxEx_MeasureItem;}private void ListBoxEx_MeasureItem(object sender, MeasureItemEventArgs e){if (e.Index < 0 || e.Index >= this.Items.Count)return;// 获取当前项MessageItem message = (MessageItem)this.Items[e.Index];// 获取图标SizeF size = e.Graphics.MeasureString(message.ToString(), Font);// 15 滚动条的宽度int width = Width - 20 - 10 - 15;float height = size.Height + 3;if (size.Width > width){height = height * 2;}height = Math.Max(height, 24);e.ItemHeight = (int)height;}// 绘制ListBox中的项private void ListBoxEx_DrawItem(object sender, DrawItemEventArgs e){if (e.Index < 0 || e.Index >= this.Items.Count)return;// 获取当前项MessageItem message = (MessageItem)this.Items[e.Index];// 绘制背景e.DrawBackground();int iconWidth = 16;// 获取图标Image icon = GetImageForMessageType(message.MessageType);// 计算绘制位置Rectangle iconRect = new Rectangle(e.Bounds.X + (24 - iconWidth) / 2, e.Bounds.Y + (24 - iconWidth) / 2,iconWidth, iconWidth);// 20 作为icon的宽高int width = e.Bounds.Width - iconWidth - 10;Rectangle textRect = new Rectangle(e.Bounds.X + iconWidth + 10, e.Bounds.Y,width, e.Bounds.Height);// 绘制图标e.Graphics.DrawImage(icon, iconRect, 0, 0, icon.Width, icon.Height, GraphicsUnit.Pixel);// 设置文本格式using (StringFormat format = new StringFormat()){format.Alignment = StringAlignment.Near;format.LineAlignment = StringAlignment.Center;// 根据消息类型设置文本颜色Color textColor = GetTextColorForMessageType(message.MessageType);// 绘制文本e.Graphics.DrawString(message.ToString(),e.Font,new SolidBrush(textColor),textRect,format);}// 绘制焦点矩形e.DrawFocusRectangle();}// 根据消息类型获取图标private Image GetImageForMessageType(MessageType type){switch (type){case MessageType.Success:case MessageType.Info:return Properties.Resources.info;case MessageType.Warning:case MessageType.Error:return Properties.Resources.error;default:return Properties.Resources.info;}}// 根据消息类型获取文本颜色private Color GetTextColorForMessageType(MessageType type){switch (type){case MessageType.Success:case MessageType.Info:return Color.FromArgb(168, 214, 255);case MessageType.Warning:case MessageType.Error:return Color.DarkOrange;default:return Color.Black;}}/// <summary>/// 清空消息/// </summary>public void ClearMessage(){messageQueue.Clear();this.Items.Clear();}/// <summary>/// 添加消息到队列和ListBox/// </summary>/// <param name="text"></param>/// <param name="type"></param>public void AddMessage(MessageItem message){// 如果队列已满,移除最旧的消息if (messageQueue.Count >= 20){messageQueue.Dequeue();this.Items.RemoveAt(0);}// 添加新消息messageQueue.Enqueue(message);this.Items.Add(message);// 滚动到最新消息this.SelectedIndex = this.Items.Count - 1;this.SelectedIndex = -1;}}
UseControlFrm.cs 中按钮绑定事件
int i = 0;private void addTipButton_Click(object sender, EventArgs e){i++;listBoxEx1.AddMessage(new MessageItem() { Text = $"这是一条提示消息这是一条提示消息这是一条提示消息这是一条提示消息这是一条提示消息这是一条提示消息--{i}", MessageType = MessageType.Tip });}private void addWarningButton_Click(object sender, EventArgs e){i++;listBoxEx1.AddMessage(new MessageItem() { Text = $"这是一条一般信息--{i}", MessageType = MessageType.Info });}private void clearButton_Click(object sender, EventArgs e){i = 0;listBoxEx1.ClearMessage();}private void addInfoButton_Click(object sender, EventArgs e){i++;listBoxEx1.AddMessage(new MessageItem() { Text = $"这是一条警告信息--{i}", MessageType = MessageType.Warning });}
