4

如果您在运行时在现有列之间添加新列,则子项索引与我假设的不同。

例如,在第二列和第三列之间添加新列后,列/子项如下所示:

colums[0] |  colums[1]   |  (new) columns[2] |  columns[3]
caption   |  subitems[0] |  subitems[2]      |  subitems[1]

但我会假设:

colums[0] |  colums[1]   |  (new) columns[2] |  columns[3]
caption   |  subitems[0] |  subitems[1]      |  subitem[2]

我需要能够在某些条件下动态更新子项的内容。这就是为什么我想依赖这样的假设,即 Column.Index = X 的列的子项位于 Item.SubItems[X-1]。

您认为这是默认和指定的行为吗?如果是这样,您会建议根据列更新子项。一种可能是保存属于最近添加的列的子项索引。

注意:Columns.Tag 属性已在使用中。

我正在使用 Delphi XE 和 XE2,但我需要与 Delphi 7 及更高版本兼容。

4

1 回答 1

3

您不需要保存索引位置,您可以随时询问列表视图控件本身列的原始位置:

procedure TForm1.Button1Click(Sender: TObject);
var
  ColumnOrder: array of Integer;
begin
  SetLength(ColumnOrder, ListView1.Columns.Count);
  ListView_GetColumnOrderArray(ListView1.Handle, ListView1.Columns.Count,
                               PInteger(ColumnOrder));


对于问题中的示例,ColumnOrder数组将包含 (0, 1, 3, 2)。如果我们要更新新插入的列(左起第三列)的子项,那么它的原始位置是'3'。代码示例:

var
  ColumnOrder: array of Integer;    
  SubIndex: Integer;
begin
  SetLength(ColumnOrder, ListView1.Columns.Count);
  ListView_GetColumnOrderArray(ListView1.Handle, ListView1.Columns.Count,
                               PInteger(ColumnOrder));

  SubIndex := ColumnOrder[2];    // We want to update 3rd column from left
                                 // (visually -> SubItems[1])

  // Test if the index is not 0, otherwise it holds an *item*,
  // not a subitem (the first column can change position too).
  if SubIndex > 0 then begin     
    Dec(SubIndex);               // VCL subitems are 0 based
    ListView1.Items[1].SubItems[SubIndex] := 'updated!';
  end;


请注意,如果您要添加列而不仅仅是重新排序现有列,则只有在您修复了另一个问题中的错误时,这才有效(如果没有,则再次提供列重新排序和列无论如何添加功能是不可能的)。


关于默认行为是否应如此,假设您有一个列表视图,您正在显示包含“名称”、“大小”、“日期”列的文件信息。作为开发人员,您不应该担心用户可能将“大小”列放在哪里,只需将信息放在“子项 [0]”中即可。此外,如果用户拖动“名称”列,它会从一个项目降级为一个子项目。

我认为期望项目/子项目将遵循它们各自的列是合乎逻辑的。

于 2011-11-30T16:38:52.970 回答