C# 编写带图标和tooltip的ListBox

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

详见代码:

一、自定义项

[csharp]  view plain copy print ?
  1. /// <summary>  
  2. /// 自定义项  
  3. /// </summary>  
  4. class MyListBoxItem : IDisposable  
  5. {  
  6.     private string _txt;  
  7.     private Image _img;  
  8.     /// <summary>  
  9.     /// 项文本  
  10.     /// </summary>  
  11.     public string Text  
  12.     {  
  13.         get { return _txt; }  
  14.         set { _txt = value; }  
  15.     }  
  16.     /// <summary>  
  17.     /// 项图标(可为null)  
  18.     /// </summary>  
  19.     public Image ItemImage  
  20.     {  
  21.         get { return _img; }  
  22.         set { _img = value; }  
  23.     }  
  24.     /// <summary>  
  25.     /// 是否显示tooltip  
  26.     /// </summary>  
  27.     public bool ShowTip { getset; }  
  28.     /// <summary>  
  29.     /// 带图标构造函数  
  30.     /// </summary>  
  31.     /// <param name="txt"></param>  
  32.     /// <param name="img"></param>  
  33.     public MyListBoxItem(string txt, Image img)  
  34.     {  
  35.         _txt = txt;  
  36.         _img = img;  
  37.     }  
  38.     /// <summary>  
  39.     /// 不带图标构造函数  
  40.     /// </summary>  
  41.     /// <param name="txt"></param>  
  42.     public MyListBoxItem(string txt)  
  43.     {  
  44.         _txt = txt;  
  45.     }  
  46.     /// <summary>  
  47.     /// 重写ToString获取项文本  
  48.     /// </summary>  
  49.     /// <returns></returns>  
  50.     public override string ToString()  
  51.     {  
  52.         return _txt;  
  53.     }  
  54.   
  55.     public void Dispose()  
  56.     {  
  57.         _img = null;  
  58.     }  
  59. }  



二、编写MyListBox,继承ListBox

