ListView Control

The ListView control provides a flexible way to represent more than one piece of information about objects. It provides four views of data inside the control with columns for each piece of information and choices of image or icon for visual representation.

Having placed a ListView control on a form there are two editors available for developing it. One is the Columns Editor, which is used to define columns of the ListView:

The other is the Items Editor, which can be used to set up items:

Typically, two Image Lists are added to a ListView application, one for the small icons and one for the larger ones.

In the following example the ListView is enhanced with two Image Lists, edit boxes and buttons to add items and sub-items, menus to provide control over views and fonts, and file dialogs to provide open and save operations.

Here is the Object Tree for the form:

Here are the property settings:

 

The menu has these options:

Open:

procedure TForm1.Open1Click(Sender: TObject);
var
 list: TStringList; //list of TStrings
 NewItem: TListItem; //individual member of a TListView
 i: integer;
begin
 if opendialog1.Execute then
 begin
  NewItem:=nil;
  ListView1.Items.Clear;
  list:=TStringList.Create;
  try
   list.LoadFromFile(opendialog1.FileName);
   for i:= 0 to list.count - 1 do
   if list[i][1]=#9 then  //tab character
    newitem.SubItems.add (trim(list[i]))
   else if list[i][1]='@' then
    newitem.ImageIndex:=strtointdef(list[i][2],0)
   else
   begin
    NewItem := Listview1.Items.add;
    NewItem.Caption:=list[i];
   end;
  finally
   list.Free;
  end;
 end;
end;

The ListView does not have its own open or save methods so a TStringList is used instead.

Save:

procedure TForm1.Save1Click(Sender: TObject);
var
 i,j: integer;
 list:TStringList;
begin
 if savedialog1.Execute then
 begin
  list:=TStringList.Create;
  try
   for i:=0 to listview1.Items.Count - 1 do
   begin
    list.add(listview1.Items[i].Caption);
    list.add('@'+inttostr(listview1.Items[i].ImageIndex));
    for j:= 0 to listview1.Items[i].subitems.count - 1 do
     list.Add(#9 + listview1.Items[i].SubItems[j]);
   end;
   list.SaveToFile(savedialog1.FileName);
  finally
   list.free;
  end;
 end;
end;

(Both these routines based on code in Marco Cantu's book on Delphi 6.) A typical file for this arrangement would look like this:

Graham Greene
@0
    English
    Novelist
    Quiet American
George Eliot
@0
    English
    Novelist
    Mill on Floss
Thomas Eliot
@0
    American
    Poet/Essayist
    Waste Land

This is simply a text file with @n representing the image index and the sub-fields indented by a tab character.

The code for the Add Node button:

procedure TForm1.Button1Click(Sender: TObject);
begin
 listview1.AddItem(edit1.text,sender);
end;

The code for the Delete Node button:

procedure TForm1.Button5Click(Sender: TObject);
begin
 listview1.DeleteSelected;
end;

The code for the Add Subnode button:

procedure TForm1.Button2Click(Sender: TObject);
begin
 if listview1.Selected <> nil then
  listview1.Selected.SubItems.Add(edit2.text);
end;

The code for the View buttons:

procedure TForm1.List1Click(Sender: TObject);
begin
 listview1.ViewStyle:=vsList;
end;

The code for each style is:

listview1.ViewStyle:=vsReport;

listview1.ViewStyle:=vsIcon;

listview1.ViewStyle:=vsSmallIcon;

The code for the font changes:

procedure TForm1.Small1Click(Sender: TObject);
begin
 listview1.Font.Size:=8;
end;

The code for displaying and removing check boxes:

procedure TForm1.CheckBoxes1Click(Sender: TObject);
begin
 listview1.Checkboxes:=not listview1.Checkboxes;
end;

Additional functionality is provided at run-time. Clicking on the left mouse button over the an item (not a sub-item) produces a display of the contents of that node and its sub-nodes, while clicking the right button allows the node to edited.

procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
 description: string;
  i:integer;
begin
 if listview1.Selected <> nil then
 begin
  if button = mbLeft then
  begin
   description:=listview1.Columns[0].Caption + #9 +
   listview1.Selected.Caption + #13;
   for i:= 1 to listview1.Selected.SubItems.Count do
    description := description + listview1.Columns[i].Caption
      + #9 + listview1.Selected.subitems[i-1] + #13;
    showmessage(description);
  end
   else if button=mbRight then
    listview1.Selected.EditCaption;
 end;
end;

Note that this routine was created by double-clicking in the OnMouseDown event in the Events column of the Object Inspector, with the ListView selected.

Another run-time feature is that the display can be sorted by clicking on any column header:

procedure TForm1.ListView1ColumnClick(Sender: TObject;
Column: TListColumn);
begin
 SortColumn :=Column.Index;
 listview1.AlphaSort;
end;

procedure TForm1.ListView1Compare(Sender: TObject; Item1, Item2: TListItem;
Data: Integer; var Compare: Integer);
begin
 if nSortCol = 0 then
  Compare := CompareStr (Item1.Caption, Item2.Caption)
 else
  Compare := CompareStr (Item1.SubItems[nSortCol - 1], Item2.SubItems[SortColumn - 1]);
end;

Here is the application running, with a text file loaded and check boxes displayed:

This is a flexible tool with many much potential for creative use. Various actions could be taken on the clicking of objects in the list.

Back to Tutorial

Back to Palette List