TListView 自动将图像列表中的图像附加到我的 TListView 的第一列。我如何摆脱这种行为?
TListView automatically appends image in imagelist to first column of my TListView. How do I get rid of this behavior?
我正在使用 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;
}
}
当您将项目添加到具有 ImageList 关联的列表视图时,它将假设您的意图是将这些图像用于项目本身,因此添加的每个项目都将是分配了默认 ImageIndex 0(图像列表中的第一个图像)。
要从项目本身中删除图像,您需要做的就是将 0 的默认 ImageIndex 替换为 -1,表示"no image".
ListItem->ImageIndex = -1;
ListItem->SubItemImages[0] = i;
如评论中所述,这涉及不在项目标题(第 0 列)旁边绘制图像,但列表视图仍将为这些图像留出空间,即使要绘制 none 也是如此:
有两种方法可以避免这种情况:
不要将图像列表与列表视图相关联,并使用自定义绘图绘制任何需要图像的sub-items。
将第 0 列的列宽设置为 0 以有效隐藏该列并将第一个 sub-item 视为项目标题。
每种方法都有 trade-offs.
第一个要求增加自定义绘图的复杂性。第二个更直接,但意味着您需要在列表视图上启用 RowSelect 行为。否则,sub-items 无法用于列表中的 select 项,也不会使用任何 selection 高光进行绘制。
这也意味着在任何事件处理等中你必须记住将 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;
我正在使用 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;
}
}
当您将项目添加到具有 ImageList 关联的列表视图时,它将假设您的意图是将这些图像用于项目本身,因此添加的每个项目都将是分配了默认 ImageIndex 0(图像列表中的第一个图像)。
要从项目本身中删除图像,您需要做的就是将 0 的默认 ImageIndex 替换为 -1,表示"no image".
ListItem->ImageIndex = -1;
ListItem->SubItemImages[0] = i;
如评论中所述,这涉及不在项目标题(第 0 列)旁边绘制图像,但列表视图仍将为这些图像留出空间,即使要绘制 none 也是如此:
有两种方法可以避免这种情况:
不要将图像列表与列表视图相关联,并使用自定义绘图绘制任何需要图像的sub-items。
将第 0 列的列宽设置为 0 以有效隐藏该列并将第一个 sub-item 视为项目标题。
每种方法都有 trade-offs.
第一个要求增加自定义绘图的复杂性。第二个更直接,但意味着您需要在列表视图上启用 RowSelect 行为。否则,sub-items 无法用于列表中的 select 项,也不会使用任何 selection 高光进行绘制。
这也意味着在任何事件处理等中你必须记住将 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;