允许每个项目在 Winforms 组合框(或列表框)中使用多行 [英] Allow each item to use multiple lines in a Winforms Combobox (or Listbox)

查看:20
本文介绍了允许每个项目在 Winforms 组合框(或列表框)中使用多行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可以相对轻松地完成吗?

Can this be done with relative ease?

推荐答案

我能够在 15 分钟内完成以下操作,所以是的.主要思想是处理DrawItem事件.

I was able to do the following in 15 minutes, so yes. The main idea is to handle the DrawItem event.

以下是我对这个问题的看法(你可以看到另一个例子,在项目 此处).

Following is my take on the problem (you can see another example, drawing icons in the items here).

public partial class Form1 : Form  
{
    public Form1()
    {
        InitializeComponent();

        this.comboBox1.DrawMode = DrawMode.OwnerDrawVariable;            
        this.comboBox1.DrawItem += new DrawItemEventHandler(comboBox1_DrawItem);
        this.comboBox1.Items.Add("Some text that needs to be take up two lines...");
        this.comboBox1.ItemHeight = 30;
    }

    IEnumerable<string> WrapString(string str, Graphics g, Font font, 
                                   int allowedWidth)
    {            
        string[] arr = str.Split(' ');            
        StringBuilder current = new StringBuilder();
        foreach (string token in arr)
        {                
            // TODO: You'll have to fix this, might break in marginal cases
            int width = 
              (int)g.MeasureString(current.ToString() + " " + token, font).Width;
            if (width > allowedWidth)
            {
                yield return current.ToString();
                current.Clear();
            }

            current.Append(token + " ");

        }
        yield return current.ToString();
    }

    void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        Brush backgroundBrush, forgroundBrush;

        if (e.State == (DrawItemState.Selected | 
                    DrawItemState.NoAccelerator | DrawItemState.NoFocusRect) ||
            e.State == DrawItemState.Selected) 
        {
            forgroundBrush = Brushes.Black;
            backgroundBrush = Brushes.White;
        }
        else
        {
            forgroundBrush = Brushes.White;
            backgroundBrush = Brushes.Black;
        }

        // some way to wrap the string (on a space)           
        string str = (string)comboBox1.Items[e.Index];


        Rectangle rc = 
           new Rectangle(e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
        e.Graphics.FillRectangle(forgroundBrush, rc);

        int stringHeight = 
               (int)e.Graphics.MeasureString(str, comboBox1.Font).Height;
        int lineNo = 0;
        foreach (string line in 
                      WrapString(str, e.Graphics, comboBox1.Font, e.Bounds.Width))
        {
            e.Graphics.DrawString(line, comboBox1.Font, backgroundBrush, 
                                  new PointF(0, lineNo * stringHeight + 5));
            lineNo++;
        }            
    }             
}

用法:创建一个常规表单并在其上放置一个组合框.

Usage: Create a regular form and drop one combobox on it.

(请注意,这当然只是一个简单的概念证明 - 显然还有改进的空间.而且它只是假设只有两行而不是一行.但它表明这是可能的.)

(Note that this is of course only a naïve proof of concept - there's obviously room for improvement. Also it's just assuming that there will only be two lines rather than one. But it shows that this is possible.)

这篇关于允许每个项目在 Winforms 组合框(或列表框)中使用多行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