2014-04-11 1 views
1

При добавлении элемента (ов) к ListView в любом другом режиме, чем LargeIcon зрения, ListView остановки, показывающие изображения из LargeImageList, когда он переключается обратно на LargeIcon. Эта ситуация сохраняется до добавления нового элемента в ListView в режиме LargeIcon.ListView не показывает изображения после переключения режима просмотра

Таким образом, следующая последовательность иллюстрирует проблему:

  1. создать ListView, добавить столбец, установите View в Details
  2. создать ImageList, установить ImageSize, присвоить его ListView.LargeImageList
  3. создать новую ListViewItem, установите его ImageKey
  4. создать новое изображение, добавить его в ImageList с заданным ключом
  5. добавить ListViewItem для переключения ListView
  6. режим ListView к LargeIcon
    • изображения не показаны
  7. повторите шаги # 3 - # 6, теперь в режиме LargeIcon
    • все изображения показаны в порядке необходимости

Что точка я все еще не хватает?

Я попытался следующие:

  • Аннулируйте ListView
  • переназначить LargeImageList до/после добавления элемента (даже через null)

тестовый код для тех, кто больше, чем слова:

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:

Для тех, кто будет страдать той же проблемой. После некоторых экспериментов, есть по крайней мере, глупо бедняка обходной путь:

ImageList Изменить, то ListViewкаким-то образом обнаруживает его изменение и перезагружает изображения для режима LargeIcon. Вопросы: как обнаруживает изменения и почему ли это игнорирует ImageList после смены режима ...

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: Я также обнаружил некоторые другие забавные особенности в ListView и связанные с ним компоненты имеют. Вы можете проверить их в ответах question 4097912 и question 23059678

+0

Я думаю, вы не установили SmallImageList в список изображений, проверьте его – CuriousPen

+0

Правильно, я этого не сделал. Мне не нужны маленькие значки, просто большие или текстовые (подробности). Требуется ли SmallImageList для правильной работы режима LargeIcon? – sharpener

ответ

1

Чтобы решить вашу проблему

Вы могли бы избежать этого использованияКонтактная ImageIndex вместо ImageKey соединить ваш ListView с ImageList. Так что в вашем использовании buttonAdd_Click событий:

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++ 
     }; 

Причина этой проблемы:

Причина этого не ясна для меня, но я предполагаю, что это может быть ошибка, что при переходе от Details к LargeIcon, он проверяет только ImageIndex по умолчанию, и если вы установили ImageKey, то ImageIndex будет установлен в -1. Или может быть это по дизайну, я не знаю (см. Ниже раздел ImageKey), так как у вас нет SmallImageList, поэтому при смене на LargeIcon вид ImageIndex - null или -1, а ImageKey игнорируется.

О ListViewItem.ImageIndex Property

ImageKey и свойства ImageIndex являются взаимоисключающими, то есть, если он установлен, другой игнорируется. Кроме того, если вы устанавливаете свойство ImageKey, свойство ImageIndex автоматически устанавливается в -1. Кроме того, если вы установите свойство ImageIndex, ImageKey автоматически устанавливается на пустую строку ("").

О ListViewItem.ImageKey Property

Если вы используете несколько списков изображений, для малого и большого просмотра значков, с помощью элемента управления ListView, вы должны поместить маленькие и большие версии изображения на тот же индекс местоположение в их соответствующих списках изображений. При переключении между представлениями местоположение индекса изображения в одном списке используется для поиска изображения в другом списке, независимо от указанного значения ключа.

И это как-то может быть проверено:

  • используя существующий код (используйте ImageKey)
  • установить ImageIndex для любого Item в вашем listView внутри обработчика buttonLarge_Click событий покажут, что деталь образ.
  • комплект ImageKey для любого Item в обработчике события buttonLarge_Click не покажет, что изображение itme.

например.:

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" ; 
     } 
+0

Ницца, спасибо. Проблема с индексом следующая: каждый раз, когда вы удаляете элемент из ListView, вам нужно перестроить индексы, иначе вы получите неправильные изображения, назначенные элементам ListView ... – sharpener

+0

@sharpener, я полагаю, вы имеете в виду, что когда вы удаляете элемент из «ImageList», вам нужно перестроить индексы? – Bolu

+0

Если вы удаляете элемент из «ListView», вам не нужно удалять связанное изображение из «ImageList», поэтому вам не нужно ничего перестраивать. – Bolu

Смежные вопросы