TListView: Subitem order after adding a new column between existing during runtime

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.

Answers


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..


Need Your Help

How can we post ASCII art on Facebook wall?

ios facebook cocoa-touch ascii

In my app, I have a requirement to post the ASCII art from my iPhone app onto the facebook wall post. But the problem I face is that facebook font (Lucida Console) Changes the formatting of my ASCI...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.