AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein VirtualStringTree und Klasseninstanzen - Node Data finden

VirtualStringTree und Klasseninstanzen - Node Data finden

Ein Thema von günni0 · begonnen am 16. Apr 2018 · letzter Beitrag vom 17. Apr 2018
Antwort Antwort
Seite 1 von 3  1 23   
günni0

Registriert seit: 7. Mär 2018
260 Beiträge
 
#1

VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 16. Apr 2018, 23:22
Ich versuche mir gerade eine Funktion zu schreiben die mir die Node-Daten anhand eines Index findet

Delphi-Quellcode:
function GetNodeData(Index: Integer): TUserdata;
var
 i: Integer;
begin
 Result := nil;
 for i := 0 to _UserDataClasses.Count - 1 do
  if _UserDataClasses[i].Index = Index then
   begin
    Result := _UserDataClasses[i].aNode.GetData<TUserData>;
    Exit;
   end;
end;
Mein Problem besteht darin, dass ich nicht weiß ob ich mich am Index .Index oder [i] orientieren muss, um das zurückzugeben was ich suche.

In einer anderen Prozedur füge ich Klasseninstanzen in meine ObjectList hinzu und dachte, dass Folgendes funktioniert
Delphi-Quellcode:
if InsertAtPosition > -1 then
 _UserDataClasses.Insert(InsertAtPosition, _UserData)
else
 _UserDataClasses.Add(_UserData);
