Delphi Programming for Beginners - Lesson 5TListView 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:
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.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;
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):
A practical example
BeginUpdate try … finally EndUpdate end
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.
A hint for homework:
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;
- 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 AuthorIng. Radek Červinka