Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Glaubensfrage: Auf zweite Form zugreifen (https://www.delphipraxis.net/146883-glaubensfrage-auf-zweite-form-zugreifen.html)

scrat1979 28. Jan 2010 19:02


Glaubensfrage: Auf zweite Form zugreifen
 
Hallo zusammen,

Leider ist mir kein besserer Titel eingefallen und sollte die Frage in der falschen Kategorie sein -> bitte verschieben.

Folgendes Szenario:
Wenn ich auf meinem Hauptformular ein 2. Formular öffne (dies sei z.B. ein Einstellungsdialog) und möchte nun nach dem Schließen des Formulares die eingegebenen Daten speichern. Wo würdet Ihr das machen bzw. gibt es da ein "Standard"?

Möglichkeit 1 wäre im OnClose des 2. Formulares die Daten zu speichern (z.B. in einer INI-Datei), dann müsste man ggf. im Hauptformular immer mit Formular2.Editxy.Text auf die Daten zugreifen.

Möglichkeit 2 wäre das Formular zu schließen und im Hauptformular nach Formular2.ShowModal etc. auf die Komponenten des Einstellungsdialoges zuzugreifen und die eigentliche Speicher-Routine somit ins Hauptformular zu packen.

Wie macht Ihr das in euren Projekten? Es kommt ja öfters mal vor, daß man in einem anderen Formular auf eingegeben Daten eines anderen Fensters zugrifen muss.

Hoffe auf aufschlußreiche Antworten :)

SCRaT

khh 28. Jan 2010 19:06

Re: Glaubensfrage: Auf zweite Form zugreifen
 
wir machen das nach Möglichkeit 2


Gruss kH

Die Muhkuh 28. Jan 2010 19:07

Re: Glaubensfrage: Auf zweite Form zugreifen
 
Zweiteres mit eigener Klasse für die Optionen

hoika 28. Jan 2010 19:12

Re: Glaubensfrage: Auf zweite Form zugreifen
 
Hallo,

in einer DB kann so ein Speichern schon mal fehlschlagen,
das Form zu schließen und erst dann zu speichern, finde ich nicht so gut.

Ich packe das Speichern in

OnOK (Button_OK.Click)

Schlägt das Speichern fehl, bleibt das Form offen !
Dann weiss der User wenigstens, das etwas faul ist.

On Form1 lese ich nach erfolgreichem Schließen
(ShowModal=mrOK) die Konfiguration neu aus
(ist eh der gleiche Befehl wie beim Laden von Form1)


OK

scrat1979 28. Jan 2010 19:50

Re: Glaubensfrage: Auf zweite Form zugreifen
 
Schonmal Danke für die Antworten.

@hoika: eigentlich mache ich das auch so :) Mir ging es nur um das Prinzip, ob die Aktionen in einer Prozedur/Mothode des ersten (Hauptformular) oder eben in dem eigentlichen Fenster (hier Einstellungsdialog) ausgeführt werden. Momentan erledige ich alles - wie Du erwähnt hast - im OnClick-Ereignis bzw. im OncloseQuery des 2. Formulares. Finde ich deshalb "sinnvoller", da die Aktionen ja eigentlich sinngemäß dem 2. Fomular zugehörig sind. Außerdem wird der Quellcode des Hauptformulares sonst zielich UNübersichlich, wie ich finde.

ALLERDINGS spiele ich gerade mit dem Gedanken, wie MuhKuh bereits geschrieben, eine eigene Klasse für die Einstellungen zu schreiben. Da ich öfters im Programm auf diverse Einstellungen zugreifen möchte, wäre dies glaube ich die sauberste Lösung...

