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 Komponente in modalem Formular ändern? (https://www.delphipraxis.net/108377-komponente-modalem-formular-aendern.html)

Marco Steinebach 12. Feb 2008 17:12


Komponente in modalem Formular ändern?
 
Hallo Listers,
ich hab eine Verständnis bzw. Frage zum guten Stil.
Ich habe ein Formular (Form1) mit einer Listview.
Ein zweites, modales, Formular (Form2) soll nach eingaben durch den Benutzer, die Eintäge der Listview des Hauptformulars ändern.
Form2 hat folgenden Konstruktor:
Code:
    constructor create(AOwner: TComponent;
                       var l: TListView); reintroduce;
Der Aufruf in Form1:
Code:
  with TForm2.Create (self, l) do
  try
    ShowModal;
  finally
    free;
  end;
So weit, so gut. Aber gibt es dafür keine, sagen wir, geschicktere Lösung? Wenn das Create mit Self als Owner aufgerufen wird, komm ich denn dann nicht an die Inhalte der aufrufenden Klasse?
Problem ist, daß nicht nur ein Eintrag der Liste, sondern unter Umständen alle Einträge geändert werden sollen.
Für 'nen Tipp wäre ich dankbar.
Viele Grüße
Marco

Muetze1 12. Feb 2008 17:26

Re: Komponente in modalem Formular ändern?
 
Ich würde den Konstruktor so lassen wie er ist sondern viel mehr das ShowModal mit reintroduce neu einführen mit dem zusätzlichen Parameter. Dort gibt Form1 seinen ListView mit und in der Form2 wird das ListView mit Assign() dazu gebracht, die Elemente zu übernehmen (im ShowModal, vor dem inherited Aufruf). Wenn dann der inherited ShowModal Aufruf mit einem mrOk zurück kommt, dann wird das Assign anders herum ausgeführt, also beim übergebenen ListView wird Assign() aufgerufen mit dem ListView der Form2 als Parameter. Damit ist Ok/Cancel etc abgedeckt und es ist eine ordentliche Trennung.

Just my 2 Cents...

/PS: Bitte benutze die Tags für den Code anstatt den allgemeinen Tags.

Marco Steinebach 12. Feb 2008 19:15

Re: Komponente in modalem Formular ändern?
 
Hi Muetze und alle anderen,
ich steh, glaube ich, gerade ein bißchen auf dem schlauch.
also:
Delphi-Quellcode:
type
  TForm2 = Class (TForm)
  lModal: TListView; // die Listview des Modalen Formulars.
  // der Constructor wird nicht mehr überschrieben.
  Function ShowModal (l: TListView): Integer; Reintroduce;
end;

...
function TForm2.ShowModal (l: TListView): Integer;
begin
  lModal.Assign (l);
  result := inherited ShowModal;
end;
So weit, so klar.
Nun der Aufruf in Form1, hier ist lHaupt die ListView, die ja von Form2 geändert werden soll:
Delphi-Quellcode:
with TForm2.Create (self) do
  if ShowModal (lHaupt) = mrOk then
...
und jetzt? Also was mir im moment nicht klar ist, wie kriege ich das umgekehrte Assign hin?
Bitte nochmal um Hilfe.
Herzliche Grüße
Marco

Pfoto 12. Feb 2008 22:06

Re: Komponente in modalem Formular ändern?
 
Hallo Marco!

es sieht so aus, als müsstest du das Kopieren
der ListView schon in Form2 nach Klick auf "Ok"
durchführen.

Ich mache es so:
Delphi-Quellcode:
  with TForm2.Create(self) do
  try
    { Eigene Methode zum Übergeben der Daten }
    Init( [ Hier Daten übergeben ] );
    If ShowModal = mrOk then
      Finalize( [ Hier Daten aus Form2 holen ] );
  finally
    free;
  end;
In der öffentlichen Methode "Finalize" kannst
du nochmals die ListView der ElternForm übergeben
und eben entsprechend in Form2 manipulieren, d.h.
die Ergebnisdaten der ListView in Form2 übergeben etc.

Wobei ich bisher immer nur "Austausch"-Records mit
Daten hin- und her gereicht und nicht den Inhalt
des Objektes kopiert habe.


Gruß
Pfoto

Muetze1 12. Feb 2008 23:27

Re: Komponente in modalem Formular ändern?
 
@Pfoto: Warum sollte die Form1 von aussen auf die Elemente von TForm2 zugreifen? Das widerspricht der Datenkapselung doch komplett.

@Marco Steinebach: Dein Ansatz ist schon fast komplett. Ich hatte es so beschrieben und meinte eigentlich nur noch eine Zeile mehr:

Delphi-Quellcode:
type
  TForm2 = Class (TForm)
  lModal: TListView; // die Listview des Modalen Formulars.
  // der Constructor wird nicht mehr überschrieben.
  Function ShowModal (l: TListView): Integer; Reintroduce;
end;

...
function TForm2.ShowModal (l: TListView): Integer;
begin
  lModal.Assign (l);

  result := inherited ShowModal;

  if result = mrOk then
    l.Assign(lModal);
end;
Mehr nicht. Datenkapselung gewart, Konstruktor noch immer Original und die Daten wandern und her...

semo 13. Feb 2008 07:46

Re: Komponente in modalem Formular ändern?
 
ich hätte es auch so gelöst:

Delphi-Quellcode:
with TForm2.Create(self) do
begin
  try
    Init(ZeigerAufListView);
    If ShowModal = mrOk then
      MachWasMitListView;
  finally
    free;
  end;
end;
wobei ich mich frage was du in form 2 mit dem listview machst.
scheinbar verarbeitest du da ja die daten der liste.
wäre doch dann sinnvoll eine liste der daten zu übergeben anstatt gleich den kompletten listview bzw einen zeiger darauf.

Marco Steinebach 13. Feb 2008 18:32

Re: Komponente in modalem Formular ändern?
 
Hallo,
Zitat:

Zitat von M. Hassmann
ich hätte es auch so gelöst:

Delphi-Quellcode:
with TForm2.Create(self) do
begin
  try
    Init(ZeigerAufListView);
    If ShowModal = mrOk then
      MachWasMitListView;
  finally
    free;
  end;
end;

tja, ;-), Problem ist, das mein Hauptformular nicht weiß, was es mit der ListView machen soll, so das, bei mir, die Procedure MachWasMitListView nicht weiß, was sie machen soll. ;-)
Zitat:

