Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set icon to subitem of listview using c#?

Tags:

c#

I have listview control. It's possible to choose imageindex from imagelist and set image to listview item but how can I set icon to listview subitem?

        listView1.Columns.Add("Objects");
        listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
        listView1.SmallImageList = imageList1;
        listviewitem = new ListViewItem("David", 1);
        listviewitem.SubItems.Add("John");
        this.listView1.Items.Add(listviewitem);
        listView1.View = View.Details;

I want to set image to subitem - named "John".

like image 990
Leri Gogsadze Avatar asked Sep 09 '17 08:09

Leri Gogsadze


1 Answers

You can only have one image for a ListViewItem and it has to be with the main ListViewItem (i.e. with SubItems[0].)

But you can change the display order, so you can display the image in any column.

listView1.Columns[0].DisplayIndex = 2;

enter image description here

But, of course you can also owner-draw the ListView and include images with any number of SubItems! This will take a few more lines of code (around a dozen) but it will allow you to style the ListView in pretty much any way you like..

Here is an example that has (random) images in all columns:

enter image description here

To get this result you need to..:

  • Set OwnerDraw = true for the LV
  • Set UseItemStyleForSubItems = false for all Items
  • Code all three Drawxxx events.
  • Decide on how to store the references to the 2nd (etc) image, since the SubItem class doesn't have an ImageIndex.

You can either use the Tag of the SubItem to hold the ImageIndex number or, if you don't need the Text, you can set the text so you can use it as index or even as Key into the ImageList.

Two of the events are simple:

private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
    e.DrawDefault = true;
}

private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
    e.DrawDefault = true;
}

The third one is where you actually do some drawing:

    private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
    {
        e.DrawBackground();
        Size sz = listView1.SmallImageList.ImageSize;
        int idx = 0;
        if (e.SubItem.Tag != null) idx = (int)e.SubItem.Tag;
        Bitmap bmp = (Bitmap)listView1.SmallImageList.Images[idx];
        Rectangle rTgt = new Rectangle(e.Bounds.Location, sz);
        bool selected = e.ItemState.HasFlag(ListViewItemStates.Selected);
        // optionally show selection:
        if (selected ) e.Graphics.FillRectangle(Brushes.CornflowerBlue, e.Bounds);

        if (bmp != null) e.Graphics.DrawImage(bmp, rTgt);

        // optionally draw text
        e.Graphics.DrawString(e.SubItem.Text, listView1.Font,
                              selected  ? Brushes.White: Brushes.Black,
                              e.Bounds.X + sz.Width + 2, e.Bounds.Y + 2);
    }

Of course you will want to restrict the drawing of images and maybe of Text to those columns you need.. Adding more checks should be simple..

like image 82
TaW Avatar answered Sep 19 '22 12:09

TaW