C# - ListBox / ListView to support both data binding and thumbnails

Question

In a C# Windows Forms Application, I want a list control which supports two features:

  1. ListView-style Thumbnail display. ListView allows you to bind it to an ImageList, but ListBox doesn't support thumbnails.
  2. Binding data - ListBox allows you to bind a list of 'object' using the DataSource property. However all I need is to be able to bind data to each item's caption and an ID value so that appropriate processing can be done based on whichever item was clicked. Unfortunately, ListView doesn't have a feature like this as far as I know.

Is there a straightforward solution? Preferably not using trial versions of additional downloadable products. A commonly-used NuGet package would be fine.


Show source
| c#   | .net   | winforms   2016-12-31 13:12 2 Answers

Answers to C# - ListBox / ListView to support both data binding and thumbnails ( 2 )

  1. 2016-12-31 13:12

    This is easily done in Blend for VS. In Blend click on properties for the ListBox. Click on the Items Property. On the bottom screen of the popup to the left of the "Add" button select other type. type image into the search textBox provided. Select image. On the image select source and add desired picture. The picture can also be added in C# by changing its Source property. I hope this helps.

  2. 2016-12-31 13:12

    You can create your own ThumbnailListBox by deriving it from ListBox:

    public class ThumbnailListBox : ListBox
    {
        public ThumbnailListBox()
        {
            DrawMode = DrawMode.OwnerDrawFixed;
            ItemHeight = 32;
        }
    
        ...
    }
    

    Then you must override OnDrawItem and draw your stuff. Note that you have to draw the text as well.

    protected override void OnDrawItem(DrawItemEventArgs e)
    {
        e.DrawBackground();
        if (e.Index >= 0 && e.Index < Items.Count) {
            var item = (MyItemType)Items[e.Index];
            StringFormat stringFormat = new StringFormat();
            stringFormat.Alignment = StringAlignment.Near;
            stringFormat.LineAlignment = StringAlignment.Center;
            var textRect = e.Bounds;
            textRect.X += 35;
            textRect.Width -= 35;
            using (var textBrush = new SolidBrush(e.ForeColor)) {
                e.Graphics.DrawString(item.Text, Font, textBrush, textRect, stringFormat);
            }
            Image img = item.GetThumbnail();
            if (img != null) {
                e.Graphics.DrawImage(img, 1, 1);
            }
        }
        e.DrawFocusRectangle();
    }
    

    In this example I assume that you are using Object-Binding to objects of a type MyItemType.


    If you have thumbnails of different sizes, you can set the DrawMode to DrawMode.OwnerDrawVariable and then override OnMeasureItem where you can specify a different height for every item.

    protected override void OnMeasureItem(MeasureItemEventArgs e)
    {
        if (e.Index >= 0 && e.Index < Items.Count) {
            var item = (MyItemType)Items[e.Index];
            e.ItemHeight = Math.Max(15, item.GetThumbnailHeight());
        }
    }
    

Leave a reply to - C# - ListBox / ListView to support both data binding and thumbnails

◀ Go back