C# 编写带图标和tooltip的ListBox

上午刚写了一篇关于带ToolTip的ListBox控件,这一篇是针对所有项,无论项文本长度有无超出控件,都会呈现ToolTip。现在这一篇基础上加一些限制并引进图标显示,只对超出部分的项才呈现ToolTip,项文本对超出部分用“…”替代

详见代码:

一、自定义项

/// <summary>/// 自定义项/// </summary>class MyListBoxItem : IDisposable{private string _txt;private Image _img;/// <summary>/// 项文本/// </summary>public string Text{get { return _txt; }set { _txt = value; }}/// <summary>/// 项图标(可为null)/// </summary>public Image ItemImage{get { return _img; }set { _img = value; }}/// <summary>/// 是否显示tooltip/// </summary>public bool ShowTip { get; set; }/// <summary>/// 带图标构造函数/// </summary>/// <param name="txt"></param>/// <param name="img"></param>public MyListBoxItem(string txt, Image img){_txt = txt;_img = img;}/// <summary>/// 不带图标构造函数/// </summary>/// <param name="txt"></param>public MyListBoxItem(string txt){_txt = txt;}/// <summary>/// 重写ToString获取项文本/// </summary>/// <returns></returns>public override string ToString(){return _txt;}public void Dispose(){_img = null;}}

二、编写MyListBox,继承ListBox

class MyListBox : ListBox{/// <summary>/// 是否带图标/// </summary>private bool HasIcon { get; set; }/// <summary>/// 图标宽度(仅在HasIcon属性为true时有效)/// </summary>private int IconWidth { get; set; }/// <summary>/// 图标高度(仅在HasIcon属性为true时有效)/// </summary>private int IconHeight { get; set; }ToolTip tip = new ToolTip();public MyListBox(){this.DrawMode = DrawMode.OwnerDrawFixed;}/// <summary>/// 设置图标大小(若不带图标就无需设置)/// </summary>/// <param name="w">图标宽度</param>/// <param name="h">图标高度</param>public void SetIconSize(int w, int h){this.HasIcon = true;this.IconWidth = w;this.IconHeight = h;this.ItemHeight = h;}protected override void OnDrawItem(DrawItemEventArgs e){e.DrawBackground();e.DrawFocusRectangle();Graphics g = e.Graphics;StringFormat sf = new StringFormat();sf.Trimming = StringTrimming.EllipsisCharacter; //超出指定矩形区域部分用"…"替代sf.LineAlignment = StringAlignment.Center;//垂直居中try{MyListBoxItem item = (MyListBoxItem)Items[e.Index];SizeF size = g.MeasureString(item.Text, e.Font); //获取项文本尺寸if (HasIcon) //带图标时{if (size.Width > e.Bounds.Width – this.IconWidth) //项文本宽度超过 项宽-图标宽度{item.ShowTip = true; //显示tooltip}/* 获取指定矩形区域,注意不能直接用项所在矩形,否则DrawString时会出现自动换行* 的情况。前面说超出指定矩形区域用“…”替代 指的是DrawString方法会先塞满整个* 矩形区域,如果区域高度够时,就会出现自动换行的情况 ******/RectangleF rectF = new RectangleF(e.Bounds.Left,e.Index * this.ItemHeight + (this.ItemHeight – size.Height) / 2.0f,e.Bounds.Width – this.IconWidth, size.Height);//写 项文本g.DrawString(item.Text, e.Font, new SolidBrush(e.ForeColor), rectF, sf);if (item.ItemImage != null) //在项右侧 画图标{/* 注意不能用DrawImage(img, x, y)方法,务必指定图标的大小,,* 否则会导致图标被放大,读者不妨一试 🙂 *****/g.DrawImage(item.ItemImage, e.Bounds.Right – this.IconWidth, e.Bounds.Top, this.IconWidth, this.IconHeight);}}else //不带图标{if (size.Width > e.Bounds.Width) //项文本宽度超过 项宽{item.ShowTip = true; //显示tooltip}//获取指定矩形区域RectangleF rectF = new RectangleF(e.Bounds.Left,e.Index * this.ItemHeight + (this.ItemHeight – size.Height) / 2.0f,e.Bounds.Width, size.Height);//写 项文本g.DrawString(item.Text, e.Font, new SolidBrush(e.ForeColor), rectF, sf);}}catch { } //忽略异常base.OnDrawItem(e);}/// <summary>/// 重写鼠标移动事件/// </summary>/// <param name="e"></param>protected override void OnMouseMove(MouseEventArgs e){base.OnMouseMove(e);int idx = IndexFromPoint(e.Location); //获取鼠标所在的项索引if (idx == MyListBox.NoMatches) //鼠标所在位置没有 项{tip.SetToolTip(this, ""); //设置提示信息为空}else{MyListBoxItem item = (MyListBoxItem)this.Items[idx];if (item.ShowTip){string txt = this.Items[idx].ToString(); //获取项文本tip.SetToolTip(this, txt); //设置提示信息}else{tip.SetToolTip(this, ""); //设置提示信息为空}}}}

三、实例

public Form1(){InitializeComponent();//myListBox1–带图标myListBox1.SetIconSize(32, 32);Image img = Image.FromFile(@"C:\Documents and Settings\Administrator\桌面\Ques.png");MyListBoxItem i1 = new MyListBoxItem("dfd dfd f", img);myListBox1.Items.Add(i1);i1 = new MyListBoxItem("dfd dfd f d df df dfdfd fd", img);myListBox1.Items.Add(i1);i1 = new MyListBoxItem("dfd dfd f", null);myListBox1.Items.Add(i1);//myListBox2–不带图标i1 = new MyListBoxItem("dfd dfd f");myListBox2.Items.Add(i1);i1 = new MyListBoxItem("dfd dfd f d df df dfdfd fd");myListBox2.Items.Add(i1);i1 = new MyListBoxItem("d");myListBox2.Items.Add(i1);}

四、效果

因为有梦,所以勇敢出发,选择出发,便只顾风雨兼程。

C# 编写带图标和tooltip的ListBox

相关文章:

你感兴趣的文章:

标签云: