Delphi Programming for Beginners - Lesson 5

TListView and TTreeView

Slowly we are learning about more complex components and doing more complex examples (we will talk about the most important component only). These 2 components are very useful and are used pretty often. You can find both implemented in Windows, as shown in the picture below:

Delphi Course

TTreeView is that tree on the left side (the appearance can be changed) and TListView is that list on the right.

TTreeView is used for visualising the tree structure (content of a disk, folders and subfolders etc.), whereas TListView is used for visualising a linear list. As shown in the picture, they are used in a combination where in a tree we pick an entity (folder, for example) and in the list we can see the content of this entity.

Both components are often used with TImageList for showing the appropriate icon for every item (so the folder has an icon of a folder, etc.).

Both of components have their own item editors, where particular items can be defined, but pretty often case is to fill items at runtime (for instance with content of the disc) and in design time determine column headers only (such as name, size, extension etc.).

The items editor for a tree is launched by a double-click or by choosing from a pop-menu on a component. In case of a list, an editor of columns or an editor of items can be launched.

Delphi Course

Delphi Course

Delphi Course

Important properties of TListView

Important one is ViewStyle, which determines a visual mode:

  • vsIcon - visualising in an icon mode
  • vsList - a simple list
  • vsSmallIcon - just like vsIcon, but small icons
  • vsReport - the most used mode, a list with columns

Connection with TImageList is provided by properties SmallImages, LargeImages and StateImages, where SmallIgames is the most important one, which are used in all modes but vsIcon.

Another important property is RowSelect which determines whether the selection is the whole line or just an item. But the most important one is Items which holds the list of items.

You can add items when the programme is running like this:


procedure TForm1.FormCreate(Sender: TObject);
 var
  lvItem: TListItem; // položka TListView
  i: Integer;
  tvItem: TTreeNode; // položka TTreeView
  j: Integer;
 begin
  lv1.Items.BeginUpdate;
  for i := 1 to 10 do //10 polozek do TListView
  begin
   lvItem := lv1.Items.Add;
   lvItem.Caption := 'Položka '+ IntToStr(i);
   lvItem.SubItems.Add('Sub'+IntToStr(i)); // druhý sloupec
  end;
  lv1.Items.EndUpdate;
  tv1.Items.BeginUpdate;
  for i := 1 to 10 do // 10 položek první úrovně
  begin
   tvItem := tv1.Items.Add(nil, 'Uzel '+IntToStr(i));
   for j := 1 to 5 do // pridame druhou uroven – 5 položek
   tv1.Items.AddChild(tvItem, 'sub'+ IntToStr(j));
   tvItem.Expanded := true; // rozbal uzel
  end;
  tv1.Items.EndUpdate;
 end;
Delphi Course

Calling BeginUpdate/EndUpdate isn’t obligatory but in case of updating more items it speeds up the whole process because it prohibits redrawing and calling different events. Ideally, the calling should be protected by try…finally, that is (because in case of a mistake, a redrawing wouldn’t be allowed):


BeginUpdate
 try
  …
 finally
  EndUpdate
 end
A practical example

Let’s make our very own File Explorer, that is, we have TTreeView on the left and TListView on the right. I’ll show you how to fill the tree, visualising items based on chosen entity will be your home work. The programme is attached, here’s the code.

After the start, the tree is filled with directories from constant csStart. In a real project the individual levels will load while unpacking, here we load them at once - even though it will take longe.r


procedure TForm1.FormCreate(Sender: TObject);
 var
  lvItem: TListItem;
  i: Integer;
  tvItem: TTreeNode;
  j: Integer;
 const
  csStart = 'c:\Windows\System32';
 begin
  tv1.Items.BeginUpdate;
  // mFillTreeLevel(nil, 'c:');
  mFillTreeLevel(tv1.Items.Add(nil, csStart), csStart );
  tv1.Items.EndUpdate;
 end;
 

The key method for loading one level is discussed here. It’s called a recursive method - it calls itself with different parameters step by step, as it goes through the disk. Combination of FindFirst, FindNext and FindClose will be used for reading the directory.


procedure TForm1.mFillTreeLevel(oParentNode: TTreeNode; const sPath:string);
 var
  sr: TSearchRec;
  oItem: TTreeNode;
 begin
  if FindFirst(sPath+'\'+'*.*', faAnyFile, sr) = 0 then
  begin
   repeat
    if (sr.Attr and faDirectory) > 0 then
    begin
    if (sr.name <> '.') and (sr.Name <> '..') then
     begin
      oItem := tv1.Items.AddChild(oParentNode, sr.Name);
      mFillTreeLevel(oItem, sPath + '\'+sr.Name );
     end;
    end;
   until FindNext(sr) <> 0;
  end;
  FindClose(sr);
 end;
A hint for homework:

  • You have always call filling ListView in tree’s OnChange
  • ListView is cleared by calling Iteams.Clear (after BeginUpdate!)
  • You can expend the programme in any way (icons, better files’ details,..)

Sample project regarding homework can be downloaded from here.

About the Author

Ing. Radek Červinka
Embarcadero MVP
Web: Delphi.cz
Twitter: @delphi.cz