[csharp]  view plain copy print ?
  1. class MyListBox : ListBox  
  2. {  
  3.     /// <summary>  
  4.     /// 是否带图标  
  5.     /// </summary>  
  6.     private bool HasIcon { getset; }  
  7.     /// <summary>  
  8.     /// 图标宽度(仅在HasIcon属性为true时有效)  
  9.     /// </summary>  
  10.     private int IconWidth { getset; }  
  11.     /// <summary>  
  12.     /// 图标高度(仅在HasIcon属性为true时有效)  
  13.     /// </summary>  
  14.     private int IconHeight { getset; }  
  15.   
  16.     ToolTip tip = new ToolTip();  
  17.   
  18.     public MyListBox()  
  19.     {  
  20.         this.DrawMode = DrawMode.OwnerDrawFixed;  
  21.     }  
  22.     /// <summary>  
  23.     /// 设置图标大小(若不带图标就无需设置)  
  24.     /// </summary>  
  25.     /// <param name="w">图标宽度</param>  
  26.     /// <param name="h">图标高度</param>  
  27.     public void SetIconSize(int w, int h)  
  28.     {  
  29.         this.HasIcon = true;  
  30.         this.IconWidth = w;  
  31.         this.IconHeight = h;  
  32.         this.ItemHeight = h;  
  33.     }  
  34.   
  35.     protected override void OnDrawItem(DrawItemEventArgs e)  
  36.     {  
  37.         e.DrawBackground();  
  38.         e.DrawFocusRectangle();  
  39.   
  40.         Graphics g = e.Graphics;  
  41.         StringFormat sf = new StringFormat();  
  42.         sf.Trimming = StringTrimming.EllipsisCharacter; //超出指定矩形区域部分用"..."替代  
  43.         sf.LineAlignment = StringAlignment.Center;//垂直居中  
  44.         try  
  45.         {  
  46.             MyListBoxItem item = (MyListBoxItem)Items[e.Index];  
  47.   
  48.             SizeF size = g.MeasureString(item.Text, e.Font); //获取项文本尺寸  
  49.             if (HasIcon) //带图标时  
  50.             {  
  51.                 if (size.Width > e.Bounds.Width - this.IconWidth) //项文本宽度超过 项宽-图标宽度  
  52.                 {  
  53.                     item.ShowTip = true//显示tooltip  
  54.                 }  
  55.                 /* 获取指定矩形区域,注意不能直接用项所在矩形,否则DrawString时会出现自动换行 
  56.                  * 的情况。前面说超出指定矩形区域用“...”替代 指的是DrawString方法会先塞满整个 
  57.                  * 矩形区域,如果区域高度够时,就会出现自动换行的情况 ******/  
  58.                 RectangleF rectF = new RectangleF(e.Bounds.Left,  
  59.                     e.Index * this.ItemHeight + (this.ItemHeight - size.Height) / 2.0f,  
  60.                     e.Bounds.Width - this.IconWidth, size.Height);  
  61.                 //写 项文本  
  62.                 g.DrawString(item.Text, e.Font, new SolidBrush(e.ForeColor), rectF, sf);  
  63.                 if (item.ItemImage != null//在项右侧 画图标  
  64.                 {  
  65.                     /* 注意不能用DrawImage(img, x, y)方法,务必指定图标的大小, 
  66.                      * 否则会导致图标被放大,读者不妨一试 :)  *****/  
  67.                     g.DrawImage(item.ItemImage, e.Bounds.Right - this.IconWidth, e.Bounds.Top, this.IconWidth, this.IconHeight);  
  68.                 }  
  69.             }  
  70.             else //不带图标  
  71.             {  
  72.                 if (size.Width > e.Bounds.Width) //项文本宽度超过 项宽  
  73.                 {  
  74.                     item.ShowTip = true//显示tooltip  
  75.                 }  
  76.                 //获取指定矩形区域  
  77.                 RectangleF rectF = new RectangleF(e.Bounds.Left,  
  78.                     e.Index * this.ItemHeight + (this.ItemHeight - size.Height) / 2.0f,  
  79.                     e.Bounds.Width, size.Height);  
  80.                 //写 项文本  
  81.                 g.DrawString(item.Text, e.Font, new SolidBrush(e.ForeColor), rectF, sf);  
  82.             }  
  83.         }  
  84.         catch { } //忽略异常  
  85.   
  86.         base.OnDrawItem(e);  
  87.     }  
  88.     /// <summary>  
  89.     /// 重写鼠标移动事件  
  90.     /// </summary>  
  91.     /// <param name="e"></param>  
  92.     protected override void OnMouseMove(MouseEventArgs e)  
  93.     {  
  94.         base.OnMouseMove(e);  
  95.         int idx = IndexFromPoint(e.Location); //获取鼠标所在的项索引  
  96.         if (idx == MyListBox.NoMatches) //鼠标所在位置没有 项  
  97.         {  
  98.             tip.SetToolTip(this""); //设置提示信息为空  
  99.         }  
  100.         else  
  101.         {  
  102.             MyListBoxItem item = (MyListBoxItem)this.Items[idx];  
  103.             if (item.ShowTip)  
  104.             {  
  105.                 string txt = this.Items[idx].ToString(); //获取项文本  
  106.                 tip.SetToolTip(this, txt); //设置提示信息  
  107.             }  
  108.             else  
  109.             {  
  110.                 tip.SetToolTip(this""); //设置提示信息为空  
  111.             }  
  112.         }  
  113.     }  
  114. }  


三、实例

[csharp]  view plain copy print ?
  1. public Form1()  
  2. {  
  3.     InitializeComponent();  
  4.     //myListBox1--带图标  
  5.     myListBox1.SetIconSize(32, 32);  
  6.     Image img = Image.FromFile(@"C:\Documents and Settings\Administrator\桌面\Ques.png");  
  7.   
  8.     MyListBoxItem i1 = new MyListBoxItem("dfd dfd f", img);  
  9.     myListBox1.Items.Add(i1);  
  10.     i1 = new MyListBoxItem("dfd dfd f d df df dfdfd  fd", img);  
  11.     myListBox1.Items.Add(i1);  
  12.     i1 = new MyListBoxItem("dfd dfd f"null);  
  13.     myListBox1.Items.Add(i1);  
  14.   
  15.     //myListBox2--不带图标  
  16.     i1 = new MyListBoxItem("dfd dfd f");  
  17.     myListBox2.Items.Add(i1);  
  18.     i1 = new MyListBoxItem("dfd dfd f d df df dfdfd  fd");  
  19.     myListBox2.Items.Add(i1);  
  20.     i1 = new MyListBoxItem("d");  
  21.     myListBox2.Items.Add(i1);  
  22. }  


四、效果

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值