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);  
}

image.png

本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864