ListView does not display images after switching view mode

When I add items to a ListView in any mode except LargeIcon , the ListView stops showing images with a LargeImageList when it switches to LargeIcon . This situation persists until a new item is added to the ListView in LargeIcon mode.

Thus, the following sequence illustrates the problem:

  • create ListView , add column, set View to Details
  • create an ImageList , set ImageSize , assign it to ListView.LargeImageList
  • create a new ListViewItem , set it to ImageKey
  • create a new image, add it to ImageList with the given key
  • add ListViewItem to ListView
  • switch ListView mode to LargeIcon
    • Images are not displayed
  • repeat steps # 3 - # 6, now in LargeIcon mode
    • all images are displayed as expected

What am I still missing?

I tried the following:

  • Cancel ListView
  • LargeImageList before / after adding item (even via null )

Test code for those who like it more than words:

 public partial class Form1 : Form { int counter = 0; ImageList iList = new ImageList(); private string GetNewKey() { return counter++.ToString(); } private Image GetNewImage(Size size) { var bmp = new Bitmap(size.Width, size.Height); using (var gra = Graphics.FromImage(bmp)) { var rnd = new Random(); var lines = rnd.Next(1000); for (int l = 0; l < lines; ++l) { var pen = new Pen(Color.FromArgb(rnd.Next(256), rnd.Next(256), rnd.Next(256))); var p1 = new Point(rnd.Next(size.Width), rnd.Next(size.Height)); var p2 = new Point(rnd.Next(size.Width), rnd.Next(size.Height)); gra.DrawLine(pen, p1, p2); } } return bmp; } public Form1() { InitializeComponent(); iList.ImageSize = new Size(100, 100); listView.LargeImageList = iList; listView.Columns.Add("name"); } private void buttonAdd_Click(object sender, EventArgs e) { var key = GetNewKey(); var lvi = new ListViewItem() { Name = key, Text = "blabla", ImageKey = key, }; iList.Images.Add(key, GetNewImage(new Size(100, 100))); listView.Items.Add(lvi); } private void buttonClear_Click(object sender, EventArgs e) { listView.Items.Clear(); } private void buttonLarge_Click(object sender, EventArgs e) { listView.View = View.LargeIcon; } private void buttonDetails_Click(object sender, EventArgs e) { listView.View = View.Details; } } 

EDIT:

For those who will experience the same problem. After some experiments, there is at least a stupid inconvenience for a person:

Change ImageList , ListView somehow detects its change and reloads images for LargeIcon mode. Questions: how it detects the change and why it ignores the ImageList change after the mode change ...

  private void FixIt() { // Trigger a reload of the ListView.LargeImageList if (listView.View == View.LargeIcon) { var key = "Dummy image to be deleted right after its insertion..."; iList.Images.Add(key, new Bitmap(1, 1)); iList.Images.RemoveByKey(key); } } 

EDIT # 2: I also discovered some other funny features that ListView and related components have. You can check them in the answers to the question question 4097912 and question 23059678

+1
source share
1 answer

To solve your problem

You can avoid this by using ImageIndex instead of ImageKey to connect the ListView to the ImageList . So in your case buttonAdd_Click use:

  var lvi = new ListViewItem() { Name = key, Text = "blabla", //ImageKey = key, //Use ImageIndex and don't set both ImageIndex= Convert.ToInt32(key) //you could just use count++ }; 

The reason for this problem:

The reason for this is not clear to me, but I suppose it could be an error that when changing from Details to LargeIcon only checks ImageIndex by default, and if you set ImageKey t20> it will be set to -1 . Or maybe itโ€™s by design, I donโ€™t know (see the ImageKey section below), since you do not have a SmallImageList , so when changing to LargeIcon , ImageIndex is null or -1 and ImageKey ignored.

About ListViewItem.ImageIndex Property

The ImageKey and ImageIndex properties are mutually exclusive, that is, if one of them is set, the other is ignored. In addition, if you set the ImageKey property, the ImageIndex property is automatically set to -1. Alternatively, if you set the ImageIndex property, ImageKey is automatically set to an empty string ("").

About ListViewItem.ImageKey Property

If you use multiple image lists, you must place small and large versions of the image in the same index location in your respective image lists to represent large and large icons using the ListView control. When switching between views, the location of the image pointer in one list is used to search for the image in another list, regardless of the specified key value.

And you can somehow check this:

  • using existing code (use ImageKey )
  • set ImageIndex for any Item in your ListView in the buttonLarge_Click event buttonLarge_Click will show you this item image.
  • set ImageKey for any Item inside the buttonLarge_Click event buttonLarge_Click does not display this itme image.

eg:.

  private void buttonLarge_Click(object sender, EventArgs e) { listView.View = View.LargeIcon; //Set ImageIndex of Item 0 you could see its Icon. listView.Items[0].ImageIndex= 0 ; //set ImageKey will change nothing //listView.Items[0].ImageKey= "0" ; } 
+1
source

All Articles