Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Informationenübertragung von einer Unit auf die andere


leuchtfeuer - Di 14.03.17 23:18
Titel: Informationenübertragung von einer Unit auf die andere
Hallöle und guten Abend,

ich habe ein Programm erstellt, indem man durch einen Button zu einer zweiten Unit bzw. einem zweiten Formular gelangt.
Ich weiß auch, dass dieser Übergang nur einseitig passieren kann,also dass ich die Daten von der ersten Unit in der zweiten nicht wieder aufrufen kann.
Ich habe aber in der ersten mehrere Radio Buttons eingerichtet und möchte diese Informationen, also das man etwas ausgewählt hat,
an das zweite Formular übergeben, weil das sehr wichtig für meine Weiterführung ist.

Jedoch weiß ich nicht genau, wie ich dabei vorgehen soll.

Vielleicht weiß ja jemand einen netten Rat :)


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Di 14.03.2017 um 22:41


Delphi-Laie - Di 14.03.17 23:46

Informationsübertragung zwischen Units ist beid-/wechselseitig möglich.

Beim Klicken auf die Radiogruppe wird ein Ereignis ausgelöst, bei dem in der nachfolgende Ereignisbehandlungsroutine globale Variablen, die beide Units kennen, verändert werden können. Oder dieses Klickereignis löst zusätzlich ein weiteres Ereignis im anderen Formular bzw. in dessen Unit aus. Wie man das schafft, weiß ich aber nicht auf Anhieb.


Narses - Di 14.03.17 23:46

Moin und :welcome: in der EE!

user profile iconleuchtfeuer hat folgendes geschrieben Zum zitierten Posting springen:
Ich weiß auch, dass dieser Übergang nur einseitig passieren kann,also dass ich die Daten von der ersten Unit in der zweiten nicht wieder aufrufen kann.
Ich habe aber in der ersten mehrere Radio Buttons eingerichtet und möchte diese Informationen, also das man etwas ausgewählt hat
Das ist so nicht korrekt, natürlich kannst du auf Inhalte eines Formulars in einer anderen Form-Unit zugreifen, z.B. auf ein Element aus Form1 in Form2:

Delphi-Quelltext
1:
ShowMessage(Form1.Edit1.Text);                    
Dazu muss in der uses-Klausel von Unit2 allerdings die Unit1 aufgeführt werden, damit der Compiler auch weiß, dass du in Form2 auf Form1 zugreifen möchtest.

cu
Narses

EDIT:
user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
globale Variablen, die beide Units kennen
Das ist zwar nicht "falsch", ich würde aber im Sinne eines defensiven Programmierstils dringend davon abraten. Insbesondere, weil es gar nicht notwendig ist. Man kann ja auch so auf Eigenschaften eines anderen Formulars zugreifen, wenn das denn sein muss. :idea:


Delphi-Laie - Di 14.03.17 23:53

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Dazu muss in der uses-Klausel von Form2 allerdings Form1 aufgeführt werden


Nicht eher dessen​ Unit, also (normalerweise) Unit1?


Narses - Di 14.03.17 23:56

Moin!

user profile iconDelphi-Laie hat folgendes geschrieben Zum zitierten Posting springen:
Nicht eher dessen​ Unit, also (normalerweise) Unit1?
Jup, natürlich der Unit-Name, danke für die Korrektur. Hab´s oben auch korrigiert. mir geht so langsam aber sicher die Delphi-Übung flöten... *seufz*

cu
Narses


Slipstream - Mi 15.03.17 07:07

user profile iconleuchtfeuer hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe aber in der ersten mehrere Radio Buttons eingerichtet und möchte diese Informationen, also das man etwas ausgewählt hat,
an das zweite Formular übergeben, weil das sehr wichtig für meine Weiterführung ist. Jedoch weiß ich nicht genau, wie ich dabei vorgehen soll.

Wenn ich dich rightig verstehe, soll Form2 (Unit2) wissen, welche RadioButtons in Form1 (Unit1) ausgewählt worden sind. Da gibt es grundsätzlich mehrere Möglichkeiten. Die korrektere besteht aus meiner Ansicht in Properties: Du legst in Unit2 Properties fest und belegst diese Properties vor dem Aufruf von Form2 von Form1 aus:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
implementation
{$R *.dfm}
{ TForm1 }

uses
  Unit2;

procedure TForm1.Button1Click(Sender: TObject);
var
  Form2Result : Integer;
begin
  Form2.Radio1Checked := Radio1.Checked; 
  Form2.Radio2Checked := Radio2.Checked; 
  Form2.Radio3Checked := Radio3.Checked; 
  ...
  Form2Result := Form2.ShowModal;
  ...
end;

In Form2 legst du zuvor natürlich die Properties fest:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
  ...
  private
    fRadiio1Checked : Boolean;
    fRadiio2Checked : Boolean;
    fRadiio3Checked : Boolean;

    Function  GetfRadio1Checked: Boolean;
    Function  GetfRadio2Checked: Boolean;
    Function  GetfRadio3Checked: Boolean;

    Procedure SetfRadio1Checked(Const Value : Boolean);
    Procedure SetfRadio2Checked(Const Value : Boolean);
    Procedure SetfRadio3Checked(Const Value : Boolean);

  public

    Property Radio1Checked : Boolean read GetfRadio1Checked write SetfRadio1Checked;
    Property Radio2Checked : Boolean read GetfRadio2Checked write SetfRadio2Checked;
    Property Radio3Checked : Boolean read GetfRadio3Checked write SetfRadio3Checked;
  end;

