上午刚写了一篇关于带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); }
本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:


