【问题标题】:How to get a number of displayed nodes in TVirtualStringTree?如何获取 TVirtualStringTree 中显示的节点数?
【发布时间】:2019-03-07 10:50:11
【问题描述】:

我需要在TVirtualStringTree 中显示一个长 db 表(例如 50000 条记录)。为了降低查询执行时间,我将记录数限制为仅实际显示在树中的记录数。处理OnGetText的代码sn-p如下。问题是 VisibleCount 返回 50000 而不是 20-30 这破坏了这种方法。有没有办法正确地做到这一点?

procedure TContactsFrame.vstContactsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; 
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
begin
  if vstContacts.GetNodeLevel(Node) = 0 then
    CellText := 'Group'
  else if vstContacts.GetNodeLevel(Node) = 1 then
  begin
    if Contacts[Node.Index].Index = -1 then
    begin
      // getting DB table values of visible records only
      GetContacts(Node.Index + 1, Node.Index + 1 + vstContacts.VisibleCount, Contacts);
    end;
    CellText := Contacts[Node.Index].Name;
  end;
end;

【问题讨论】:

    标签: delphi tvirtualstringtree


    【解决方案1】:

    VisibleCount 为您提供设置了vsVisible 标志的节点数(可见含义未隐藏)。

    要枚举当前显示在树视图中的节点,您可以使用TopNodeBottomNode,类似以下方式:

    var
      Run, LastNode: PVirtualNode;
    begin
      LastNode := Treeview.GetNextVisible(Treeview.BottomNode);
      Run := Treeview.TopNode;
    
      while Assigned(Run) do
      begin
        // your processing here
    
        Run := Treeview.GetNextVisible(Run);
        if Run = LastNode then
          Break;
      end;
    end;
    

    【讨论】:

      【解决方案2】:

      要查找显示节点的数量,您需要编写自己的函数,但在这种情况下,使用TopNodeBottomNodeGetFirst 和@ 获取第一个和最后一个显示节点应该足够了987654325@ 如果它们不存在。

      procedure TContactsFrame.vstContactsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; 
        Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
      var
        lTopNode, lBottomNode : PVirtualNode;
      begin
        case vstContacts.GetNodeLevel(Node) of
          0 : CellText := 'Group'
          1 : begin
                if Contacts[Node.Index].Index = -1 then
                begin
                  // getting DB table values of visible records only
                  lTopNode := vstContacts.TopNode;
                  if not Assigned(lTopNode) then
                    lTopNode := vstContacts.GetFirst;
                  lBottomNode := vstContacts.BottomNode;
                  if not Assigned(lBottomNode) then
                    lBottomNode := vstContacts.GetLast;
                  GetContacts(lTopNode.Index + 1, lBottomNode.Index + 1, Contacts);
                end;
                CellText := Contacts[Node.Index].Name;
              end;
        end;
      end;
      

      但是我不得不说这似乎不是最有效的解决方案,因为您会在随意滚动树的同时运行数千个查询。如果有的话,我会乘以检索到的联系人的数量,因此您不需要如此频繁地运行新查询。

      【讨论】:

      • 感谢您的回答,我得到了类似的问题,如果我想知道单元节点是否真的可见,我应该使用相同的方法吗?
      • @Molochnik 如果要检查某个特定节点是否实际显示,可以使用this function
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多