I need to show a long db table in the TVirtualStringTree
(e.g. 50000 records). To lower query execution time I limit the number of records with only those that are actually displayed in the tree. The code snippet of handling OnGetText
is below. The problem is that VisibleCount
returns 50000 instead of 20-30 which ruins this approach. Is there a way to do it properly?
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;
To find the number of displayed nodes you need to write your own function, but in this case, it should be enough to get the first and the last displayed node using TopNode
and BottomNode
or GetFirst
and GetLast
if they don't exist.
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;
However I have to say that this doesn't seem to be the most effective solution, because you will run thousands of queries while casually scrolling the tree. If anything, I would multiply the number of retrieved contacts, so you don't need to run new queries so often.