Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Nodes in VirtualStringTree verschieben. (https://www.delphipraxis.net/82808-nodes-virtualstringtree-verschieben.html)

formosa 19. Dez 2006 19:52


Nodes in VirtualStringTree verschieben.
 
Hallo zusammen,

Ich habe mich Heute mit dem verschieben von Nodes in der VirtualStringTree Komponente auseinander gesetzt. Da ich noch Anfänger bin hat es mich sehr viel Zeit gekostet.

In meinem Tree gibt es momentan nur zwei Arten von Nodes. Node "A", der weitere Nodes aufnehmen kann (so ne Art Ordner) und Node "B", welcher keine haben kann (wäre dann wohl die Datei). Also wollte ich das nur "A" nach "A" oder "B" nach "A" verschoben werden kann.

Weiterhin kann ein ParentNode nicht in einen ChildNode verschoben werden. Nodes welche auf einen anderen Node gezogen werden, sollten als Child hinzugefügt werden.

Gibt es eine Möglichkeit meinen Code etwas zu verkleinern?

Delphi-Quellcode:
//------------  Drag&Drop bei VST starten (verschieben) -------------
procedure TForm1.VSTDragDrop(Sender: TBaseVirtualTree; Source: TObject;
  DataObject: IDataObject; Formats: TFormatArray; Shift: TShiftState;
  Pt: TPoint; var Effect: Integer; Mode: TDropMode);
var
  TempNode, SourceNode, TargetNode : PVirtualNode;
  DropMode                         : TVTNodeAttachMode;
  Data                             : PTreeData;
begin
  SourceNode := VST.FocusedNode;
  TargetNode := Sender.DropTargetNode;
  If TargetNode = nil then exit;                 // Kein Node als Zeil = Exit;
  Data := VST.GetNodeData(TargetNode);           // Daten von ZielNode holen;
  If Data^.FAnimal = true then                   // Wenn Ziel Ein Tier = Exit;
  begin
    beep;
    exit;
  end;
  If SourceNode = TargetNode then exit;           // Wenn Quelle = Ziel -> Exit;
  while vst.GetNodeLevel(TargetNode)>0 do         // Ist Source Parent von Target?
  begin
    TargetNode:=TargetNode.Parent;
    If SourceNode = TargetNode then               // Wenn Source = Parent von Target
    begin
      beep;
      exit;                                        // Exit; Weil Uebergertneter Node kann sich nicht in sich selbst verschieben;
    end;
  end;
  TargetNode := Sender.DropTargetNode;             // Target nochmals holen. Wegen Parent Test oben;
    case Mode of
        dmAbove:   DropMode := amInsertBefore;
        dmOnNode:  DropMode := amInsertAfter;
        dmBelow:   DropMode := amInsertAfter;
        else       exit;
    end;
  if Mode = dmOnNode then                          // Abgelegt AUF Node = Als Child verschieben;
  begin
    if not VST.HasChildren[TargetNode] then        // Node hat noch KEIN Child;
    begin
      VST.BeginUpdate;
      TempNode := TargetNode;                              // Kopie von TagetNode erstellen;
      TempNode := VST.AddChild(TempNode);                  // Dem Temporaeren Node ein Child hinzufügen;
      VST.MoveTo(SourceNode, TempNode, DropMode, false);   // Den SourceNode hinzufügen;
      VST.DeleteNode(TempNode);                            // TempNode wieder löschen;
      VST.Expanded[TargetNode]:=True;                      // TargetNode aufklappen;
      VST.EndUpdate;
      exit;                                                // Exit:
    end
    else                                                   // Wenn TargetNode schon ein Child hat;
    begin
      TargetNode := TargetNode.LastChild;                  // TargetNode auf letztes Child setzten
    end;
  end;
  VST.MoveTo(SourceNode, TargetNode, DropMode, false);     // verschieben;
end;
//-------------------------------------------------------------------

Hab mich den ganzen Tag durch X Tutorials gearbeitet.

Für Vorschläge wie ich den Code verbessern kann wäre ich dankbar.

Schönen Gruss,

Chris

Alloc 19. Dez 2006 20:49

Re: Nodes in VirtualStringTree verschieben.
 
Hi Chris,

im Prinzip ist ein Großteil des Codes ja nur dazu da, zu erkennen, ob die Move-Aktion erlaubt werden soll.
Das VST bietet dazu zwei Events:
1. OnDragAllowed: Dort kann man beim Versuch des Nutzers einen Node zu bewegen sagen, ob der gerade aktive Node verschiebbar sein soll.
2. OnDragOver: In diesem Event kann man während des Bewegens eines Nodes angeben, ob der Node an der aktuellen Stelle eingefügt werden darf. Den Parameter "Mode" beachten. In dem Event kannst du dem Nutzer auch visuell zeigen, dass er einen Node an der aktuellen Stelle nicht droppen kann.

Hilft zwar nicht unbedingt soviel beim Code sparen, aber damit hast du schonmal einiges an Übersichtlichkeit gewonnen. =)

Gruß,
Chris

/Edit: Um den zu verschiebenden Node und das aktuelle Ziel-Node in OnDragOver zu bekommen, VST.FocusedNode und VST.DropTargetNode verwenden.

formosa 21. Dez 2006 10:21

Re: Nodes in VirtualStringTree verschieben.
 
Hallo,

Ich hab jetzt die meisten Abfragen was, wie verschoben werden kann ins OnDragOver Event veschoben. Hab den Event aus irgendwelchen Gründen komplett vernachlässigt, und mich nur auf OnDragDrop konzentriert.

Vielen Dank noch,

Gruss Chris


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:09 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz