VST实例(4)节点(NODE) 一、节点的状态详解

发布时间 2023-05-29 15:23:51作者: Luo大哥

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
);

 

5node.dummy

node.dummy是一个byte类型的附加型参数,你可以把它理解为node的tag。所以其实这个值没什么好讲述的,但某些时候你会发现其实它很有用,就看你的需求。

6vst的展开和收拢

对vst. Expanded[node]赋值可以展开节点。当然如果设置为false,则是收拢该节点。

VST.FullCollapse(Node: PVirtualNode = nil);用于完全收拢某节点及其子孙节点。如果不带参数,则是针对VST本身的设置,即收拢整个VST树。

而VST. FullExpand (Node: PVirtualNode = nil);则是进行相反的操作。

最后提醒一点:treeoptions的autooptions如果包含属性toAutoExpand,那么当节点获得焦点时,将自动展开此节点,而失去焦点时,则自动收拢该节点。