Wenn man z.B. eine Klasse NameXY : TEinstellungen im Hauptformular deklariert und möchte nun in einem anderen Formular auf die Einstellungen zugreifen, macht ihr das, indem ihr mit MainForm.NameXY.PropertyXY darauf zugreift oder würdet Ihr in dem entsprechenden Fenster eine eigene Instanz erzeugen (die allerdings wieder zur Folge hat, dass die Einstellungen ja erst einmal geladen (z.B. INI-Datei) werden müssen...

Die Muhkuh 28. Jan 2010 19:55

Re: Glaubensfrage: Auf zweite Form zugreifen
 
Hi,

für Einstellungen benutz ich gerne das Singleton-Pattern und lagere die Klasse dafür in eine eigene Unit aus.

Je nach dem, wie "extrem" man das ganze braucht, kann man auch verschiedene "Writer" erstellen: Einer schreibts in eine Ini, einer in eine XML, ..., so kann der Benutzer auswählen, wie er die Daten speichern möchte (ein Switch zwischen XML und Registry macht z.B. Sinn, wenn die Anwendung portabel sein soll)

Namenloser 28. Jan 2010 20:25

Re: Glaubensfrage: Auf zweite Form zugreifen
 
Logik und Darstellung trennen!

Ich mache es immer so, dass ich zuerst eine Klassenstruktur erstelle, die die benötigten Daten beinhaltet, Methoden zum Zugriff und zur Verwaltung etc. bietet. Die GUI ist nur die letzte Schicht, sozusagen eine Maske, die auf die eigentlichen Daten aufgesetzt wird, und mir gefilterten Zugriff auf die eigentliche Verarbeitungsschicht bietet.

Alle datenbezogenen Formulare (z.B. Einstellungsfenster, Fenster zum Anlegen von Datensätzen usw.) werden zunächst mal aus der Liste der automatisch beim Programmstart erzeugten Formulare in der Projektdatei entfernt. Stattdessen wird in der jeweiligen Unit eine function erstellt (etwas mehr OOP wäre vllt. ein neuer Konstruktor), die
  • das zu modifizierende Datenobjekt als Parameter entgegennimmt,
  • automatisch das Formular erstellt,
  • die Werte aus den Datenobjekt in die Steuerelemente des Formulars schreibt und
  • das Formular anschließend per ShowModal anzeigt.
  • Danach wird ModalResult ausgewertet:
    • Wenn es mrOK entspricht, werden die Daten aus den Steuerelementen zurück ins Objekt geschrieben und die Funktion gibt True zurück.
    • Andernfalls bleibt das Objekt wie es ist und die FUnktion gibt False zurück.
Konkret aussehen könnte das so:
Delphi-Quellcode:
unit unContacts;

type

  TContact = class
  public
    Name: string;
    Email: string;
    Birthday: TDateTime;

    { ... }

    procedure SaveToFile;
    procedure LoadFromFile;
  end;

  TContactList = class(TObjectList)
  private
    { ... }
  public
    property Items[Index: integer]: TContact read GetItem write SetItem;
    procedure SaveToFile(FileName: string);
    { ...}
  end;

implementation

{...}

end.
Delphi-Quellcode:
unit unContactEditor;

uses
  unContacts;

type

  TfrmContactEditor = class(TForm)
    edName,
    edEmail,
    edBirthday: TEdit;
    btnOK, // ModalResult = mrOK
    btnCancel: TButton; // ModalResult = mrCancel
  end;

  function EditContactData(Contact: TContact): boolean;

implementation

function EditContactData(Contact: TContact): boolean;
var
  LForm: TfrmContactEditor;
begin
  LForm := TfrmContactEditor.Create(Application);
  LForm.edName.Caption := Contact.Name;
  LForm.edEmail.Caption := Contact.Email;
  LForm.edBirthday.Caption := DateToStr(Contact.Birthday);
  if LForm.ShowModal = mrOK then
  begin
    Contact.Name := LForm.edName.Caption;
    Contact.Email := LForm.edEmail.Caption;
    Contact.Birthday := StrToDate(LForm.edBirthday.Caption);
    Result := True;
  end
  else
    Result := False;
  LForm.Free;
end;

end.
Delphi-Quellcode:
unit unMain;

uses
  unContacts, unContactEditor;

type

  TfrmMain = class(TForm)
    lstContacts: TListBox; // Liste mit verschiedenen Kontakten drin
    btnEditContact: TButton; // In Liste selektierter Kontakt soll bearbeitet werden
    procedure btnEditContactClick(Sender: TObject);
  private
    ContactList: TContactList;
  end;


implementation

procedure TFrmMain.btnEditContactClick(Sender: TObject);
var
  LContact: TContact;
begin
  if lstContacts.ItemIndex >= 0 then
  begin
    // Anmerkung: Wir nutzen das hier nur, um elegant an das Objekt zu bekommen.
    // Die Objekte sind eigentlich in ContactList "gespeichert", lstContacts enthält
    // lediglich zusätzliche Referenzen.
    LContact := TContact(lstContacts.Items.Objects[lstContacts.ItemIndex]);
    if EditContactData(LContact) then
    begin
      // Dieser Block wird ausgeführt, wnen das Objekt verändert wurde
      // wir könnten jetzt irgendwelche Anzeigen aktualisieren oder abspeichern usw...
      ContactList.SaveToFile('blabla.blub');
      { ... } 
    end;
  end;
end;

end.
Ist nur hier "schnell" im Beitragseditor runtergeschrieben, aber ich hoffe das Prinzip wird klar.

scrat1979 28. Jan 2010 21:00

Re: Glaubensfrage: Auf zweite Form zugreifen
 
Vielan Dank für die vielen und ausführlichen Beiträge!!!

Also die Sache mit Singleton Patterns hört sich interessant an. Habe mir gerade mal ein paar Beispiele angesehen, so schwer ist das ja gar nicht :) Ich denke, das ist genau das, was ich benötige.

@NamenLozer: Trennung von Logik und Darstellung ist klar, ich denke in dem Fall der Einstellungen wäre das ja mit einem Singleton Pattern gut zu lösen

Danke Euch (mal wieder), ihr habt es echt drauf :cheers:

SCRaT

hoika 29. Jan 2010 06:46

Re: Glaubensfrage: Auf zweite Form zugreifen
 
Hallo,

das wichtige an #7 (u.a. ;) ) ist diese Funktion

function EditContactData(Contact: TContact): boolean;

OK, bei mir würde sie ExecuteForm_ContactData heissen.

Das Hauptform hat mit der Datenübergabe nur wenig zu tun (lose Kopplung).
Die Contact-Klasse kann so erweitert werden,
ohne dass in der Hauptform-Unit was geändert werden muss.

Ob das Singleton-Pattern hier notwenig ist,
ist eine andere Frage,
das Hauptform benutzt die Klasse ja eh als erstes
und könnte sie im FormCreate erzeugen.

Ich denke dabei auch an das Laden der Konfiguration und anderer Startdaten aus einer DB.
Wird das an einer einzigen Stelle gemacht, kann man es in eine Transaktion "sperren".


Heiko


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:57 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