2016-07-30 122 views
1

請看看與波紋管代碼:的getText是越來越觸發多次

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]

enter image description here

+3

這是設計。注意參數。您的事件處理程序針對不同的列和文本類型分別觸發。 –

+2

你確實需要比'ShowMessage'更好的日誌記錄。投入「AllocConsole」並使用「WriteLn」。或者一個簡單的'OutputDebugString'。 –

+0

我從來沒有使用這個工具,直到現在大衛! – REALSOFO

回答

2

控制使用所謂虛擬範例。作者Mike Lischke explains this like so

正如名稱已經指出的那樣,此控件與其他此類控件使用不同的範例來進行樹管理。它不知道它管理的數據(除了它的大小),甚至不知道節點的標題。一切都通過事件(或通過重寫方法的後代)從應用程序中檢索。

控件不記錄節點標題。每當需要知道它們時,就會觸發OnGetText方法。該控件不緩存,不記得節點標題。因此,如果控制代碼的多個部分依賴於標題,則該事件將針對同一節點多次調用。

您觀察到的行爲完全正常,完全可以預料。您的OnGetText處理程序的工作是生成節點的文本。如果兩次詢問同一問題,請不要擔心。只要確保你每次都給出相同的答案!

+0

很好回答!謝謝大衛! – REALSOFO