VST由节点(node)组成,节点的定义如下:
PVirtualNode = ^TVirtualNode; TVirtualNode = packed record Index, ChildCount: Cardinal; NodeHeight: Word; States: TVirtualNodeStates; Align: Byte; CheckState: TCheckState; CheckType: TCheckType; Dummy: Byte; TotalCount, TotalHeight: Cardinal; Parent, PrevSibling, NextSibling, FirstChild, LastChild: PVirtualNode; private Data: record end; public function IsAssigned(): Boolean; inline; function GetData(): Pointer; overload; inline; function GetData<T>(): T; overload; inline; procedure SetData(pUserData: Pointer); overload; procedure SetData<T>(pUserData: T); overload; procedure SetData(const pUserData: IInterface); overload; end;
一、节点(NODE)的状态
节点的状态如下:
TVirtualNodeState = ( vsInitialized, // Set after the node has been initialized. vsChecking, // Node's check state is changing, avoid propagation. vsCutOrCopy, // Node is selected as cut or copy and paste source. vsDisabled, // Set if node is disabled. vsDeleting, // Set when the node is about to be freed. vsExpanded, // Set if the node is expanded. vsHasChildren, // Indicates the presence of child nodes without actually setting them. vsVisible, // Indicate whether the node is visible or not (independant of the expand states of its parents). vsSelected, // Set if the node is in the current selection. vsOnFreeNodeCallRequired, // Set if user data has been set which requires OnFreeNode. vsAllChildrenHidden, // Set if vsHasChildren is set and no child node has the vsVisible flag set. vsReleaseCallOnUserDataRequired, // Indicates that the user data is a reference to an interface which should be released. vsMultiline, // Node text is wrapped at the cell boundaries instead of being shorted. vsHeightMeasured, // Node height has been determined and does not need a recalculation. vsToggling, // Set when a node is expanded/collapsed to prevent recursive calls. vsFiltered, // Indicates that the node should not be painted (without effecting its children). vsInitializing // Set when the node is being initialized ); TVirtualNodeStates = set of TVirtualNodeState;
节点的状态是一个组合,下面讲述一下部分状态的应用。
1、节点的可见性
每一个节点都有一个属性:isvisible,在前面的代码中我们我们用到过这个属性,设置节点的可见性的方法是:TBaseVirtualTree.isvisible[node]:=true;
注意,isvisible是VST的一个数组值,不是node的一个状态值,当然,当对isvisible进行赋值后,node的state属性也会进行相应的修改。
为什么呢?实际上,不但是可见性,其它的而许多属性也建议直接使用VST.属性[node]来进行设置,这样可以直接体现在VST上,如果只是设置node的值,则只有但刷新该节点时才会正确显示。
注意:在客户区找不到某个节点,除了该节点不在客户区外(所谓的客户区指的是VST展现给用户看的区域,客户区外的节点可能通过滚动出现在客户区),它还有两种可能被隐藏。一种是在TVirtualNodeState中的vsVisible状态,如果没有指定,它将隐藏该节点,而不考虑另一个节点的当前状态。前面讲的就是如何设置或隐藏某节点。
另一种是一个或多个父节点可能会隐藏,从而隐藏整个子节点结构。如果父节点设置为隐藏,则子节点无论进行了如何的设置都将是不可见的,只有当某节点和其父节点、祖父节点等等都可见时,才能确保本节点可见。
vst.VisiblePath[node]:=True;可以设置某节点的所有父节点都可见,而
VST.FullyVisible[NODE]:=true;相当于同时进行了前面所述的两种设置。
2、节点的筛选和enable
在事件的处理程序中,通常Sender:TBaseVirtualTree,代表VST本身。
Sender.IsFiltered:设置本节点是否筛选,用户可以使用此属性。
Sender.IsDisabled:设置本节点是否可用。当某节点设置为不可用时,则该节点默认显示为灰色,且不可选择,不能成为焦点节点。
例如下图所示,我设置乌兰巴托情报区的所有机场与情报区为不可用:
设置的代码是:
if CellText.Contains('ZM') then Sender.IsDisabled[node]:=True;
不过在本程序中未使用此二属性。
3、节点的选择
Sender.Selected[node]可以设置或判断节点是否选中。
如果对VST的treeoptions进行“SelectionOptions:=SelectionOptions+[toMultiSelect];”设置,那么可以对节点进行多选,否则当选中一个节点时,其它节点的selected属性为false。
vst.SelectedCount,VST被选择的节点数。
过程procedure TBaseVirtualTree.SelectAll(VisibleOnly: Boolean);可以让所有节点处于被选择状态。
vst.SelectedNodes()是一个序列集合,里面包括了所有被选择的节点。其类型是:TVTVirtualNodeEnumeration。
TVTVirtualNodeEnumeration的用法将在后面讲述。
同时,VST有下面几个与选择节点相关的设置:
TVTSelectionOption = ( toDisableDrawSelection, toExtendedFocus, toFullRowSelect, //整行选定 toLevelSelectConstraint, // 在多选时,只能在同一层进行选择. toMiddleClickSelect, // 允许按鼠标中间键选择 toMultiSelect, // 允许多节点选择. toRightClickSelect, // 允许右键选择 toSiblingSelectConstraint, // 只允许选择兄弟节点. toCenterScrollIntoView, // 当选中某一节点时,该节点滚动到VST视野中 toSimpleDrawSelection, //. toAlwaysSelectNode, // 当设置了此值时,VST中总是有至少一个节点是selected toRestoreSelection, toSyncCheckboxesWithSelection ); TVTSelectionOptions = set of TVTSelectionOption;
4、节点的选择框状态
VST支持选择框,如果要使用选择框,首先得设置:
MiscOptions:=MiscOptions+[toCheckSupport]
然后在oninitnode事件让节点有一个checktype。
可以直接设置node.checktype,不过最好通过设置VST.checktype[node]。例如:
sender.CheckType[node]:=ctTriStateCheckBox;
checktype有以下类型:
- ctNone:不带选择框
- ctTriStateCheckBox:关联选择框,通常用于有子节点的节点,check部分或全部子节点时有不同的样式,如果check父节点,则所有子节点check。
- ctCheckBox//普通复选框
- ctRadioButton//单选按钮,同一父节点的具有单选按钮的子节点只能有一个checked。
- ctButton:只有一个按钮,不可用于选择。
Sender.CheckState[node]可用于设置或获取复选框的状态。常用的状态有:
- csUncheckedNormal:未选中状态
- csCheckedNormal:通常的选中状态
- csMixedNormal:三态复选框状态
其它几种状态不常用,可用于特殊用途。
TCheckState = ( csUncheckedNormal, // unchecked and not pressed csUncheckedPressed, // unchecked and pressed csCheckedNormal, // checked and not pressed csCheckedPressed, // checked and pressed csMixedNormal, // 3-state check box and not pressed csMixedPressed, // 3-state check box and pressed csUncheckedDisabled,// disabled checkbox, not checkable csCheckedDisabled, // disabled checkbox, not uncheckable csMixedDisabled // disabled 3-state checkbox );
例如,sender.checkstate[node]:=ctcheckednormal可以设置某节点为选择状态。这个语句也可以写为:sender.checkstate[node]. GetPressed,也有相同的效果,VST为TCheckState写了个Helper。
此外,vst.CheckedCount返回所有非csuncheckednormal的checkstate的节点数。
而vst.CheckedNodes()返回具有指定复选状态的节点序列。返回值是一个TVTVirtualNodeEnumeration类型的record,同样的,其具体使用也将放在后面讲述。
复选框的状态也是可调整的,可通过设置vst.CheckImageKind来进行调整,CheckImageKind的值和效果如下图所示:
TCheckImageKind = (
ckLightCheck,
ckDarkCheck,
ckLightTick,
ckDarkTick,
ckFlat,
ckXP,
ckCustom,
ckSystemFlat,
ckSystemDefault
);
5、node.dummy
node.dummy是一个byte类型的附加型参数,你可以把它理解为node的tag。所以其实这个值没什么好讲述的,但某些时候你会发现其实它很有用,就看你的需求。
6、vst的展开和收拢
对vst. Expanded[node]赋值可以展开节点。当然如果设置为false,则是收拢该节点。
VST.FullCollapse(Node: PVirtualNode = nil);用于完全收拢某节点及其子孙节点。如果不带参数,则是针对VST本身的设置,即收拢整个VST树。
而VST. FullExpand (Node: PVirtualNode = nil);则是进行相反的操作。
最后提醒一点:treeoptions的autooptions如果包含属性toAutoExpand,那么当节点获得焦点时,将自动展开此节点,而失去焦点时,则自动收拢该节点。