ListBox控件扩展内容高度自适应,添加图标

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

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

项目结构

ListBox控件扩展内容高度自适应,添加图标

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 });
        }
© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...