Zitat von M. Hassmann
wobei ich mich frage was du in form 2 mit dem listview machst.
scheinbar verarbeitest du da ja die daten der liste.
wäre doch dann sinnvoll eine liste der daten zu übergeben anstatt gleich den kompletten listview bzw einen zeiger darauf.

Es ist eine Liste von Dateien, die im modalen Formular, je nach auswahl des Benutzers, auf bestimmte weise Umbenannt werden sollen. Davon sind aber nicht immer alle betroffen: zu deutsch, kann man wählen, ob Umlaute konvertiert werden sollen. Nur die Dateien, für die das auch sinn macht, sprich, in denen umlaute vorkommen, werden natürlich umbenannt. Und genau die umbenannten Dateien, müssen, in der eigentlich ListView geändert werden. Ich kann sie nicht einfach neu erstellen, da nicht klar ist, in welchen Verzeichnissen die Dateien liegen.
Wenn wir hier nichts schönes finden, dann werdne die Daten vorher in einer Liste gesammelt, an ShowModal übergeben, und hinterher ausgewertet, welche Daten sich geändert haben, und die dann in der ListView des Hauptformulars nachgetragen. tja, Datenkapselung adee...

@Muetze1:
Ja, *lach*, manchmal sieht man den Wald vor lauter Bäumen nicht. Ich hab nicht dran gedacht, daß die übergebene (l) ja nur eine Objekt-Referenz ist, und man darauf natürlich auch ein Assign machen kann.
Aber, ..., es funktioniert nicht. Ich kriege beim
Delphi-Quellcode:
Function TForm2.ShowModal (l: TListView): integer;
begin
 lModal.Assign (l);
eine EConvertErrorException. Die übergebene L ist, laut meinem Debugger, aber nicht nil. Muß ich assign selber schreiben, oder wie, ...
Fragende Grüße
Marco

Muetze1 13. Feb 2008 18:51

Re: Komponente in modalem Formular ändern?
 
Ich habe mir schon gedacht, dass die TListView direkt kein Assign() implementiert. Die TListItems tun dies aber. Somit bei den beiden Assign() Aufrufen einfach zuvor noch ein Items. einfügen. Im Endeffekt sollte es dann so aussehen:

Delphi-Quellcode:
function TForm2.ShowModal (l: TListView): Integer;
begin
  lModal.Items.Assign (l);

  result := inherited ShowModal;

  if result = mrOk then
    l.Items.Assign(lModal);
end;
Aber grundlegend muss ich allen zustimmen, dass eine Arbeit mit einer visuellen Komponenten zur Datenhaltung wirklich schlechter Stil ist. Hier liegt eindeutig keine Trennung von Oberflächen und Daten vor. Im Normalfall sollte dein Programm eine nicht visuelle Liste haben, welche alle Daten entsprechend hält. Die Oberfläche kann dann mit Nutzung der Liste die Oberfläche befüllen (hier: das ListView). Wenn du nun einen zweiten Dialog hast der die Liste bearbeitet, dann sollte diesem nur diese nicht visuelle Liste übergeben werden und dann kann sie dort bearbeitet werden. Danach kann Form1 seine Oberfläche an den veränderten Listinhalt anpassen. Diese Trennung von Oberfläche und Daten ermöglicht mehr Freiheiten beim gestalten der Oberfläche. So kann die Oberfläche die gleichen Daten auch später z.B. in einem VST darstellen, ohne das die Datenverwaltung umgestellt werden muss. Oder wenn der Kunde eine Spalte in der ListView einfach nicht mehr sehen will, dafür aber beim Bearbeiten im Form2-Dialog. So hättest du z.Z. mit deinem Aufbau keine Chance diese Änderung einfach zu machen, da dir dann die Daten der Spalte in Form1 definitv fehlen. Bei der Trennung der Daten ist es nur eine Zeile beim befüllen der ListView für Form1.

Marco Steinebach 14. Feb 2008 19:46

Re: Komponente in modalem Formular ändern?
 
Hallo Muetze1 und alle Anderen,
okay, okay, überredet. Es stimmt natürlich, da gibt's nix dran zu rütteln, es ist definitiv schlechter Stil. Es war mehr die Faulheit, weil ich nicht zwei gleiche Listen halten wollte, und alle Operationen, wie verschieben, löschen, etc. verdoppeln.
Aber jetzt ist alles so, wie es sich gehört, es gibt zwei getrennte Listen und, natürlich, auch keine Datenübergabeprobleme mehr. ;-)
Aber trotzdem danke, wer weiß, wo ich sowas nochmal brauche.
Viele herzliche Grüße
Marco
p.s.: und jetzt mache ich mich an die entwirrung deiner Signatur!


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