Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - MainForm von einer Klasse aus benachrichtigen
LuMa86 - Mo 26.05.14 21:43
Titel: MainForm von einer Klasse aus benachrichtigen
Hallo,
Ich bin ja leider nur ein kleiner Hobby-Programmierer uns rätsel gerade an einer Frage: Wie kann ich aus meiner eigenen Klasse heraus, meine Main-Form benachrichtigen? Das heißt wenn etwas in meiner Klasse passiert, wird bei der MainForm ein Event ausgelöst, was dann etwas macht.
Aber irgendwie scheitert es bei mir schon am Konzept :/
Gruß
Moderiert von
Narses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Mo 26.05.2014 um 22:43
trm - Mo 26.05.14 22:07
Hallo.
Sobald Du im Code Deine Klasse auf Änderungen überprüfst, kannst Du in VCL mittels TMainForm auf Dein Hauptformular zugreifen.
Vielleicht hilft Dir ds schon ein wenig weiter.
LuMa86 - Mo 26.05.14 23:23
Hat geholfen wie ein Schlag auf den Hinterkopf :D Manachmal brauche ich einfach jemanden der mich mit dem Kopf druafstößt :)
Danke !
Xion - Di 27.05.14 08:11
Allgemein macht man sowas über Events, das ist flexibler als auf eine MainForm zuzugreifen, die sich dann später auch mal ändern könnte (oder hab ich den Hinweis nicht richtig verstanden?).
Das ganze sieht dann in etwa so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| type TSomethingChangedEvent = procedure(newValue: integer) of object; type TMyClass = class private vValue: integer; vOnSomethingChanged: TSomethingChangedEvent; public procedure DoSomething(x: integer); property OnSomethingChanged: TSomethingChangedEvent read vOnSomethingChanged write vOnSomethingChanged; end;
procedure TMyClass.DoSomething(x: integer); begin if x mod 2 <> vValue mod 2 then if Assigned(vOnSomethingChanged) then OnSomethingChanged(x mod 2); vValue := x; end; |
In der Main Klasse:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TMainForm.ChangedHandler(newValue: integer); begin if newValue mod 2 = 0 then ShowMessage('even value stored') else ShowMessage('odd value stored'); end;
procedure TMainForm.Create; var MyClass: TMyClass; begin MyClass := TMyClass.Create; MyClass.OnSomethingChanged := ChangedHandler; MyClass.DoSomething(20); MyClass.DoSomething(23); MyClass.DoSomething(25); MyClass.DoSomething(30); MyClass.Free; end; |
WasWeißDennIch - Di 27.05.14 08:11
Wieso denn ein Event des Formulars statt der Klasse? Oder hab ich das falsch verstanden?
Xion - Di 27.05.14 08:11
Mist, Doppelpost...die Knöpfe sind aber auch irgendwie schwer auseinander zu halten...also muss ich noch was konstruktives sagen...hmmm :oops:
Eine andere Möglichkeit wäre das Verknüpfen der Form mit der Klasse, ist aber typischerweise nicht so flexibel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| type TMyClass = class private vOwner: TForm; public constructor Create(Owner: TForm); procedure DoSomething(x: integer); end;
constructor TMyClass.Create(Owner: TForm); begin vForm := Owner; end;
procedure TMyClass.DoSomething(x: integer); begin vForm.Caption := 'hello world'; end; |
LuMa86 - So 01.06.14 18:38
Um euch zu beruhigen: WasWeißIchDenn's erster Post hat mich auf die Idee gebracht es mit Events zu machen. Ich weiß zwar nicht wie ich von selbst auf einmal darauf gekommen bin aber ich mache ziemlich genau so wie du in deinem ersten Post Xion :)
Danke für den Denkanstoß :)
Delete - So 01.06.14 23:49
Wenn sich deine Klasse standardmäßig in einer eigenen Unit befindet, müßtest du von dieser Unit aus deine Mainform-Unit referenzieren (= in deiner Klasse unter Uses die Haupt-Unit eintragen). Das kann problematisch werden, denn deine Mainform-Unit referenziert vermutlich bereits deine Klassen-Unit. Natürlich könntest du die Referenzierungen (Uses) jeweils unter Implementation vornehmen, so daß die beiden Klassen nichts von den Implementation-Referenzierungen der jeweils anderen "wissen". Doch auch das kann u.U. problematisch werden.
Deshalb ist es eleganter und programmtechnisch variabler, wenn du für solche Fälle ein Ereignis deklarierst, wie oben von Xion sehr schön gezeigt wurde. In deinem Mainform-Code weist du dem Ereignis dann nur noch den richtigen Event-Handler zu: Eine Methode deiner Mainform-Klasse, die das tut, was im Falle des Ereignisses getan werden soll.
Das Schöne an der Sache ist, daß einerseits auch andere Formulare diesem Ereignis einen Eventhandler zuweisen können und andererseits dieses Ereignis in deiner Klasse mehrfach verwendet werden kann: Ich hab z.B. ein Ereignis im Datenmodul, das in der Mainform diverse Statusanzeigen aktualisieren soll, und zwar bei diversen Aktionen, die im Datenmodul geschehen: AfterPost, AfterScroll und was weiß ich noch können in ihren Eventhandlern immer dasselbe Ereignis zur Aktualisierung der Statusanzeigen im Hauptformular auslösen. Das vereinfacht die Sache ungemein.
Früher hab ich das auch so gemacht mit dem gegenseitigen Referenzieren. Doch seit ich diese Event-Geschichte kenne und anzuwenden weiß, bin ich davon begeistert und mache das nur noch auf diese Weise.
ZeitGeist87 - Mo 02.06.14 15:48
Events sind die beste Lösung.
[OT]
Dazu fällt mir ein vor einigen Wochen gemachtes SVN-Commit wieder ein.
Meine Azubis dachten, sie seinen total clever:
Quelltext
1: 2: 3:
| @Private und Marshall<Name der Redaktion geändert>: Wenn ich noch EINMAL, EIN EINZIGES MAL den Aufruf von Formularen in Klassen sehe, gibt´s Ärger! Klassen haben keinerlei Zugriff auf irgendwelche Formulare. Ihr habt alles so aufzubauen, dass die Klasse die Logik übernimmt und wenn die passt, ein Formular eine Interaktion ausführt! Bei Gelegenheit gehe ich den kompletten Code in CArma durch und entferne alles, was mir nicht passt. Fehler dürft ihr dann suchen. |
Nersgatt - Mi 04.06.14 15:33
ZeitGeist87 hat folgendes geschrieben : |
Events sind die beste Lösung.
[OT]
Dazu fällt mir ein vor einigen Wochen gemachtes SVN-Commit wieder ein.
Meine Azubis dachten, sie seinen total clever:
|
Lol! na hoffentlich hast Du den Azubis schon beigebracht, wie sie sich die Unterschiede der Revisionen anschauen. Damit sie auch die Stellen finden, die Dir nicht passen. :D
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!