2016-07-30 22 views
1

Bitte nehmen Sie sich einen Blick Code unten:GetText von TVirtualStringTree ausgelöst wird immer öfter

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. 

Nachdem die Taste, um die Nachrichten gedrückt wird i bekommen sind:

[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] 

Grundsätzlich ist die GetText 4 ausgelöst Zeiten für jeden Knoten und jede Spalte.

Warum wird nicht nur einmal ausgelöst? Wie folgt aus: [0,0] [1,0] [0,1] [1,1]

enter image description here

+3

Dies ist von Entwurf. Beachten Sie die Parameter. Ihr Event-Handler wird separat für verschiedene Spalten und Textarten ausgelöst. –

+2

Sie müssen wirklich besser als 'ShowMessage' protokollieren. Werfen Sie einen Aufruf an "AllocConsole" und verwenden Sie "WriteLn". Oder ein einfacher 'OutputDebugString'. –

+0

Ich benutze dieses Werkzeug nie bis jetzt David! – REALSOFO

Antwort

2

Die Steuerung verwendet das so genannte virtuelle Paradigma. Der Autor Mike Lischke explains this like so:

Wie der Name bereits andeutet, nutzt diese Steuerung ein anderes Paradigma für Baum-Management als andere Kontrollen dieser Art. Es weiß nichts über die Daten, die es verwaltet (außer seiner Größe), nicht einmal die Beschriftungen eines Knotens. Alles wird über Ereignisse (oder Abkömmlinge über überschriebene Methoden) aus der Anwendung abgerufen.

Das Steuerelement behält die Knotenbeschriftungen nicht im Auge. Wann immer es benötigt wird, wird die Methode OnGetText ausgelöst. Das Steuerelement wird nicht zwischengespeichert und speichert die Knotenbeschriftungen nicht. Wenn also mehrere Teile des Steuercodes von der Beschriftung abhängen, wird das Ereignis für denselben Knoten mehrfach aufgerufen.

Das Verhalten, das Sie beobachten, ist völlig normal und völlig zu erwarten. Der Job Ihres OnGetText-Handlers besteht darin, den Text des Knotens zu liefern. Mach dir keine Sorgen, wenn dieselbe Frage zweimal gestellt wird. Stellen Sie sicher, dass Sie jedes Mal die gleiche Antwort geben!

+0

Gut beantwortet! Danke David! – REALSOFO