GUI Design und Objektliste
-
- Beiträge: 1059
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
GUI Design und Objektliste
Hallo allseits !
Falls das Thema woanders besser passt, bitte ich die Admins es zu verschieben.
Es geht um ein GUI Design für eine Applikation. Nennen wir sie der Einfachheit halber eine Kundenverwaltung.
Die klassischen Funktionen neben dem Hauptformular sind:
- Kunden suchen
- Kunden bearbeiten
Aus der Ergebnisliste der Kundensuche sollen Formulare zur Kundenbearbeitung aufgerufen werden.
Diese Formulare (und auch Formulare von anderen Fomulartypen) sollen nicht modal aufgerufen und angezeigt werden.
Im Gegensatz zu modalem Design hat der Anwender mehr Möglichkeiten (z.B. zwei Kunden im Fenster direkt gegenüber zu stellen), allerdings braucht es dann auch eine Verwaltung der existierenden Formulare, um sie sauber zu schließen und etwaige offene Speichervorgänge anzumahnen oder auch um bereits existierende Formulare nur in den Vordergrund zu bringen.
Meine Frage geht dahin welches die beste Methode zum Verwalten heterogener Objekte in Form einer "Liste" ist.
A.) mit TObjectlist
B.) mit TStringlist
C.) andere Variante?
Zur Verwaltung heterogener Objekte/Formulare müsste in der Liste ein Objekttyp und eine ID zum Objekt mitgeführt werden, um es schnell in einer Liste auffinden zu können. Als Elementanzahl könnte man die Liste nach oben hin begrenzen, wenn die Performance leidet, ich gehe mal von einer durchschnittlichen Objektanzahl von 20-50 aus.
Variante A mit TObjectlist bringt außer dem Suchen bestimmter Objekte alles mit, auch das freigeben aller in der Liste enthaltenen Objektelemente (evtl kann man im OnCloseQuery eines Formulares abfangen ob geänderte Daten zu speichern sind)
Ich bitte um Erfahrungen und Empfehlungen für unterschiedliche Verfahren.
Danke im Voraus
Falls das Thema woanders besser passt, bitte ich die Admins es zu verschieben.
Es geht um ein GUI Design für eine Applikation. Nennen wir sie der Einfachheit halber eine Kundenverwaltung.
Die klassischen Funktionen neben dem Hauptformular sind:
- Kunden suchen
- Kunden bearbeiten
Aus der Ergebnisliste der Kundensuche sollen Formulare zur Kundenbearbeitung aufgerufen werden.
Diese Formulare (und auch Formulare von anderen Fomulartypen) sollen nicht modal aufgerufen und angezeigt werden.
Im Gegensatz zu modalem Design hat der Anwender mehr Möglichkeiten (z.B. zwei Kunden im Fenster direkt gegenüber zu stellen), allerdings braucht es dann auch eine Verwaltung der existierenden Formulare, um sie sauber zu schließen und etwaige offene Speichervorgänge anzumahnen oder auch um bereits existierende Formulare nur in den Vordergrund zu bringen.
Meine Frage geht dahin welches die beste Methode zum Verwalten heterogener Objekte in Form einer "Liste" ist.
A.) mit TObjectlist
B.) mit TStringlist
C.) andere Variante?
Zur Verwaltung heterogener Objekte/Formulare müsste in der Liste ein Objekttyp und eine ID zum Objekt mitgeführt werden, um es schnell in einer Liste auffinden zu können. Als Elementanzahl könnte man die Liste nach oben hin begrenzen, wenn die Performance leidet, ich gehe mal von einer durchschnittlichen Objektanzahl von 20-50 aus.
Variante A mit TObjectlist bringt außer dem Suchen bestimmter Objekte alles mit, auch das freigeben aller in der Liste enthaltenen Objektelemente (evtl kann man im OnCloseQuery eines Formulares abfangen ob geänderte Daten zu speichern sind)
Ich bitte um Erfahrungen und Empfehlungen für unterschiedliche Verfahren.
Danke im Voraus
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2808
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: GUI Design und Objektliste
Was sind denn das für heterogene Objekte? Unterscheiden sie sich stark oder könnten sie alle von einer Basisklasse ableiten. Im letzteren Fall brauchst du eventuell den Objekttyp gar nicht, sondern kannst alles über Vererbung und Polymorphie lösen. Dann wäre eine generische Liste deines Basistyps eine Lösung.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
-
- Beiträge: 1059
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
Re: GUI Design und Objektliste
Ich hab mir deinen Ansatz auch angesehenm.fuchs hat geschrieben:Was sind denn das für heterogene Objekte? Unterscheiden sie sich stark oder könnten sie alle von einer Basisklasse ableiten. Im letzteren Fall brauchst du eventuell den Objekttyp gar nicht, sondern kannst alles über Vererbung und Polymorphie lösen. Dann wäre eine generische Liste deines Basistyps eine Lösung.

