VST实例(6) 节点(NODE) 特殊节点和节点的增减
这一部分在程序中并未直接使用,只是对VST的一些特性进行讲解,不喜欢的可以跳过。
三、特殊节点
1、Rootnode
property RootNode: PVirtualNode;
rootnode不是一个具体的节点,是为了锚定树的层次结构,维护的一个内部树节点,这个节点大部分情况下与其他树节点一样,但有时会有不同的处理。根节点始终是展开和初始化的。它的父成员指向节点所属的树视图,它的PreviousSibling和NextSibling成员指向根节点本身,以便于实际识别出该节点。
您不应该使用根节点来遍历整个树。它只是公开访问的,因为它是所有顶级节点的父节点,并且可以用来测试节点是否为顶级节点。
在VST中,某节点如果是根节点(LEVEL=0),那么就有node.parent=rootnode。可使用此特性来判断节点是否根节点。
2、FocusedNode
property FocusedNode: PVirtualNode;
用于读取或设置焦点节点。通常情况下,焦点节点总是selected节点,反之不然。
树视图中只有一个节点可以获得当前输入焦点,标记为该节点标题周围的虚线矩形。获得输入焦点意味着可以通过按F2或单击它来编辑该节点,并且用户键盘输入将与焦点节点相关解释(例如,树导航,展开/折叠等)。如果启用了扩展焦点,则还将考虑FocusedColumn属性。
关于焦点节点,还有两个相关的事件:
property OnFocusChanged: TVTFocusChangeEvent;
用于当焦点节点发生变化之后。TVTFocusChangeEvent = procedure (Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex) of object;过程中的node就是focusednode;
property OnFocusChanging: TVTFocusChangingEvent;
用于当焦点准备发生改变时,可以在此时禁止变更焦点。TVTFocusChangingEvent = procedure (Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode; OldColumn, NewColumn: TColumnIndex);
一些老版本用户注意:当我们调用deletenode过程时,参数不能使用focusednode,如果一定要删除焦点节点,应该设置某节点指向focusednode,然后删除该节点。
例如:
VAR NODE:PVIRTUALNODE;
……
node:=vst.focusednode;
Vst.deletenode(node);
同时,我们可以把焦点节点(focusednode)指向某一不存在的节点,但不能直接设置焦点节点为空。
3、topnode和bottomnode
这两个节点都是可视区域的节点。例如:
procedure TForm2.pnl1Click(Sender: TObject); begin Caption:=pcodes(vst.GetNodeData(vst.TopNode))^.icao; end;
运行时结果如图:
四、增加和删除节点
增加节点的最佳方法是修改rootnodecount和childcount,方法前面已经介绍,下面再讲讲几种其它途径的方法。
function AddChild(Parent: PVirtualNode; UserData: Pointer = nil): PVirtualNode; virtual;
函数addchild可以在指定节点增加最后一个子节点。如果parent=nil,则增加最后一个根节点。
前面提到过,不建议使用AddChild方法。该方法只是为了更容易地从TTreeView迁移。原因是该方法必须验证节点并进行一些其他处理,这会防止树使用其虚拟范例。重要的优势将会消失。如果可能的话,您应该重新设计并尝试使用正确的方法:通过OnInitNode和OnInitChildren。
但如果你确实想使用addchild,请记得处理oninitnode和oninitchildren中的相应处理语句,免得重复处理或出错(例如如果你在事件处理时使用了数据库查询,而在使用addchild时又关闭了数据库,肯定会出错的)。
function InsertNode(Node: PVirtualNode; Mode: TVTNodeAttachMode; UserData: Pointer = nil): PVirtualNode;
函数InsertNode在指定节点的前面或后面插入节点。在前面或后面取决于参数Mode。
参数 |
作用 |
amNoWhere |
只是做个测试,实际并不做插入处理 |
amInsertBefore |
指定节点之前插入一个兄弟节点 |
amInsertAfter |
指定节点之后插入一个兄弟节点 |
amAddChildFirst |
插入指定节点的第一个子节点 |
amAddChildLast |
相当于addchild |
procedure DeleteNode(Node: PVirtualNode; Reindex: Boolean = True);
函数DeleteNode用于删除指定节点。如果此节点已经initialized 或者已经指定了data,则在删除时会触发事件onfreenode,在事件中可以处理数据占用的内存。
procedure DeleteSelectedNodes; virtual;
用于删除所有已经selected的节点。