Einzelnen Beitrag anzeigen

Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.468 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: Daten zwischen dynamisch erstellten Formularen austauschen

  Alt 21. Apr 2014, 15:20
Die "Vorgeschichte":
Von einem Hautpformular (frmMain) kann, mit Click auf einen Button, ein Unterformular (frmKind1) mit
Delphi-Quellcode:
frmKind := TFrmKind.Create( Self );
frmKind.Show;
zur Laufzeit erzeugt und angezeigt werden.
Von frmKind1 aus kann, analog zu frmKind1, ein weiteres Unterformular (frmKind2) erzeugt und angezeigt werden.

Das Problem:
frmKind2 enthält ein Editfeld (edit1), dessen Inhalt an einen, auf frmKind1 befindlichen, ListView (lv) übergeben werden soll. Dazu ist in der Unit zu frmKind1 eine Prozedur zur Datenübergabe (siehe folgende Code) hinterlegt, die von frmKind2 aus aufgerufen wird.
Bei Aufruf der Prozedur gibt es eine Fehlermeldung/ Zugriffverletzung.
Delphi-Quellcode:
//Die Übergabeprozedur
procedure TfrmChild1.Datenuebergabe( String1: String );
var
  lvItem: TListItem;
begin
  lvItem := lv.Items.Add; //<-- An dieser Stelle gibt es eine Exception.
  lvitem.Caption := String;
end;

//Prozeduraufruf
procedure TfrmChild2.Button1Click( Sender: TObject );
begin
   frmChild1.Datenuebergabe( edit1.text );
end;
Was mache ich diesem Fall falsch bzw. wie kann ich die Datenübergabe elegant gestalten?
frmChild1 in Prozedur TFrmChild2.Button1Click ist vermutlich nicht initialisiert, denn im Code weiter oben steht:
Delphi-Quellcode:
frmKind := TFrmKind.Create( Self );
frmKind.Show;
Also frmKind und nicht frmChild1.

Das erste, was ich immer nach dem Erzeugen eines neuen Formulars in Delphi mache, ist die automatisch erzeugte Variablendeklaration loeschen, so dass ich nicht in Versuchung komme sie zu benutzen. Die einzige Ausnahme dabei ist das Hauptformular der Anwendung.

Es gibt diverse Moeglichkeiten, Dein Problem eleganter zu loesen. Eine waere beispielsweise, den Listview als Parameter an TFrmChild2 zu uebergeben, z.B. als Property und ihn dort direkt anzusprechen. Aber eigentlich kann ich Aviator nur zustimmen: Events waeren hier angesagt:

Delphi-Quellcode:
type
  TAddItemCallback = procedure(_Sender: TObject; const _Item: string) of object;

type
  TFrmKind2 = class(TForm)
  // [...]
  private
    FCallback: TAddItemCallback;
    procedure doCallback(const _Item: string);
  public
    property Callback: TAddItemCallback read FCallback write FCallback;
  end;

procedure TFrmKind2.doCallback(const _Item: string);
begin
  if Assigned(FCallback)
    FCallback(Self, _Item);
end;

procedure TFrmKind2.btnAddClick(Sender: TObject);
begin
  doCallback(edit1.Text);
end;
und

Delphi-Quellcode:

type
  TFrmKind1 = class(TForm)
  // [...]
  private
    procedure HandleCallback(_Sender: TObject; const _Item: string);
  // [...]
  end;


procedure TFrmKind1.Button1Click(Sender: TObject);
begin
  frmKind2 := TfrmKind2.Create(Self);
  frmKind2.Callback := HandleCallback;
  frmKind2.ShowModal;
end;

procedure TFrmKind1.HandleCallback(_Sender: TObject; const _Item: string);
var
  lvItem: TListItem;
begin
  lvItem := lv.Items.Add;
  lvitem.Caption := String;
end;
(Code ungetestet, nur so runtergetippt.)

twm
Thomas Mueller
  Mit Zitat antworten Zitat