2

我正在使用 Embarcadero 的 C++ Builder XE8。我有一个 ListView 并正在动态添加列及其项目。我需要一个图像列表,因为我想使用 (ListItem->SubItemImages[0] = i;) 将图像添加到第二列

似乎通过添加此图像列表,默认情况下 C++ Builder 认为主列也需要图像,因此默认情况下它将我的图像列表的第 0 个元素附加到该列中的所有项目。我不希望这种情况发生。相反,在“ID”列下,我只想要 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;
  }
}
4

2 回答 2

7

当您将项目添加到具有关联ImageList的列表视图时,它将假定您的意图是将这些图像用于项目本身,因此添加的每个项目将被分配一个默认的ImageIndex 0(图像列表中的第一个图像) .

要从项目本身中删除图像,您只需将默认的ImageIndex 0替换为-1,表示“无图像”。

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

如评论中所述,这涉及不绘制项目标题(第 0 列)旁边的图像,但列表视图仍将为这些图像留出空间,即使不绘制任何图像:

留给不存在的图像的空间

有两种方法可以避免:

  1. 不要将图像列表与列表视图相关联,并使用自定义绘图来绘制任何需要图像的子项。

  2. 将 Column 0 的列宽设置为 0 以有效隐藏该列并将第一个子项视为项标题。

每种方法都有取舍。

第一个需要增加自定义绘图的复杂性。第二个更直接,但意味着您需要在列表视图上启用RowSelect行为。没有它,子项目不能用于选择列表中的项目,也不能使用任何选择突出显示。

这也意味着在任何事件处理等中,您必须记住将Subitem[0]视为特殊情况(项目“标题”):

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;

一些好奇的用户也极有可能调整 column[0]的大小并发现您隐藏的秘密。:)

于 2017-04-10T22:00:51.070 回答
3

以下内容不是您要找的吗?

TItem 没有图像空间的标题

然后,在 TForm.OnCreate 中,只需将ListItem->Indent属性设置为 -1:

// in Pascal code
for lListItem in ListView1.Items do
  lListItem.Indent := -1;
于 2019-09-16T18:31:16.873 回答