上午刚写了一篇关于带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);
- }
四、效果