开发者

Draw images and text in ComboBox

开发者 https://www.devze.com 2023-02-26 02:04 出处:网络
I have a ComboBox in WindowsForms and I draw items manually. Each item is composed from picture开发者_如何学运维 and text (Cell.Image and Cell.Title), so item is 34 px height.

I have a ComboBox in WindowsForms and I draw items manually. Each item is composed from picture开发者_如何学运维 and text (Cell.Image and Cell.Title), so item is 34 px height.

My problem is that when I drop down ComboBox, only 1 item is visible. MaxDropDownItems = 4 so ComboBox would draw 4 items. I know that I have set DropDownHeight = 34, but I want to display empty rectangle when there is no item in ComboBox like on the following picture.

ComboBox with no item - OK:

Draw images and text in ComboBox

ComboBox with only 1 visible item - Bad:

Draw images and text in ComboBox

My class derived from ComboBox:

public class ComboBoxCells : ComboBox
{
    private List<Cell> _cells;

    public List<Cell> Cells
    {
        get { return this._cells; }
        set
        {
            this._cells = value;
            this.BeginUpdate();
            this.Items.Clear();

            if (value != null)
                this.Items.AddRange(value.ToArray());

            this.EndUpdate();
        }
    }

    public ComboBoxCells()
    {
        this.DrawMode = DrawMode.OwnerDrawVariable;
        this.DropDownHeight = 34;
        this.DropDownWidth = 200;
        this.DropDownStyle = ComboBoxStyle.DropDownList;
        this.MaxDropDownItems = 4;

        this.DrawItem += new DrawItemEventHandler(ComboBoxCells_DrawItem);
        this.MeasureItem += new MeasureItemEventHandler(ComboBoxCells_MeasureItem);
    }

    private void ComboBoxCells_DrawItem(object sender, DrawItemEventArgs e)
    {
        e.DrawBackground();

        // Draw item inside comboBox
        if ((e.State & DrawItemState.ComboBoxEdit) != DrawItemState.ComboBoxEdit && e.Index > -1)
        {
            Cell item = this.Items[e.Index] as Cell;

            e.Graphics.FillRectangle(Brushes.Gray, new Rectangle(e.Bounds.Left + 6, e.Bounds.Top + 6, 22, 22));

            e.Graphics.DrawImage(item.Image, new Rectangle(e.Bounds.Left + 7, e.Bounds.Top + 7, 20, 20));

            e.Graphics.DrawString(item.Title, e.Font,
                    new SolidBrush(e.ForeColor), e.Bounds.Left + 34, e.Bounds.Top + 10);
        }
        // Draw visible text
        else if (e.Index > -1)
        {
            Cell item = this.Items[e.Index] as Cell;

            e.Graphics.DrawString(item.Title, e.Font,
                    new SolidBrush(e.ForeColor), e.Bounds.Left, e.Bounds.Top);
        }

        e.DrawFocusRectangle();
    }

    private void ComboBoxCells_MeasureItem(object sender, MeasureItemEventArgs e)
    {
        e.ItemHeight = 34;
    }
}

Thanks


DropDownHeight is the number you want to set higher. It is the maximum number of pixels for the drop down box. The system will automatically make it the largest multiple of your item height.

this.DropDownHeight = 200;


If you set IntegralHeight to true it will resize the drop down list so it doesn't show partial items. It should get rid of the white space.


In your ComboBoxCells() constructor, add default cell item that can draw white rectangle of 34 px height.

In List<Cell> Cells Set property, remove that item and add new items specified by value.ToArray(). This makes sure that default item is removed whenever list of items are specified, otherwise draw default item.

In your ComboBoxCells_DrawItem() event, handle this change with e.Index = 0 condition and draw the rectangle.

Hope this approach works for you.

0

精彩评论

暂无评论...
验证码 换一张
取 消