ComboBox draw image on selected item

Change your ComboBox DrawMode to OwnerDrawVariable.
Use the DrawItem event to draw the images from your source (an ImageList, in this case) inside the ComboBox item Bounds.

If the ComboBox DropDownStyle is set to DropDownList, the image will be shown in the selection box; if it’s set to DropDown, only the text will be drawn.

Here, the Focus rectangle is only drawn when the mouse point hovers the ListControl’s items, while it’s not used when an item is selected, which is determined by:
(e.State.HasFlag(DrawItemState.Focus) && !e.State.HasFlag(DrawItemState.ComboBoxEdit)).

private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
    if (e.Index < 0) return;
    var cbo = sender as ComboBox;
    Color foreColor = e.ForeColor;

    if (e.State.HasFlag(DrawItemState.Selected) && !(e.State.HasFlag(DrawItemState.ComboBoxEdit))) {
        e.DrawBackground();
        e.DrawFocusRectangle(); // <= could be removed for a cleaner rendering
    }
    else {
        using (var brush = new SolidBrush(cbo.BackColor)) {
            var rect = e.Bounds;
            rect.Inflate(1, 1);
            e.Graphics.FillRectangle(brush, rect);
        }
        foreColor = cbo.ForeColor;
    }
    TextRenderer.DrawText(e.Graphics, cbo.GetItemText(cbo.Items[e.Index]), e.Font,
        new Point(e.Bounds.Height + 10, e.Bounds.Y), foreColor);

    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    e.Graphics.DrawImage(imageList1.Images[e.Index],
                         new Rectangle(e.Bounds.Location,
                         new Size(e.Bounds.Height - 2, e.Bounds.Height - 2)));
}

The Magic Numbers here (10, -2) are just offsets:
e.Bounds.Height + 10 => 10 pixels to the right of the image.
e.Bounds.Height -2 => 2 pixels less than the item.Bounds.Height.

ComboBox Ownerdraw with Images

Leave a Comment