Delphi TListView自动将imagelist中的图像附加到my TListView的第一列。我如何摆脱这种行为? 我使用的是NavaCabro的C++ Builder XE8。我有一个ListView,正在动态添加列及其项。我需要一个imagelist,因为我想使用(ListItem->SubItemImages[0]=I;)将图像添加到第二列 似乎通过添加这个IVILLIST,默认的C++ Builder认为主列也需要一个图像,所以它默认将我的图像列表的零个元素附加到该列中的所有项。我不希望这种情况发生。相反,在“ID”列下,我只想要ID,而不是任何图像。我该怎么做

Delphi TListView自动将imagelist中的图像附加到my TListView的第一列。我如何摆脱这种行为? 我使用的是NavaCabro的C++ Builder XE8。我有一个ListView,正在动态添加列及其项。我需要一个imagelist,因为我想使用(ListItem->SubItemImages[0]=I;)将图像添加到第二列 似乎通过添加这个IVILLIST,默认的C++ Builder认为主列也需要一个图像,所以它默认将我的图像列表的零个元素附加到该列中的所有项。我不希望这种情况发生。相反,在“ID”列下,我只想要ID,而不是任何图像。我该怎么做,delphi,c++builder,c++builder-xe8,Delphi,C++builder,C++builder Xe8,我的代码: void\uu fastcall TForm1::FormCreate(TObject*Sender) { const string firstName[]={“雪球”、“斯卡维斯”、“小叮当”、“菲多”、“加菲猫”、“神户”}; 常量字符串lastName[]={“M”、“E”、“O”、“W”、“W”、“W”}; TListColumn*NewColumn; TListItem*列表项; TListView*ListView=ListView1; ListView->SmallIm

我的代码:

void\uu fastcall TForm1::FormCreate(TObject*Sender)
{
const string firstName[]={“雪球”、“斯卡维斯”、“小叮当”、“菲多”、“加菲猫”、“神户”};
常量字符串lastName[]={“M”、“E”、“O”、“W”、“W”、“W”};
TListColumn*NewColumn;
TListItem*列表项;
TListView*ListView=ListView1;
ListView->SmallImages=ImageList1;
ListView->ViewStyle=vsReport;
NewColumn=ListView->Columns->Add();
NewColumn->Caption=“ID”;
NewColumn=ListView->Columns->Add();
新建列->标题=“节点”;
NewColumn=ListView->Columns->Add();
新建列->标题=“第一”;
对于(int i=0;iItems->Add();
ListItem->Caption=缓冲区;
ListItem->SubItems->Add(firstName[i].c_str());
ListItem->SubItems->Add(lastName[i].c_str());
ListItem->SubItemImages[0]=i;
//ListItem->ImageIndex=NULL;
}
}

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

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

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

有两种方法可以避免这种情况:

  • 不要将图像列表与listview关联,并使用自定义图形绘制任何需要图像的子项

  • 将列0的列宽设置为0,以有效隐藏该列,并将第一个子项视为项标题

  • 每种方法都有权衡

    第一个要求增加自定义图形的复杂性。第二个更简单,但意味着您需要在列表视图上启用RowSelect行为。否则,子项将无法用于选择列表中的项,并且不会使用任何选择高亮显示进行绘制

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


    一些好奇的用户调整[0]列的大小并发现您隐藏的秘密的可能性也很小

    以下不是你想要的吗

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

    // in Pascal code
    for lListItem in ListView1.Items do
      lListItem.Indent := -1;
    

    欢迎来到Stack Overflow,感谢分享您的故事。你有问题吗?如果是这样,请在你的帖子中明确你想要什么。@RobKennedy谢谢你的关注。修正了这项工作,但现在只有一个空白框占据了图像所在的空间。不管怎么说,要摆脱这个问题?我想问题是,因为有一个图像列表关联,假设您的项目将有图像,所以空间留给一个。我认为避免这种情况的唯一方法是不要将imagelist与listview关联,而是使用自定义绘图来绘制子项。您不需要所有者绘图来解决此问题。在
    vsReport
    模式下,分配图像列表时,第0列用于显示
    TListItem.ImageIndex
    (即使它是-1)。因此,只需添加但隐藏列0(将其
    宽度设置为0),然后为ID添加一个单独的列(您必须使用
    ListItem->SubItems[0]
    而不是
    ListItem->Caption
    来保存ID值)。@Remy一个好主意,只要您愿意使用RowSelect=true,因为第一个子项的行为方式与
    列[0]
    不同。特别是,如果没有RowSelect,子项是不可选择的,如果需要将子项[0]视为特殊情况子项(而不是简单的项处理与子项处理),则可能会使事件处理复杂化。但是RowSelect通常是可以接受的,在某种程度上,它可能是默认值,但它不是,也可能并不总是可取的@LucaGuarro您可以对ListView进行子类化,以拦截来自其头控件的通知。为列0返回TRUE以防止调整大小。您也可以考虑让子类丢弃试图直接调整列宽度的消息。非常感谢!
    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;
    
    // in Pascal code
    for lListItem in ListView1.Items do
      lListItem.Indent := -1;