If you create a node and add it to a branch that already contains another node, the new node is referred to as a sibling to the existing child node. To create a new node that would be a sibling to an existing node, you can call the TTreeNodes::Add() method we used to create the root node. If you want to specify that the new node would be a sibling to an existing node, pass the existing node as the first argument to this method. Here is an example: //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { TTreeView* tvwCountries = new TTreeView(this); tvwCountries->Parent = this; tvwCountries->Left = 10; tvwCountries->Top = 12; tvwCountries->Width = 220; tvwCountries->Height = 90; TTreeNode *nodRoot = tvwCountries->Items->Add(NULL, "World"); TTreeNode *nodAfrica = tvwCountries->Items->AddChild(nodRoot, "Africa"); tvwCountries->Items->Add(nodAfrica, "America"); tvwCountries->Items->Add(nodAfrica, "Asia"); tvwCountries->Items->Add(nodAfrica, "Europe"); } //---------------------------------------------------------------------------
Notice that America, Asia, and Europe are siblings to Africa, whose node was passed as the first argument to the Add() method. When you call the TreeNodes::Add() method to create a node, the new branch is added at the end of the list of its siblings. If you want, you can add a new child somewhere in the tree. To do this, you would call the TreeNode::Insert() method. Its syntax is: TTreeNode* __fastcall Insert(TTreeNode* Node, const AnsiString S); The first argument to this method is a reference to the node that will the sibling to the new node. The second argument is the text that the new node will display. To perform the same operation, you can call the TTreeNodes::InsertNode() method. Its syntax is: TTreeNode* __fastcall InsertNode(TTreeNode* Node, TTreeNode* Sibling, const AnsiString S, void * Ptr);
Besides looking at a node, probably the primary action a user performs on a tree is to select an item. To select a node in the tree, the user can click it. To programmatically select a node, assign its reference to the TreeView::Selected property: __property Comctrls::TTreeNode * Selected = {read=GetSelected,write=SetSelected}; Here is an example: //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { TTreeView* tvwCountries = new TTreeView(this); tvwCountries->Parent = this; tvwCountries->Left = 12; tvwCountries->Top = 12; tvwCountries->Width = 220; tvwCountries->Height = 90; TTreeNode *nodRoot = tvwCountries->Items->Add(NULL, "World"); TTreeNode *nodAfrica = tvwCountries->Items->AddChild(nodRoot, "Africa"); TTreeNode *nodAmerica = tvwCountries->Items->Add(nodAfrica, "America"); tvwCountries->Items->Add(nodAfrica, "Asia"); tvwCountries->Items->Add(nodAfrica, "Europe"); tvwCountries->Selected = nodAmerica; } //---------------------------------------------------------------------------
After selecting a node, the tree view indicates the item selected by highlighting it. In the above picture, the America node is selected.
By default, the user can select only one item from a time in the tree view. If you want to user to be able to select more than one node, set the TTreeView::MultiSelect property to true: __property bool MultiSelect = {read=FMultiSelect,write=SetMultiSelect}; Its default value is false. If you allow the user to select more than one node, you can then control how a multiple selection can be performed. This is done using the TTreeView::MultiSelectStyle property: __property System::Set<Comctrls::TMultiSelectStyles,0,3> MultiSelectStyle = { read=FMultiSelectStyle, write=SetMultiSelectStyle }; Whether the user selects one or more items, the list of selected nodes is stored in the TTreeView::Selections property, which is a collection: __property Comctrls::TTreeNode * Selections = {read=GetSelection}; Each member of this collection is an object of type TTreeNode. When only one node is selected, which is usually the case, you can get its reference from its index of the Selections property. The code to get this information would be as follows: TTreeNode *nodSel = tvwCountries->Selections[0]; If you had allowed the user to select more than one node, you can get a reference for each using its index in the Selected property.
After locating a node, the user may want to change its text. To change the string of a node, it must be put to edit mode. To do this, you can call the TTreeNodes::BeginUpdate() method. Its syntax is: void __fastcall BeginUpdate(void); When a node is in edit mode, the caret blinks in its edit box section. The user can then type a new string or edit the existing string. After setting the (new) string, the user can press Enter or may click somewhere. At this time, you need to indicate that the user has finished this operation. To do this, you can call the TTreeNodes::EndUpdate() method. Its syntax is: void __fastcall EndUpdate(void); Just before this method, you can check the content of the string that was added or edited. This allows you to accept or reject the change.
To get a reference to the top most node of the tree view, you can access the value of the TTreeView::TopItem, which produces a TTreeNode object. As mentioned already, the nodes of a tree view are stored in a collection of type TTreeNodes. Every time you create a new node, it occupies a position inside the tree. Each node is represented by the Item indexed property of this collection and each item is of type TTreeNode. Besides the Item property, the [] operator is overloaded in the TTreeNodes class to allow you to access any node using its index. The first node of the tree has an index of 0 in the TTreeNodes::Item[] collection. Another technique you can use to get a reference to the first item is by calling the TTreeNodes::GetFirstNode() method. Its syntax is: TTreeNode* __fastcall GetFirstNode(void); The second node has an index of 1 in the TTreeNodes::Item[] collection and so on. You can use this property to access any node in the tree. Another technique you can use to get a reference to the first item is by calling the TTreeNodes::GetFirstNode() method. Its syntax is: TTreeNode* __fastcall GetFirstNode(void); The children of a node are stored in its TTreeNode::Item[] property, which is a collection. To get a reference to the first child of a node, you can access the item stored in TTreeNode::Item[0]. An alternative is to call its TTreeNode::GetFirstChild() method. Its syntax is: TTreeNode* __fastcall getFirstChild(void); In the same way, the TTreeNode class provides other methods to access the last child (GetLastChild()), the next sibling (GetNextSibling()), the next child (GetNextChild()), etc, nodes. Another technique you can use to locate a node consists of using some coordinates. To do this, you can call the TreeView::GetNodeAt() method. Its syntax is: TTreeNode* __fastcall GetNodeAt(int X, int Y); To use this method, you must know the location or the x and y coordinates of the node. If you provide valid argumentation to this method, it returns a reference to the TTreeNode located at the argument.
When a tree contains a few nodes, the user may want to delete some of them, for any reason. To remove a node, you can call the TTreeNodes::Delete() method. Its syntax is: void __fastcall Delete(TTreeNode* Node); This method expects a reference to the node you want to remove. If you are already at that node and you want to remove it, you can call the TTreeNode::Delete() method. Its syntax is: void __fastcall Delete(void); One of the characteristics of a tree in the real world is that, if you cut a branch, the other branches attached to it and their leaves are cut too. In the same way, if you call any of these Delete() methods to delete a node, its children would be deleted too. If you want to remove (only) the children of an item, you can call its TTreeNode::DeleteChildren() method. Its syntax is: void __fastcall DeleteChildren(void); To remove all nodes of a tree view, you can call the TTreeNodes::Clear() method. Its syntax is: void __fastcall Clear(void); This method is used to get rid of all nodes of a tree.
In order to select an item, the user must click it or navigate to it using the keyboard. Alternative, if you want, you can cause the item to be underlined when the mouse passes over it: To produce this effect, you can set to true the TTreeView::HotTrack Boolean property: __property bool HotTrack = {read=FHotTrack,write=SetHotTrack}; Its default value is false. Here is an example of using it: //---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
TTreeView* tvwCountries = new TTreeView(this);
tvwCountries->Parent = this;
tvwCountries->Left = 12;
tvwCountries->Top = 12;
tvwCountries->Width = 220;
tvwCountries->Height = 90;
tvwCountries->HotTrack = True;
TTreeNode *nodRoot = tvwCountries->Items->Add(NULL, "World");
TTreeNode *nodAfrica = tvwCountries->Items->AddChild(nodRoot, "Africa");
TTreeNode *nodAmerica = tvwCountries->Items->Add(nodAfrica, "America");
tvwCountries->Items->Add(nodAfrica, "Asia");
tvwCountries->Items->Add(nodAfrica, "Europe");
}
//---------------------------------------------------------------------------
As mentioned already, a tree view appears as a list of items arranged like a tree. This implies a relationship of parent-child between two items in the control. To indicate this relationship between two nodes, a line is drawn from one to another. Based on this, a line from a node on top to another node under it indicates that the one on top is the parent to the one under it. The presence or absence of the lines among related nodes is controlled by the TTreeView::ShowLines Boolean property. By default, this property is set to true. If this property is set to false, the lines among the nodes would not display. Here is an example: //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { TTreeView* tvwCountries = new TTreeView(this); tvwCountries->Parent = this; tvwCountries->Left = 10; tvwCountries->Top = 12; tvwCountries->Width = 220; tvwCountries->ShowLines = false; TTreeNode *nodRoot = tvwCountries->Items->Add(NULL, "World"); TTreeNode *nodContinent = tvwCountries->Items->AddChild(nodRoot, "Africa"); tvwCountries->Items->Add(nodContinent, "America"); tvwCountries->Items->Add(nodContinent, "Asia"); tvwCountries->Items->Add(nodContinent, "Europe"); } //---------------------------------------------------------------------------
If you create a tree that has more than one root, a line is drawn among those root nodes. Here is an example: The presence or absence of this type of line is controlled by the TTreeView::ShowRoot Boolean property: __property bool ShowRoot = {read=FShowRoot,write=SetRootStyle}; Its default value is true. If you set its value to false, these lines would not appear.
Indentation is the ability for a child node to be aligned to the right with regards to its parent. The general distance from the left border of the parent to the left border of the children is partially controlled by the TTreeView::Indent property which is an integer. If the default distance doesn't suit you, you can change it by assigning a positive number to the control's Indent property.
When the user clicks an item, that node becomes highlighted for the length of its string. If you want, you can show the highlighting on the selected node but from the left to the right borders of the tree view. To support this, the TCustomTreeView class provides the RowSelect Boolean property: __property int Indent = {read=GetIndent,write=SetIndent}; The default value of this property is False. For the TTCustomTreeView::RowSelect property to work, the ShowLines property must be set to False. Here is an example: //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { TTreeView* tvwCountries = new TTreeView(this); tvwCountries->Parent = this; tvwCountries->Left = 12; tvwCountries->Top = 12; tvwCountries->Width = 220; tvwCountries->Height = 90; tvwCountries->ShowLines = False; tvwCountries->RowSelect = True; TTreeNode *nodRoot = tvwCountries->Items->Add(NULL, "World"); TTreeNode *nodAfrica = tvwCountries->Items->AddChild(nodRoot, "Africa"); TTreeNode *nodAmerica = tvwCountries->Items->Add(nodAfrica, "America"); tvwCountries->Items->Add(nodAfrica, "Asia"); tvwCountries->Items->Add(nodAfrica, "Europe"); } //---------------------------------------------------------------------------
We saw that, to select an item, the user can click it. If the user clicks another control, the node that was selected in the tree view loses its highlighting because the control has lost focus. When the focus moves to another control, if you want the selected node of the tree view to preserve its highlighting, set to false the TTreeView::HideSelection Boolean property: __property bool HideSelection = {read=FHideSelection,write=SetHideSelection}; Its default value is true.
In previous sections, we saw that some nodes have children and some don't. When a node has at least one child, the node indicates this by displaying a + button. If the user clicks the + button, the node expands, displays a list of its children, and the button becomes -. The presence or absence of the + and - buttons is controlled by the TTreeView::ShowButtons Boolean property: __property bool ShowButtons = {read=FShowButtons,write=SetButtonStyle}; By default, this property is set to true. If you don't want the parent nodes to display the + or - button, set this property to false.
When a node displays a + button and the user clicks that button, the node displays its child(ren). This action is referred to as expanding the node. To programmatically expand a node, call its TTreeNode::Expand() method. Its syntax is: void __fastcall Expand(bool Recurse); This method can be called to expand the node that calls it. If you want to expand only the node but not its children that have their own children, pass the Recurse argument as false. To expand a node and its children that have nodes, pass the argument as true. To find out if a node is expanded, check the value of its TTreeNode::Expanded property: __property bool Expanded = {read=GetExpanded,write=SetExpanded}; To expand other nodes of the tree view, the user can continue clicking each node that has a + button as necessary. To programmatically expand all nodes of a tree view, call its TTreeView::FullExpand() method. Its syntax is: void __fastcall FullExpand(void); If a node is displaying a - button, it indicates that it is showing the list of its children. To hide the list, the user can click the - button. This action is referred to as collapsing the node. To programmatically collapse a node, call its TTreeNode::Collapse() method whose syntax is: void __fastcall Collapse(bool Recurse); If you want to collapse only the node but not its children that are already expanded, pass the argument as false. If you want to collapse the node and its children that have their own children, pass the argument as true. The user can continually click the - button of each node that is expanded to collapse them. To programmatically collapse all nodes of a tree view, call its TTreeView::FullCollapse() method. Its syntax is: void __fastcall FullCollapse();
Besides the strings (and some small pictures as we will see later), the nodes of a tree view can display a check box on their left side. To display check boxes on the items of a tree view, call the SetWindowLong() function and specify that you want to add the TVS_CHECKBOXES style. This can be done as follows: //--------------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { TTreeView* tvwCountries = new TTreeView(this); tvwCountries->Parent = this; tvwCountries->Left = 12; tvwCountries->Top = 12; tvwCountries->Width = 140; tvwCountries->Height = 270; LONG GWLTreeView = GetWindowLong(tvwCountries->Handle, GWL_STYLE); SetWindowLong(tvwCountries->Handle, GWL_STYLE, GWLTreeView | TVS_CHECKBOXES); TTreeNode *nodRoot = tvwCountries->Items->Add(NULL, "World"); TTreeNode *nodAfrica = tvwCountries->Items->AddChild(nodRoot, "Africa"); TTreeNode *nodAmerica = tvwCountries->Items->AddChild(nodRoot, "America"); tvwCountries->Items->AddChild(nodRoot, "Asia"); TTreeNode *nodEurope = tvwCountries->Items->AddChild(nodRoot, "Europe"); tvwCountries->Items->AddChild(nodAfrica, "Senegal"); tvwCountries->Items->AddChild(nodAfrica, "Botswana"); tvwCountries->Items->AddChild(nodAfrica, "Ghana"); tvwCountries->Items->AddChild(nodAfrica, "Morocco"); tvwCountries->Items->AddChild(nodAmerica, "Canada"); tvwCountries->Items->AddChild(nodAmerica, "Jamaica"); tvwCountries->Items->AddChild(nodAmerica, "Colombia"); tvwCountries->Items->AddChild(nodEurope, "Italy"); tvwCountries->Items->AddChild(nodEurope, "Greece"); tvwCountries->Items->AddChild(nodEurope, "Spain"); tvwCountries->Items->AddChild(nodEurope, "England"); } //---------------------------------------------------------------------------
If you equip the nodes with check boxes, the user can click an item to select it independently of the check box. The user can also click the check box, which would place a check mark in the box. Here are examples:
Each of the nodes we have used so far displayed text. To enhance the appearance of a node, besides its text, you can display a small icon to the left of its string. To do this, you must first create a list of images and store them in a TImageList object. After creating a tree view, if you plan to display an icon next to its nodes, first assign a TImageList value to its Images property. To support pictures associated with items, the TTreeNode class is equipped with a property called ImageIndex: __property int ImageIndex = {read=FImageIndex,write=SetImageIndex}; This property allows you to assign the intended image to the node.
|
|
|||||||||||||||||||||||||||||||||||||||
|