![]() |
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:
Der Aufruf in Form1:
constructor create(AOwner: TComponent;
var l: TListView); reintroduce;
Code:
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?
with TForm2.Create (self, l) do
try ShowModal; finally free; end; 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 |
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. |
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:
So weit, so klar.
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; Nun der Aufruf in Form1, hier ist lHaupt die ListView, die ja von Form2 geändert werden soll:
Delphi-Quellcode:
und jetzt? Also was mir im moment nicht klar ist, wie kriege ich das umgekehrte Assign hin?
with TForm2.Create (self) do
if ShowModal (lHaupt) = mrOk then ... Bitte nochmal um Hilfe. Herzliche Grüße Marco |
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:
In der öffentlichen Methode "Finalize" kannst
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; 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 |
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:
Mehr nicht. Datenkapselung gewart, Konstruktor noch immer Original und die Daten wandern und her...
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; |
Re: Komponente in modalem Formular ändern?
ich hätte es auch so gelöst:
Delphi-Quellcode:
wobei ich mich frage was du in form 2 mit dem listview machst.
with TForm2.Create(self) do
begin try Init(ZeigerAufListView); If ShowModal = mrOk then MachWasMitListView; finally free; end; end; 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. |
Re: Komponente in modalem Formular ändern?
Hallo,
Zitat:
Zitat:
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:
eine EConvertErrorException. Die übergebene L ist, laut meinem Debugger, aber nicht nil. Muß ich assign selber schreiben, oder wie, ...
Function TForm2.ShowModal (l: TListView): integer;
begin lModal.Assign (l); Fragende Grüße Marco |
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:
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.
function TForm2.ShowModal (l: TListView): Integer;
begin lModal.Items.Assign (l); result := inherited ShowModal; if result = mrOk then l.Items.Assign(lModal); end; |
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 09:53 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz