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