Delphi TVirtualStringTree中的GetText被触发的次数更多
请查看以下代码:Delphi TVirtualStringTree中的GetText被触发的次数更多,delphi,virtualtreeview,tvirtualstringtree,Delphi,Virtualtreeview,Tvirtualstringtree,请查看以下代码: unit Unit2; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VirtualTrees, Vcl.StdCtrls; type TTreeData = record Fields: array
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VirtualTrees, Vcl.StdCtrls;
type
TTreeData = record
Fields: array of String;
end;
PTreeData = ^TTreeData;
const
szVirtualTree = SizeOf(TTreeData);
type
TForm2 = class(TForm)
tree: TVirtualStringTree;
Button1: TButton;
procedure treeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
procedure treeGetNodeDataSize(Sender: TBaseVirtualTree;
var NodeDataSize: Integer);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
var
LTreeData: PTreeData;
Node: PVirtualNode;
cols, rows, col, row: Integer;
begin
cols:= 2;
rows:= 2;
Tree.Header.Columns.Clear;
if cols > 0 then
for col := 0 to cols - 1 do
with Tree.Header.Columns.Add do
begin
Text:= 'H' + IntToStr(col);
Width:= 80;
end;
Tree.Clear;
Tree.BeginUpdate;
if (cols> 0) and (rows > 0) then
for row := 0 to rows - 1 do
begin
Node:= Tree.AddChild(nil,nil);
Tree.ValidateNode(Node,False);
LTreeData:= Tree.GetNodeData(Node);
SetLength(LTreeData^.Fields, cols);
if cols > 0 then
for col := 0 to cols - 1 do
LTreeData^.Fields[col]:= '[' + inttostr(col) + ',' + inttostr(row) + ']';
end;
Tree.EndUpdate;
end;
procedure TForm2.treeGetNodeDataSize(Sender: TBaseVirtualTree;
var NodeDataSize: Integer);
begin
NodeDataSize:= szVirtualTree;
end;
procedure TForm2.treeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
var
LTreeData: PTreeData;
begin
LTreeData:= Sender.GetNodeData(Node);
CellText:= LTreeData^.Fields[Column];
showmessage(CellText);
end;
end.
按下按钮后,我收到的信息是:
[0,0]
[0,0]
[0,0]
[0,0]
[1,0]
[1,0]
[1,0]
[1,0]
[0,1]
[0,1]
[0,1]
[0,1]
[1,1]
[1,1]
[1,1]
[1,1]
基本上,GetText
会为每个节点和列触发4次
为什么不触发一次?像这样:[0,0][1,0][0,1][1,1]
控件使用所谓的虚拟范例。作者Mike Lischke: 正如名称已经指出的,此控件使用与其他此类控件不同的树管理范例。它不知道它所管理的数据的任何信息(除了其大小),甚至不知道节点的标题。通过事件(或通过重写方法的子体)从应用程序检索所有内容 控件不跟踪节点标题。每当需要了解它们时,它就会触发
OnGetText
方法。控件不缓存,不记得节点标题。因此,如果控制代码的多个部分依赖于标题,那么将对同一节点多次调用该事件
你观察到的行为是完全正常的,完全是意料之中的。
OnGetText
处理程序的任务是生成节点的文本。如果同一个问题被问了两次,不要担心。只要确保你每次都给出相同的答案 这是故意的。注意参数。您的事件处理程序会针对不同的列和文本类型分别触发。您确实需要获得比ShowMessage
更好的日志记录。调用alloconsole
并使用WriteLn
。或者是一个简单的OutputDebugString
。直到现在我才使用这个工具,大卫!原因可能是由于array
或szVirtualTree
?我对VST不太了解,但由于是虚拟的,它调用OnGetText来获取节点的文本似乎很自然。回答得好!谢谢你,大卫!