Es geht um quasi alle Formulare die in einer Applikation so vorkommen können.
Suchformulare, Eingabeformulare (sagen wir für Stammdaten aller Art), Reportformulare und was weiß ich noch alles.
Mit deinem Ansatz könnte ich für jeden Objekttyp eine eigene Liste führen, was mir aber noch nicht die Suche nach einem bestimmten (Formular-) Objekt abdeckt. Bei der Suche in einer nicht von außen identifizierbaren Objektliste (also eine Suche bei der ich das Objekt "angreifen" muss, um z. B. eine Property auszulesen) wäre ich vermutlich auch langsamer (oder etwa nicht?).
Kann auch sein dass ich da etwas nicht verstehe ???
Die Formulare sind praktisch alle von TForm abgeleitet, sonst aber sehr unterschiedlich und mittels Lazarus-GUI erzeugt.
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2808
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: GUI Design und Objektliste
Ah, ich verstehe. Es geht dir um die Formulare, nicht um die angezeigten Datenobjekte.
Nun gut.
Wenn ein Datensatz aufgerufen wird, schaust du in der Map nach ob schon ein Eintrag mit der ID drin ist. In diesem Fall nimmst du das bestehende Formular und zeigst es an.
Nun gut.
Dafür ist es ja nicht wichtig, um was für ein Formular es sich handelt. Eine Liste vom Typ der Basisklasse würde ausreichen.charlytango hat geschrieben:um sie sauber zu schließen und etwaige offene Speichervorgänge anzumahnen
Auch hier ist eventuell die Art des Formulars uninteressant. Wenn deine Datensätze datenbankweit eindeutig identifizierbar sind. Zum Beispiel per GUID (https://de.wikipedia.org/wiki/Globally_ ... Identifier). Dann brauchst du zum geöffneten Formular nur den Datensatz-Identifikator abzulegen. Zum Beispiel in einer generischen Map:charlytango hat geschrieben:auch um bereits existierende Formulare nur in den Vordergrund zu bringen
Code: Alles auswählen
TDataFormHashTable = specialize TFPGMap<String, TForm>;
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
-
- Beiträge: 1059
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
Re: GUI Design und Objektliste
Yep -- es geht um Formulare, die je nach Usersinstellung entweder (nach MDI-Vorbild) frei schwebend angezeigt werden oder auch per TPagecontrol oder TTabControl in ein Hauptformular eingedockt werden sollen.
Leider sind die Datensätze nicht datenbankweit eindeutig per GUID identifizierbar sondern nur als Tabellenname samt deren Primary Key (integer, autoincrement)
Ich habe mir nochmal deine Lösung angesehen, die verwendet eine TFPObjectList.
Ich könnte also eine Liste gleichartiger Elemente so realisieren dass ich ein Formular (TBaseForm) erstelle und dieses mit den nötigen Properties zum Identifizieren des dann gesuchten Formulars ausstatte.
Vom Formular TBaseForm leite ich dann alle meine Arbeitsformulare ab.
TFPObjectList verwaltet (im Gegensatz zu TObjectList) lt Wiki Objekte ohne "Notification" -- was ist damit gemeint ?
In TFPObjectList werden also Objekte und nicht nur die Pointer darauf verwaltet.
Ein Formular hinzuzufügen würde also so funktionieren:
Da tauchen aber auch noch Fragen auf:
Das Objekt f1 wird erzeugt und der Liste hinzugefügt. Nachdem das Objekt selbst in der Liste verwaltet wird, sollte es eigentlich kopiert werden, oder ?
Und muss dann das quasi temporär erzeugte Objekt f1 nicht noch zerstört werden?
Deine Funktion dazu:
function Add(AObject: TForm): Integer;
Folgt man der Objekthierarchie wird das im Objekt TFPObjectList als
realisiert und dort wiederum als
endet. Leider setzt da mein Verständnis aus -- ist das nun noch das Objekt oder nur "mehr" ein Pointer drauf ?
LG
Leider sind die Datensätze nicht datenbankweit eindeutig per GUID identifizierbar sondern nur als Tabellenname samt deren Primary Key (integer, autoincrement)
Ich habe mir nochmal deine Lösung angesehen, die verwendet eine TFPObjectList.
Ich könnte also eine Liste gleichartiger Elemente so realisieren dass ich ein Formular (TBaseForm) erstelle und dieses mit den nötigen Properties zum Identifizieren des dann gesuchten Formulars ausstatte.
Code: Alles auswählen
type
TBaseForm= class(TForm)
Label1: TLabel;
private
FiID: string;
FsTyp: string;
procedure SetiID(AValue: string);
procedure SetslTyp(AValue: string);
public
property psTyp:string read FsTyp write SetslTyp;
property piID:string read FiID write SetiID;
end;
Code: Alles auswählen
type
TMeinFormular1 = class(TBaseForm)
In TFPObjectList werden also Objekte und nicht nur die Pointer darauf verwaltet.
Ein Formular hinzuzufügen würde also so funktionieren:
Code: Alles auswählen
//Deine Objektliste erzeugen
oWindowList := TWindowsList.Create
//Neues Formular erzeugen und der Objektliste hinzufügen
procedure TfrmMain.Button1Click(Sender: TObject);
var
f1:TMeinFormular1;
begin
f1:=TMeinFormular1.Create(Nil);
f1.psTyp:='Kunde'; //Typ festlegen
f1.piID:=1; //ID festlegen
oWindowList.Add(tf1);
end;
Das Objekt f1 wird erzeugt und der Liste hinzugefügt. Nachdem das Objekt selbst in der Liste verwaltet wird, sollte es eigentlich kopiert werden, oder ?
Und muss dann das quasi temporär erzeugte Objekt f1 nicht noch zerstört werden?
Deine Funktion dazu:
function Add(AObject: TForm): Integer;
Folgt man der Objekthierarchie wird das im Objekt TFPObjectList als
Code: Alles auswählen
Function TFPObjectList.Add(AObject: TObject): Integer; {$ifdef CLASSESINLINE}inline;{$endif}
begin
Result:=FList.Add(AObject);
end;
Code: Alles auswählen
function TFPList.Add(Item: Pointer): Integer;
begin
if FCount = FCapacity then
Self.Expand;
FList^[FCount] := Item;
Result := FCount;
FCount := FCount + 1;
end;
LG
- m.fuchs
- Lazarusforum e. V.
- Beiträge: 2808
- Registriert: Fr 22. Sep 2006, 19:32
- OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
- CPU-Target: x86, x64, arm
- Wohnort: Berlin
- Kontaktdaten:
Re: GUI Design und Objektliste
Auch damit wären sie eindeutig identifizierbar:charlytango hat geschrieben:Leider sind die Datensätze nicht datenbankweit eindeutig per GUID identifizierbar sondern nur als Tabellenname samt deren Primary Key (integer, autoincrement)
Code: Alles auswählen
var
UniqueId: String;
begin
UniqueId := TableName + ':' + IntToStr(Id);
end;
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de
-
- Beiträge: 1059
- Registriert: Sa 12. Sep 2015, 12:10
- OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
- CPU-Target: Win 32/64, Linux64
- Wohnort: Wien
Re: GUI Design und Objektliste
m.fuchs hat geschrieben:Auch damit wären sie eindeutig identifizierbar:charlytango hat geschrieben:Leider sind die Datensätze nicht datenbankweit eindeutig per GUID identifizierbar sondern nur als Tabellenname samt deren Primary Key (integer, autoincrement)
Code: Alles auswählen
var UniqueId: String; begin UniqueId := TableName + ':' + IntToStr(Id); end;
Du hast völlig recht -- was mir nicht ganz klar ist:
wo liegen die Vorteile einer TFPGMap
Code: Alles auswählen
TDataFormHashTable = specialize TFPGMap<String, TForm>;
Code: Alles auswählen
TWindowlist = class(TFPObjectList)
PS: dein Code aus dem Generator funktioniert fein, danke !