Frage

Dies ist eine aktualisierte Version einer zuvor veröffentlichten Frage, der vorherige Titel war Auswählen des Knotens nach Index in Delphis virtuellem Baumview.]

Nach dem größten Teil eines Tages glaube ich, dass ich die virtuelle Treeview -Komponente (leistungsstark, aber komplex) in einer einfachen zwei Tabellendaten bearbeitet habe.

Jetzt versuche ich einfach den 1.512. (zum Beispiel) der obersten Knoten auszuwählen. Ich kann keinen anderen Weg sehen, als den ersten Knoten auf der obersten Ebene zu bekommen und dann GetNextsibling 1.511 in einer Schleife zu rufen.

Dies scheint unnötig zu beteiligt. Gibt es einen einfacheren Weg?

AKTUALISIEREN

Da die Initialisierung der Knoten in meinem Baum Datenbankzugriff erfordert, ist die Initialisierung aller Knoten beim Start nicht möglich. Wenn der Benutzer mit einem bereits ausgewählten Datensatz startet, ist das in Ordnung. Wenn der Benutzer um den Baum rollt, werden genügend Knoten besiedelt, um das aktuelle Fenster in den Baum anzuzeigen, und die Leistung ist in Ordnung.

Wenn der Benutzer das Formular im Dialogmodus mit einem bereits ausgewählten Datenbankdatensatz startet, muss ich den Baum zu diesem Knoten vorantreiben, bevor der Benutzer das Formular sieht. Dies ist ein Problem, denn wenn die Aufzeichnung gegen Ende des Baumes liegt, kann es zehn Sekunden dauern, wenn ich den Baum vom ersten Knoten gehe. Jedes Mal, wenn ich GetNextSsibling () kann, wird ein Knoten initialisiert, obwohl die überwiegende Mehrheit dieser Knoten nicht dem Benutzer angezeigt wird. Ich würde es vorziehen, die Initialisierung dieser Knoten bis zu dem Punkt zu verschieben, an dem sie für den Benutzer sichtbar werden.

Ich weiß, dass es einen besseren Weg geben muss. ohne die Knoten initialisieren zu müssen, die ich übersprungen habe.

Dies ist der Effekt, den ich beim Öffnen des Baumes mit einem ausgewählten Datensatz erwerben möchte. Ich kenne den Index des Knotens, zu dem ich gehen möchte, aber wenn ich nicht mit dem Index dort gelangen kann Mitte des Baumes).

Alternativ gibt es vielleicht eine staatliche Einstellung, die ich für die Baumansicht vornehmen kann, die die Zwischenknoten uneinheitlich lässt, wenn ich das Netz durchquere. Ich habe versucht, Start/End -Update zu erzielen, und das scheint den Trick nicht zu tun.

War es hilfreich?

Lösung

Um das Geschwister eines Knotens zu erhalten, ohne es zu initialisieren, verwenden Sie einfach das NextSibling Zeiger (siehe Erklärung von TVirtualNode).

Andere Tipps

Die Baumsteuerung ist wie klassische Bäume strukturiert, über die Sie in einer Computer-Science-Klasse erfahren würden. Die einzige Möglichkeit, von der Wurzel des Baumes zum 1512. Kind zu gelangen, besteht darin, die Links einzeln zu wandeln. Egal, ob Sie es selbst tun oder eine Methode der Baumsteuerung verwenden, es muss immer noch so getan werden. Ich sehe nichts, was in der Steuerung selbst bereitgestellt wird, sodass Sie diese Funktion verwenden können:

function GetNthNextSibling(Node: PVirtualNode; N: Cardinal;
  Tree: TBaseVirtualTree = nil): PVirtualNode;
begin
  if not Assigned(Tree) then
    Tree := TreeFromNode(Node);
  Result := Node;
  while Assigned(Result) and (N > 0) do begin
    Dec(N);
    Result := Tree.GetNextSibling(Result);
  end;
end;

Wenn Sie das oft tun, möchten Sie sich vielleicht zu einem Index machen. Es könnte so einfach sein wie eine Reihe von einer Reihe von PVirtualNode Zeiger und Speichern aller Werte der obersten Ebene darin, sodass Sie einfach den 1512. Wert daraus lesen können. Die Baumsteuerung ist für eine solche Datenstruktur selbst nicht erforderlich, sodass sie nicht beibehält.

Sie könnten auch überdenken, ob Sie Benötigen Sie eine solche Datenstruktur. Tust du Ja wirklich Müssen Sie auf die Knoten nach Index so zugreifen? Oder könnte stattdessen a beibehalten PVirtualNode Zeiger, seine Position relativ zum Rest der Knoten im Baum ist keine Rolle mehr (was bedeutet, dass Sie sie beispielsweise sortieren können, ohne den Bezug auf den gewünschten Knoten zu verlieren)?

Sie schreiben in Ihr Update:

Ich weiß, dass es einen besseren Weg geben muss. ohne die Knoten initialisieren zu müssen, die ich übersprungen habe.

Hier gibt es einen Unterschied, da vertikale Scrolling die logische y -Koordinate ändert, die an der Client -Position 0 angezeigt wird. Die Steuerung berechnet den Offset von der Bildlaufleisteposition und dem Bildlaufbereich und berechnet dann, welcher Knoten oben auf der Steuerung sichtbar ist. Knoten werden nur erneut initialisiert, wenn der Bereich, der in Sichtweise gescrollt wurde, gestrichen werden muss.

Wenn Sie die Y -Koordinate eines Knotens haben

function TBaseVirtualTree.GetNodeAt(X, Y: Integer; Relative: Boolean;
  var NodeTop: Integer): PVirtualNode;

Die Y -Koordinate eines Knotens ist die Summe der Höhen aller früheren sichtbaren Knoten. Angenommen, Sie haben keine zusammengebrochenen Knoten (entweder handelt es sich also um eine flache Liste von Datensätzen, oder alle Knoten mit untergeordneten Knoten sind erweitert) und alle haben die Standardhöhe, dies ist einfach. Dieser Code sollte ein guter Ausgangspunkt sein:

procedure TForm1.SelectTreeNode(AIndex: integer; ACenterNodeInTree: boolean);
var
  Y, Dummy: integer;
  Node: PVirtualNode;
begin
  Y := Round((AIndex + 0.5) * VirtualStringTree1.DefaultNodeHeight);
  Node := VirtualStringTree1.GetNodeAt(0, Y, False, Dummy);
  if Node <> nil then begin
    Assert(Node.Index = AIndex);
    VirtualStringTree1.ScrollIntoView(Node, ACenterNodeInTree);
    VirtualStringTree1.Selected[Node] := True;
    VirtualStringTree1.FocusedNode := Node;
  end;
end;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top