Das .Insert( funktioniert leider überhaupt nicht wie gewollt. Das VST zeichnet mir den an beispielsweise Index 2 hinzugefügten Eintrag gar nicht und kopiert irgendwie nur den aller letzten.

Daher die Frage.
Ist es vollkommen egal in welcher Reihenfolge die Daten in der ObjectList liegen [man sortiert das VST ja glaube ich eh manuell] und soll man sich nur am Index .Index (eigene Variable in der Klasse) orientieren den ich dann jetzt so setze
Delphi-Quellcode:
// Prozedur die Daten lädt, eine Klasseninstanz erstellt und in die ObjectList packt. Mit dem optionalen Parameter UseIndex kann man den Inhalt der Variablen Index selber bestimmen.
if UseIndex> -1 then
 _UserDataClasses.Index := UseIndex
else
 _UserData.Index := _UserDataClasses.Count;

_UserDataClasses.Add(_UserData);
?

zweite Frage. Wie schaffe ich es die Funktion GetNodeData(Index: Integer) oben als überladene Funktion ohne doppelten Code bereitzustellen?
Beispielsweise wenn ich als Parameter UserName: string haben und diesen auch finden möchte?
Ich könnte die Funktion einfach kopieren und statt .Index = Index dann .UserName = Username prüfen. Aber das wäre doppelter Code.


Bin für Hilfe sehr dankbar!


Oder meine frage etwas anders formuliert.
Wenn ich einen Nutzernamen finden möchte, iteriere ich dann durch die Nodes oder durch die ObjectList?
Delphi-Quellcode:
// General helper function used in multiple other functions (e.g. DeleteUserNameNode)
function FindUserIDByName(const UserName: string): Integer;
var
 i: Integer;
begin
 Result := -1;
 if Assigned(_UserDataClasses) then
  begin
   for i := 0 to _UserDataClasses.Count - 1 do
    begin
     if AnsiSameText(_UserDataClasses[i].UserName, UserName) then
      begin
       Result := i;
       Break;
      end;
    end;
  end;
end;

function FindUserIDByIndex(iIndex: Integer): PVirtualNode;
begin
 Result := _VST.GetFirst(True);
 while Assigned(Result) and (_VST.AbsoluteIndex(Result) <> Cardinal(iIndex)) do
  Result := _VST.GetNext(Result, True);
end;

procedure DeleteUserNameNode(const UserName: string);
var
 Node: PVirtualNode;
begin
 DeleteUserNameNode(FindUserIDByName(UserName));
end;

procedure DeleteUserNameNode(iIndex: Integer);
var
 Node: PVirtualNode;
begin
 Node := FindUserNameByIndex(iIndex);
 if Assigned(Node) then
  _VST.DeleteNode(Node);
end;
Irgendwie bin ich gerade total durcheinander weil ich absolut keine Ahnung habe, an welche Daten ich mich jetzt halten soll... Klasseninstanzen oder nicht?
Bei FindUserIDByName(<string>) halte ich mich ganz klar daran den Nutzer anhand des Namens zu finden und durchsuche die Klasseninstanzen.
Bei FindUserNameByIndex(<int>) durchsuche ich aber direkt das Index der VST und greife nicht auf die Klasseninstanzen zu. Da ist doch schon der erste Fehler oder?

Geändert von günni0 (17. Apr 2018 um 08:17 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
1.745 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#2

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 08:21
Warum so kompliziert?
Bei allen wichtigen Eventhandlern des VST hast du doch eine Referenz auf den Node.
Die Objektliste machste du nur aus Speicherfreigabegründen.

Delphi-Quellcode:
procedure TForm2.VirtualStringTree1GetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
  TextType: TVSTTextType; var CellText: string);
var
  UserData: TUserData;
begin
  if Assigned(Node) then
  begin
    UserData := Node.GetData<TUserData>;
    if Assigned(UserData) then
    begin
      case Column of
        0:
          CellText := UserData.FirstName;
        1:
          CellText := UserData.LastName;
        2:
          CellText := UserData.Address;
      end;
    end;
  end;
end;

Geändert von TiGü (17. Apr 2018 um 08:30 Uhr)
  Mit Zitat antworten Zitat
günni0

Registriert seit: 7. Mär 2018
260 Beiträge
 
#3

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 08:25
Wie ich Text lade ist mir klar.

Was mir nicht klar ist, ist der letzte Abschnitt aus meinem ersten Beitrag.

Ich möchte, dass wenn ich DeleteUserNameNode(<string>) aufrufe genau dasselbe gelöscht wird wie wenn ich DeleteUserNameNode(<int>) aufrufe.

Letzteres ist aber sicher nicht gleich wie ersteres denn in FindUserIDByIndex greife ich direkt auf das VST zu und nicht wie bei allen anderen Prozeduren auf die Klasseninstanzen um an die Daten zu kommen. Ich möchte mir nur ein paar kleine Helfer-prozeduren zusammenstellen, um später doppelten Code zu vermeiden. Aber diese Basis muss auch korrekt sein, sonst geht später alles schief.


--------------- Schnipps
ich glaube ich habs. Hier meine Änderung. Nodes werden jetzt auch korrekt bei umsortierter Liste gelöscht.
Hier ein Beispiel, um Nodes (+ Daten da OwnObjects True) aus einem VST, egal wie es sortiert ist, zu löschen.

Delphi-Quellcode:
// Helferfunktion, um UserName zu finden
function FindUserIDByName(const UserName: string): Integer;
var
 i: Integer;
begin
 Result := -1;
 if Assigned(_UserDataClasses) then
  begin
   for i := 0 to _UserDataClasses.Count - 1 do
    begin
     if AnsiSameText(_UserDataClasses[i].UserName, UserName) then
      begin
       Result := i;
       Break;
      end;
    end;
  end;
end;

// Helferfunktion, um den Node im VST anhand eines gesuchten Index zurückzugeben (Achtung: nicht AbsoluteIndex, sondern der Index in meinen Klassendaten!)
function FindUserIDByIndex(iIndex: Integer): PVirtualNode;
var
 i: Integer;
begin
 Result := nil;
 for i := 0 to _UserDataClasses.Count - 1 do
  if _UserDataClasses[i].Index = iIndex then
   begin
    Result := _UserDataClasses[i].aNode;
    Break;
   end;
 // Result := _VST.GetFirst(True);
 // while Assigned(Result) and (_VST.AbsoluteIndex(Result) <> Cardinal(iIndex)) do
 // Result := _VST.GetNext(Result, True);
end;

procedure DeleteUserNameNode(const UserName: string);
var
 Node: PVirtualNode;
begin
 DeleteUserNameNode(FindUserIDByName(UserName));
end;

procedure DeleteUserNameNode(iIndex: Integer);
var
 Node: PVirtualNode;
begin
 Node := FindUserNameByIndex(iIndex);
 if Assigned(Node) then
  _VST.DeleteNode(Node);
end;

// Aufruf
DeleteUserNameNode('Peter Wurst'); // Sucht den Namen, den Index (in den Klassendaten) und löscht den Node

DeleteUserNameNode(2); // Sucht in den Klassendaten nach einem Eintrag mit Index = 2 und löscht den dazugehörigen Node
Ob das mit dem Index nun so korrekt ist, muss ich erst noch sehen. Aber es erscheint mir logischer über die Variable Index der Klassendaten zu prüfen statt über den VST AbsoluteIndex.

Geändert von günni0 (17. Apr 2018 um 08:43 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
1.745 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#4

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 08:49
In TUserData eine Referenz auf PVirtualNode zu halten ist schon von vornherein ein Designfehler.
Der VST ist nur ein Abbild von deinen Userdaten in _UserDataClasses. Alle Operationen wie hinzufügen und löschen sollten darüber geschehen und danach dann ein aktualisieren/updaten/neuzeichnen des VST.
  Mit Zitat antworten Zitat
günni0

Registriert seit: 7. Mär 2018
260 Beiträge
 
#5

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 08:53
Delphi-Quellcode:
 iUserNameID := FindUserNameIDByName('Peter Wurst'); // // Helferfunktion, um den Index der Klasseninstanz für den Nutzer zu finden (um doppelten Code zu vermeiden)
 if iUserNameID > -1 then
  begin
   _UserDataClasses[iUserNameID].sUserName := 'Peter Lustig';

   _VST.InvalidateNode(_UserDataClasses[iUserNameID ].aNode); // ?
  end;
Danke für den Hinweis. Wie lade ich im obigen Beispiel denn dann einen Node neu, nachdem ich ihn geändert habe? Ohne InvalidateNode müsste ich erst die Maus über das VST bewegen, damit es neugezeichnet wird. Oder zeichnet man einfach das ganze VST mit _VST.Invalidate; neu?

Und das hier funktioniert dann ja auch nicht mehr
Delphi-Quellcode:
function FindUserIDByIndex(iIndex: Integer): PVirtualNode;
var
 i: Integer;
begin
 Result := nil;
 for i := 0 to _UserDataClasses.Count - 1 do
  if _UserDataClasses[i].Index = iIndex then
   begin
    Result := _UserDataClasses[i].aNode; // <=
    Break;
   end;
 // Result := _VST.GetFirst(True);
 // while Assigned(Result) and (_VST.AbsoluteIndex(Result) <> Cardinal(iIndex)) do
 // Result := _VST.GetNext(Result, True);
end;

Geändert von günni0 (17. Apr 2018 um 08:55 Uhr)
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
1.745 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#6

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 09:05
Das wird jetzt ineffizient in der Kommunikation.
Vorschlag: Baue ein kleines Beispielprojekt mit den wesentlichen Operationen (hinzufügen, löschen, ändern etc.) und lade es hier als Zip-Archiv hoch.
Anhand von richtigen Code kann dir besser geholfen werden.
  Mit Zitat antworten Zitat
günni0

Registriert seit: 7. Mär 2018
260 Beiträge
 
#7

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 09:09
Das ist nicht so einfach. Aber ich sehe schon, das ich die Referenz auf Node gar nicht weglassen kann.
Wenn ich einen Eintrag aus meiner ObjectList lösche, werden zwar die Daten gelöscht, aber nicht der dazugehörige "Node" selber im VST.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
1.745 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#8

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 09:11
Das ist nicht so einfach. Aber ich sehe schon, das ich die Referenz auf Node gar nicht weglassen kann.
Wenn ich einen Eintrag aus meiner ObjectList lösche, werden zwar die Daten gelöscht, aber nicht der dazugehörige "Node" selber im VST.
Doch, das ist ganz einfach mit dem Beispielprojekt. Man muss es nur machen! Ein TUserData mit zwei Properties, ein VST und dann noch zwei, drei Buttons und ein, zwei Editfelder.

Nach aktualisieren bzw. ändern der Objekte in der Objektliste machst du einfach ein VST.Clear und neu hinzufügen.
So hast du immer einen konsistenten Stand.
  Mit Zitat antworten Zitat
günni0

Registriert seit: 7. Mär 2018
260 Beiträge
 
#9

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 09:14
Wenn ich VST.Clear aufrufe, lösche ich aber auch alle meine Klasseninstanzen.
Das war ja genau das was ich wollte: lösche ich einen Node, löscht er die Klasseninstanz die dranhängt direkt mit.

Immer das ganze VST löschen und neuladen war auch genau das, was ich vermeiden wollte mit den Daten die ich im Hintergrund halte.

Geändert von günni0 (17. Apr 2018 um 09:20 Uhr)
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.294 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#10

AW: VirtualStringTree und Klasseninstanzen - Node Data finden

  Alt 17. Apr 2018, 09:39
Warum löscht er deine Instanz? Das kann nur der Fall sein, wenn du OnFreeNode implementiert hast. Das solltest du nicht machen wenn deine Instanzen von der ObjectList verwaltet werden.

EDIT: Du musst natürlich auch aufpassen, dass deine Instanz so lange existiert, wie es eine Node im VST gibt die darauf zugreift. Ansonsten hagelt es AVs.

Das bedeutet im Umkehrschluss: Erst die Nodes im VST löschen, dann die Instanz aus der ObjectList werfen und die Nodes wieder erzeugen.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:01 Uhr.
Powered by vBulletin® Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2018 by Daniel R. Wolf