![]() |
TVirtualStringTree: nachträglich Objekt am Knoten tauschen
Moin,
ist es möglich nachträglich das Objekt an einem Node des VirtualTreeView zu tauschen? 1. Erstellen
Delphi-Quellcode:
2. Später soll der Knoten auf eine anderes Objekt zeigen.
data:= TMyData.Create;
vst.AddChild(nil, data); PS: Bisher habe ich einen neuen Knoten mit den neuen Daten hinter den alten eingefügt und den alten danach gelöscht. Vllt. gehts aber auch irgendwie nur mit austauschen. |
Re: TVirtualStringTree: nachträglich Objekt am Knoten tausch
Klar kannst du das tauschen ;)
|
Re: TVirtualStringTree: nachträglich Objekt am Knoten tausch
Hehe, sag mal wie :).
|
Re: TVirtualStringTree: nachträglich Objekt am Knoten tausch
an jedem TVirtualNode gibt es ein Zeiger Data bzw. ab dort ist ein Speicherbereich für die Daten.
Meist 4 Byte für einen Zeiger, wenn du mit Objekten arbeitest. In diese 4 Bytes legst du deinen neuen Zeiger rein.
Delphi-Quellcode:
Bei AddChild findest du diesen Code welcher den Zeiger bzw. den Inhalt setzt:
TVirtualNode = packed record
Index, // index of node with regard to its parent ChildCount: Cardinal; // number of child nodes NodeHeight: Word; // height in pixels States: TVirtualNodeStates; // states describing various properties of the node (expanded, initialized etc.) Align: Byte; // line/button alignment CheckState: TCheckState; // indicates the current check state (e.g. checked, pressed etc.) CheckType: TCheckType; // indicates which check type shall be used for this node Dummy: Byte; // dummy value to fill DWORD boundary TotalCount, // sum of this node, all of its child nodes and their child nodes etc. TotalHeight: Cardinal; // height in pixels this node covers on screen including the height of all of its // children // Note: Some copy routines require that all pointers (as well as the data area) in a node are // located at the end of the node! Hence if you want to add new member fields (except pointers to internal // data) then put them before field Parent. Parent, // reference to the node's parent (for the root this contains the treeview) PrevSibling, // link to the node's previous sibling or nil if it is the first node NextSibling, // link to the node's next sibling or nil if it is the last node FirstChild, // link to the node's first child... LastChild: PVirtualNode; // link to the node's last child... Data: record end; // this is a placeholder, each node gets extra data determined by NodeDataSize end;
Delphi-Quellcode:
result ist ein PVirtualNodefunction TBaseVirtualTree.AddChild(Parent: PVirtualNode; UserData: Pointer = nil): PVirtualNode; if Assigned(UserData) then if FNodeDataSize >= 4 then begin NodeData := Pointer(PChar(@Result.Data) + FTotalInternalDataSize); NodeData^ := UserData; Include(Result.States, vsInitialUserData); end |
Re: TVirtualStringTree: nachträglich Objekt am Knoten tausch
Warum setzt du denn nicht gleich die Werte des TMyData Objekts in dem alten Knoten,
anstatt einen neuen Knoten zu erstellen, diesem das neue TMyData Objekt zu übergeben und den aten Knoten zu löschen? Also etwa so:
Delphi-Quellcode:
var
OldNodeData : PMyData; begin if Assigned(ANode) then begin OldNodeData := VST.GetNodeData(ANode); if Assigned(OldNodeData) then begin OldNodeData^.Field1 := XYZ; OldNodeData^.Field2 := 123; end; end; end; |
Re: TVirtualStringTree: nachträglich Objekt am Knoten tausch
Hier nun meine Lösung:
1. Ich habe eine abgeleitete Klasse vom Tree erstellt:
Delphi-Quellcode:
uses
VirtualTrees; type TVirtualStringTreeEx = class(TVirtualStringTree) public procedure ReplaceNodeData(Node: PVirtualNode; UserData: Pointer); end; implementation { TVirtualStringTreeEx } procedure TVirtualStringTreeEx.ReplaceNodeData(Node: PVirtualNode; UserData: Pointer); var NodeData: ^Pointer; begin if Assigned(UserData) then if NodeDataSize >= 4 then begin NodeData := Pointer(PByte(@Node.Data) + TotalInternalDataSize); NodeData^ := UserData; end end; 2. Programmcode aufs Ersetzen angepaßt:
Delphi-Quellcode:
Ich hoffe es stimmt soweit und hilft vielleicht jemanden weiter.
var
lNewData: TMyData; lNode: PVirtualNode; begin lNode:= vstData.FocusedNode; // lNewData besorgen ... // Daten ersetzen TVirtualStringTreeEx(vstData).ReplaceNodeData(lNode, lNewData); end; Danke für die Hilfe. Gruß, Matthias |
AW: TVirtualStringTree: nachträglich Objekt am Knoten tauschen
Ich würde gerne im DragDrop-Ereignis die beiden Knoten vertauschen (also FocusedNode mit DropTargetNode). Vermutlich wäre es das beste, deren beide Zeiger zu vertauschen. Leider weiß ich nicht, wie das korrekt geht. Ich denke, dieser Thread geht in eine ähnliche Richtung und ich habe mal etwas herumprobiert, aber es scheitert allein schon daran, dass "TotalInternalDataSize" nicht definiert ist. Könnt Ihr mir bitte kurz aufzeigen, wie man zwei Knoten korrekt vertauschen kann?
|
AW: TVirtualStringTree: nachträglich Objekt am Knoten tauschen
Probier es mal so, wie ich es oben beschrieben habe.
Du mußt erst eine abgeleitet Klasse von TVirtualStringTree anlegen, diese übernimmt das Austauschen der Daten, siehe 1. In deiner Methode DragDrop machst du ein cast deines Trees auf die abgeleitet Tree-Klasse TVirtualStringTreeEx(<YourTree>), damit du Zugriff auf die Funktion ReplaceNodeData() bekommst und die Daten austauschen kannst, siehe 2. |
AW: TVirtualStringTree: nachträglich Objekt am Knoten tauschen
Danke für die Antwort und sorry für die Verzögerung...
Was ist denn "TotalInternalDataSize"? Wo ist das denn deklariert? |
AW: TVirtualStringTree: nachträglich Objekt am Knoten tauschen
siehe VirtualTrees.pas:
Delphi-Quellcode:
FTotalInternalDataSize eine private Variable in der Klasse TBaseVirtualTree, sie ist nicht von extern ansprechbar. Über die abgeleitete Klasse TVirtualStringTreeEx kommt man doch daran.
TBaseVirtualTree = class(TCustomControl)
private ... FTotalInternalDataSize: Cardinal; // Cache of the sum of the necessary internal data // size for all tree ... end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz