TListView автоматически добавляет изображение из списка изображений в первый столбец моего TListView. Как мне избавиться от этого поведения?

Я использую Embarcadero C++ Builder XE8. У меня есть ListView и я добавляю столбцы с их элементами динамически. Мне нужен список изображений, потому что я хочу добавить изображение во 2-й столбец, также используя (ListItem->SubItemImages[0] = i;)

Похоже, что при добавлении этого списка изображений C++ Builder по умолчанию считает, что первичному столбцу также необходимо изображение, поэтому он по умолчанию прикрепляет 0-й элемент моего списка изображений ко всем элементам в этом столбце. Я не хочу, чтобы это произошло. Вместо этого под столбцом "ID" я просто хочу идентификатор, а не изображения. Как я могу это сделать?

Снимок экрана, показывающий, что происходит

Мой код:

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  const string firstName[] = {"Snowball", "Scavies", "Tinkerbell", "Fido", "Garfield", "Kobe"};
  const string lastName[] = {"M", "E", "O", "W", "W", "W"};
  TListColumn  *NewColumn;
  TListItem  *ListItem;
  TListView   *ListView = ListView1;

  ListView->SmallImages = ImageList1;

  ListView->ViewStyle = vsReport;
  NewColumn = ListView->Columns->Add();
  NewColumn->Caption = "ID";
  NewColumn = ListView->Columns->Add();
  NewColumn->Caption = "Node";
  NewColumn = ListView->Columns->Add();
  NewColumn->Caption = "First";
  for (int i = 0; i < sizeof( firstName ) / sizeof( firstName[0] ); i++)
  {
    char buffer[3];
    itoa(i,buffer,10);
    ListItem = ListView->Items->Add();
    ListItem->Caption = buffer;
    ListItem->SubItems->Add(firstName[i].c_str());
    ListItem->SubItems->Add(lastName[i].c_str());
    ListItem->SubItemImages[0] = i;
    //ListItem->ImageIndex = NULL;
  }
}

1 ответ

Решение

Когда вы добавляете элемент в просмотр списка, с которым связан ImageList, он будет предполагать, что вы намерены использовать эти изображения для самих элементов, и поэтому каждому добавленному элементу будет присвоен по умолчанию ImageIndex, равный 0 (первое изображение в списке изображений).,

Чтобы удалить изображение из самого элемента, все, что вам нужно сделать, это заменить значение по умолчанию ImageIndex, равное 0, на -1, что означает "нет изображения".

ListItem->ImageIndex = -1; 
ListItem->SubItemImages[0] = i;

Как отмечено в комментариях, это касается не рисования изображений рядом с заголовками элементов (столбец 0), но просмотр списка все равно оставит место для этих изображений, даже если ни одно из них не должно быть нарисовано:

Осталось места для несуществующих изображений

Есть два способа избежать этого:

  1. Не связывайте список изображений с представлением списка и используйте пользовательский рисунок для рисования любых подпунктов, требующих изображений.

  2. Установите ширину столбца от 0 до 0, чтобы эффективно скрыть этот столбец и рассматривать первый подпункт как заголовок элемента.

У каждого подхода есть компромиссы.

Первый требует дополнительной сложности пользовательского рисунка. Второй более простой, но означает, что вам нужно включить поведение RowSelect в представлении списка. Без этого подэлементы не могут использоваться для выбора элементов в списке и не рисуют с выделением выделения.

Это также означает, что при любой обработке событий и т. Д. Вы должны помнить, что Subitem[0] следует рассматривать как особый случай (элемент 'caption'):

ListView->RowSelect = true;

// ..

NewColumn = ListView->Columns->Add();
NewColumn->Caption = "Not Used";
NewColumn->Width   = 0;
NewColumn = ListView->Columns->Add();
NewColumn->Caption = "ID";

// ..

// No need to set ListItem->Caption since it is hidden

ListItem->SubItems->Add(buffer);  // subitem[0] = 'the item'
ListItem->SubItems->Add(firstName[i].c_str());
ListItem->SubItems->Add(lastName[i].c_str());
ListItem->SubItemImages[1] = i;

Существует также небольшая вероятность того, что какой-нибудь любознательный пользователь может изменить размер столбца [0] и обнаружить ваш скрытый секрет.:)

Разве это не то, что вы ищете?

Затем в TForm.OnCreate просто установите ListItem->Indent свойство до -1:

// in Pascal code
for lListItem in ListView1.Items do
  lListItem.Indent := -1;
Другие вопросы по тегам