Var
  Form2 : TForm2;




Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
implementation
{$R *.dfm}
{ TForm2 }

Function  TForm2.GetfRadio1Checked : Boolean;
begin
  Result := fRadiio1Checked;
end;


Function  TForm2.GetfRadio2Checked : Boolean;
begin
  Result := fRadiio1Checked;
end;


Function  TForm2.GetfRadio3Checked : Boolean;
begin
  Result := fRadiio1Checked;
end;

Procedure TForm2.SetfRadio1Checked(Const Value : Boolean);
begin
  fRadiio1Checked := Value;
end;

Procedure TForm2.SetfRadio2Checked(Const Value : Boolean);
begin
  fRadiio1Checked := Value;
end;

Procedure TForm2.SetfRadio3Checked(Const Value : Boolean);
begin
  fRadiio1Checked := Value;
end;


In deinen Form2-Methoden greifst du dann immer nur auf die Variable mit dem vorangestellten f zu: fRadio1Checked usw.

Möglichkeit 2 ist eleganter und weniger aufwendig: Du erstellst in Form2 ein Public Array of Boolean, das von Form1 aus belegt werden kann:


Delphi-Quelltext
1:
2:
3:
4:
...
  public
    RadioChecks : Array[1..3of Boolean:
...

Im OnClick-Handling von Form1, wo du Form2 aufrufst, übergibst du dann einfach diese Werte so wie oben, diesmal aber an das Array:


Delphi-Quelltext
1:
2:
3:
4:
5:
...
  Form2.RadiChecks[1] := Radio1.Checked;
  Form2.RadiChecks[2] := Radio2.Checked;
  Form2.RadiChecks[3] := Radio3.Checked;
...


leuchtfeuer - Mi 15.03.17 17:32

Dankeschön an alle :) Das hat mir alles sehr geholfen, besonders die große Erklärung.


Slipstream - Fr 17.03.17 06:21

user profile iconleuchtfeuer hat folgendes geschrieben Zum zitierten Posting springen:
Dankeschön an alle :) Das hat mir alles sehr geholfen, besonders die große Erklärung.

Sehr erfreut, dass dir mein kleines Tutorial geholfen hat. Doch das ist noch lange nicht alles, denn wir haben noch nicht geklärt, wie Informationen von Form2 an Form1 übertragen werden können. Beim Aufruf der Form2 von Form1 aus mit der Function ShowModal gibt diese beim Schliessen von Form2 einen Wert zurück, denn du in Form2 selber festlegen kannst, und zwar mit Modalresult [http://docwiki.embarcadero.com/CodeExamples/Seattle/en/ShowModal2_%28Delphi%29]. Beim Aufruf von Form2 via ShowModal hat ModalResult standardmässig den Wert 0, der in der Konstante mrNone festgelegt ist. Wenn du in Form2 der Variablen ModalResult einen anderen Wert als 0 zuweist, wird Form2 automatisch geschlossen. Wenn du Form2 mit Close schliesst, wird ModalResult automatisch auf mrCancel gesetzt. Soweit zur Informationsübergabe beim Schliessen von Form2.

Es gibt aber auch Fälle, wo Form1 auf Aktionen in Form2 reagieren soll, während Form2 sichtbar ist. Dazu muss man in beiden Units ein paar Vorbereitungen treffen. Zuerst braucht man einen neuen Type in Form2, der in etwa so aussieht:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
unit Unit2;

interface

uses
  ...

type
  TUpdateEvent = Procedure of Object;

type
  TForm2 = class(TForm)
  ...

Als nächstes braucht man ein Property in Form2:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
...
private
  fUpdateForm2 : TUpdateEvent;

public
  ...
  Property OnUpdateForm2 : TUpdateEvent read fUpdateForm2 write fUpdateForm2;
  ...

Das Ereignis in Form2, das in Form1 Reaktionen hervorrufen soll, wird so ausgelöst:


Delphi-Quelltext
1:
if Assigned(fUpdateForm2) then fUpdateForm2;                    

Das heisst, dass du zB in einer Button-Ereignisbehandlung, deren Resultat in Form1 sichtbar sein soll, am Ende einfach diese Codezeile einfügst.

Um jetzt in Form1 darauf reagieren zu können, machst du dir erstmal eine Procedure, die die Reaktionen ausführt:

Procedure TForm1.ReaktionAufForm2Ereignis;
begin
MachIrgendwas;
end;
Damit Form1 aber weiß, wann ReaktionAufForm2Ereignis ausgeführt werden soll, weist du vor dem Aufruf von Form2 dem soeben in Form2 deklarierten Ereignis deine Reaktions-Procedure zu:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm1.Button1Click(Sender: TObject);
begin
  Form2.Radio1Checked := Radio1.Checked; 
  Form2.Radio2Checked := Radio2.Checked; 
  Form2.Radio3Checked := Radio3.Checked; 
  ...
  Form2.OnUpdateForm2 := ReaktionAufForm2Ereignis;
  Form2.Show;
  ...
end;

Damit wird jetzt jedesmal, wenn in Form2 if Assigned(fUpdateForm2) then fUpdateForm2; ausgeführt wird, in Form1 ReaktionAufForm2Ereignis aufgerufen.