If you add a new column between existing columns during runtime, the subitem indices are not like I'ld assume.
e.g. after adding a new column between the second and third column the columns/subitems look like this:
colums[0] | colums[1] | (new) columns[2] | columns[3]
caption | subitems[0] | subitems[2] | subitems[1]
but i would assume:
colums[0] | colums[1] | (new) columns[2] | columns[3]
caption | subitems[0] | subitems[1] | subitem[2]
I need to be able to dynamically update the subitem's content under some conditions. That's why I would like to rely on the assumption, that the subitem for a column with Column.Index = X is at Item.SubItems[X-1].
Do you think this is a default and designated behavior? If so, what would you suggest for updating the subitems according to the columns. A possibility might be saving the subitem index that belongs to the recently added columns.
Note: The Columns.Tag-property is already in use.
I`m using Delphi XE and XE2, but I need to be compatible with Delphi 7 and higher.
You don't need to save index positions, you can always ask the list view control itself the columns' original position:
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));
For the example in the question, the ColumnOrder
array will hold (0, 1, 3, 2). If we want to update the subitem of the newly inserted column (3rd column from left), then its original position is '3'. Code example:
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;
Note that if you're adding columns and not just re-ordering existing ones, this will only work if you have a fix for the bug in the other question (then again if you don't, providing both column re-ordering and column adding functionality is not possible at all anyway).
Regarding if the default behavior is as it should be, suppose you have a list view which you're displaying file information having columns 'name', 'size', 'date'. As a developer you shouldn't be worrying about where a user might have put the 'size' column, just put the information to 'SubItems[0]'. Furhermore, what if the user drags the 'name' column, will it demote from being an item to a subitem.
I'd think it is only logical to expect that items/subitems would follow their respective columns..