![]() |
Formular neu zeichnen erzwingen
Hallo,
ich bräuchte eine Möglichkeit von jeder Stelle im Programm, auch von meinen Units aus, das Hauptformular zum Neuzeichnen zu zwingen. Ich dachte mir, dass das über eine Message gehen sollte. Weis hier jemand wie man dies am besten umsetzt. Danke und Gruß Dieter |
Re: Formular neu zeichnen erzwingen
Du könntest Invalidate des Formulars aufrufen, das sorgt für ein komplettes Neuzeichnen.
|
Re: Formular neu zeichnen erzwingen
Hallo,
das Hauptform hat ja eine globale Form-Variable.
Delphi-Quellcode:
Ich würde aber im Main-Form eine Methode definieren (RefreshForm),
unit X
implementation uses Form1; // Hauptform begin Form1.Invalidate die nur Invalidate aufruft. Das lässt sich besser Debuggen, wenn du mal einen "Refresh"-Fehler suchst. Heiko |
Re: Formular neu zeichnen erzwingen
Hallo zusammen und Danke für die Antworten.
An euren Antworten kann ich erkennen, dass ich mich nicht richtig ausgedrückt habe. Ich versuche es am besten noch mal. Also was ich möchte ist eine grundsätzliche Lösung, ich suche eine z.B. Procedure FormRefresh die ich in meine, z.B. Komponenten; Klassenobjekten, einbaue welche mir die Form auf der sie sich befinden zum Neuzeichnen zwingt. Das ganze muss sehr flexibel sein, da ich den Namen der Form nicht kenne. Ich hoffe es ist nun ein bisschen klarer geworden was ich erreichen möchte. Gruß Dieter |
Re: Formular neu zeichnen erzwingen
Versuch doch, mit GetParentForm das Formular zu ermitteln, welches Du dann mit Invalidate/Refresh/Repaint neu zeichnen kannst.
|
Re: Formular neu zeichnen erzwingen
Falsche Frage bzw. falsch aufgebauter Code, das ist dein Problem.
Eine Komponente belegt nur einen kleinen Teil eines Formulars oder sogar nur eines Containers. Warum sollte die Komponente also das Neuzeichnen auslösen? Es gibt keinen Grund, da die Komponente auf dem Bereich nicht zugreifen kann. Da liegt eindeutig ein Designfehler vor. Wenn du nun behauptest du änderst z.B. die Systemfarben und willst erreichen das das Fenster nun grün gezeichnet wird, dann ist dein angefragter Weg auch falsch, da du dann das Ändern der Systemfarben falsch umgesetzt hast. Es gibt bei allen Dingen entsprechende Möglichkeiten und um bei dem Beispiel zu bleiben hättest du nach Änderung der Systempalette ein Broadcast rausschicken müssen der über diese Änderung informiert und alle Programme mit Nutzung der Systemfarben sind verpflichtet auf diese Botschaft zu reagieren und ihre Farben neu zu ermitteln und die Paletten neu anzumischen. Also nochmals: Dein Ansatz ist falsch bzw. der Aufbau. Stell lieber eine detaillierte Beschreibung ein, dann kann man eher aufzeigen wo das Problem liegt. |
Re: Formular neu zeichnen erzwingen
Zitat:
Delphi-Quellcode:
wm_RefreshForm definierst Du als
SendMessage({MainForm.Handle}, wm_RefreshForm, 0, 0);
Delphi-Quellcode:
und in der MainForm muss Du nur noch die Message abfangen mit
wm_RefreshForm = wm_User + 42;
Delphi-Quellcode:
Sowohl der MainForm.Handle als auch wm_RefreshForm muss in all Deinen Units bekannt sein.
TMainForm = class(TForm)
private procedure wmRefreshForm(var Msg: TMessage); message wm_RefreshForm; end; procedure TMainForm.wmRefreshForm(var Msg: Tmessage); begin Self.Invalidate; end; War es das, was Du suchst? Gruß, Carsten |
Re: Formular neu zeichnen erzwingen
Hallo zusammen,
@ Muetze1 ich habe hinter den Komponenten Objekte (jede Komponente ist eine Instanz von einem Objekt). Durch die Eingaben eines Users wird nun das Objekt hinter der Komponente geändert. Diese Änderung wirkt sich nun auch auf andere Objekte aus. Um nun den Komponneteninhalt der geänderten Objekte zu aktuallisieren soll das ganze Formular neu gezeichnet werden. Dann ist mann nämlich frei von der Bildschirmaktuallisierung der einzelnen Komponenten und kann sich ausschließlich um das Verhalten seiner Objekte kümmern. Was ist bitte daran falsch, ich glaube das ist das Grundprinzip der OOP. Denn hier wird der eigentliche Programmablauf und Datenfluß in den Objekten abgearbeitet und die Visuelle Seite wird in den Komponenten geregelt. @ DeddyH Zitat:
Wenn ich dann auf die Form zugreifen kann, sollte es zumindest in den Komponenten gehen. @ Carsten1234 Ich glaube nicht, dass ich damit ans Ziel komme, trotzdem Danke Gruß Dieter |
Re: Formular neu zeichnen erzwingen
Zitat:
Du solltest ein ![]() Ein Beispiel hierfür sind die datensensitiven Steuerelemente von Delphi (TDBEdit, TDBGrid etc.) Sie reagieren auf Änderungen am Dataset und stellen sich dann ggf. selbstständig neu dar. Dabei weiss ein Dataset gar nicht, ob und welche visuellen Controls vorhanden sind, es soll es auch gar nicht wissen. Zitat:
![]() |
Re: Formular neu zeichnen erzwingen
Hallo alzaimar
Zitat:
Ich wollte eigentlich nur erreichen, dass die Komponenten (die ja die richtigen Daten beinhalten) neu gezeichnet werden, wenn ich nämlich das Formular in der Taskleiste ablege und wieder öffne werden meine Komponenten korrekt dargestellt. Seit gestern Abend weis ich allerdings, dass ich durch ein Form.Repaint dies nicht erreichen kann, da die Form scheinbar nicht komplett neu gezeichnet wird. :oops: Nun mal Butter bei den Fischen. Leider war kein Beispiel für Delphi bei dem Link für Observerpattern dabei und die Umsetzung nach Delphi bekomme ich nicht hin, zu wenige Kenntnisse. Wie erstelle ich ein Überwachungsmuster in Delphi und wie melde ich meine Komponenten dort an und ab und wie werden diese Komponenten zum Neuzeichnen veranlasst? Hast du mal ein Beispiel in Delphi für mich oder waren das nur Schlagworte die du drauf hast? :zwinker: Gruß Dieter |
Re: Formular neu zeichnen erzwingen
|
Re: Formular neu zeichnen erzwingen
Zitat:
|
Re: Formular neu zeichnen erzwingen
Hallo
@Alzaimar mit so oder einer ähnlichen Antwort muss man bei einer kleinen Provokation rechnen. Was muss ich tun damit du mir verzeihst? und mir dein Beispiel doch noch gibst? @Guido danke für den link, ich sehen schon etwas klarer, wobei ich immer noch Umsetzungsprobleme habe. :oops: @ Alle Ich habe verstanden, dass ich eigentlich nicht anderes habe als ein Objekt, in diesem Objekt verwalte ich eine Zeigerliste die auf eine Methode zeigen. 1 kann diese Methode in einer Komponente sein z.B. Componente.update oder muss diese sich im Programm direkt befinden 2 wie melde ich diese Methode in meine Liste an bzw. ab 3.wie wird mein Überwachungsobjekt benachrichtigt, dass sie etwas tun muss. ich habe z.B. zwei Objekte TPerson und TPersonList und zwei Komponenten eine TPersonEdit und TPersonScrollbox jetzt wird eine Person geändert z.B. Namen innerhalb der Objekte klappt das, nur der Bildschirm wird nicht aktualisiert. Wie kann ich das mit einem Observer lösen? wie ich schon sagte, blicke ich mit dieser Observergeschichte noch nicht ganz durch, scheint aber ganz interessant zu sein, weil sich scheinbar damit eine ganze reihe von Problemen lösen lassen. Ich hoffe ihr helft mir weiter. Gruß Dieter |
Re: Formular neu zeichnen erzwingen
1. Kann diese Methode in einer Komponente sein z.B. Componente.update oder muss diese sich im Programm direkt befinden?
Verstehe die Frage nicht ganz, aber die Methode muss eine Ereignisbehandlungsprozedur sein. 2. Wie melde ich diese Methode in meine Liste an bzw. ab? Das Subject hat dafür die beiden Methoden "MeldeAn" und "MeldeAb" (Aus dem Beispiel entnommen). 3. Wie wird mein Überwachungsobjekt benachrichtigt, dass es etwas tun muss? Das Subject benachrichtigt die angemeldeten Beobachter (d.h. es ruft die angemeldeten Ereignisbehandlungen auf). Das Subject selbst sollte natürlich das Objekt sein, in dem die sich ändernden Daten gehalten werden und dementsprechend "merken", wenn sich daran was ändert. Beispielsweise könnte das Subject eine TCollection enthalten, die hat dann auch ein Ereignis "Changed", in dem du entsprechend reagieren kannst. "Changed" wird immer aufgerufen, wenn sich an einem TCollectionItem etwas ändert (TCollection speichert TCollectionItems). Zitat:
Das heisst dann, dass TPersonList das Subject ist und TPersonEdit und TPersonScrollbox sind Beobachter. Ändert sich jetzt etwas an der Personenliste, dann werden die Beobachter benachrichtigt und können sich aktualisieren. |
Re: Formular neu zeichnen erzwingen
Hallo Opti,
Hast du schon mal versucht herauszubekommen, warum
Delphi-Quellcode:
funktioniert, ohne das man da explizit sagen muss, das sich der Titel neu zeichnen muss.
Form1.Caption := 'Hallo Delphi';
Versuch doch einfach mal herauszubekommen wie das geht und mach das bei deinen Komponenten ähnlich. Nur mal so als Hinweis: Wenn in der Frage das Wort "erzwingen" drin steht, dann hast du schon einen Denkfehler. mfg DerDan |
Re: Formular neu zeichnen erzwingen
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
|
Re: Formular neu zeichnen erzwingen
Zitat:
Er möchte ja mehrere voneinander unabhängige Objekte davon informieren, dass eine Änderung eingetreten ist, die evtl. eine Aktualisierung erfordern. Grundsätzlich folgt er damit ja dem Prinzip Daten und GUI zu trennen und ist auf dem richtigen Weg. |
Re: Formular neu zeichnen erzwingen
Hallo zusammen
@Guido, die Schatten lichten sich, scheinbar liegen meine Verständnisprobleme mehr bei den neuen von mir nicht bekannten Bezeichnungen. Ich habe es geschafft, mit der Unit aus deinem Link, dass die Benachrichtigung Objekt zur Komponente funktioniert. Erstmal bin ich darüber sehr Happy. Zitat:
@Alzaimar, wenn du ein Spaßversteher bist dann liegen wir beide auf derselben Wellenlänge. :zwinker: Wow deine Unit sieht ja richtig Prof aus. Allerdings hätte ich mir gewünscht, dass ein paar Kommentare drinn sind, um sie besser zu verstehen. Ich habe zum Beispiel nicht verstanden warum du ein Hilfsobjekt zu TSubject machst. In TSubject arbeitest du schon mit einer TObjectList was ich sehr gut finde da sie leichter zu händeln ist als ein Array. In der Unit SampleClass.pas machst du noch ein Objekt TObserverableObject für was wird dieses benötigt? wenn ich das richtig sehe könnte ich doch auch gleich von TSubject ableiten oder? Was sind den die Vorteile gegenüber der Unit von Guido die ja recht einfach gehalten ist? So das sind eigentlich genug Fragen für den frühern Morgen Gruß und einen schönen Tag Dieter |
Re: Formular neu zeichnen erzwingen
Zitat:
Die Klasse TSubject definiert eine Struktur, die eine Nachricht 'Changed' an andere (per Subscribe angemeldete) Objekte zu verteilen. Die Klasse TCallbackHelper dient nur dazu, eine Methodenzeiger in einer Liste zu verwalten. Ich hätte auch ein 'Array Of TObserverNotification' verwenden können, dann hätte ich mir diese Hilfsklasse sparen können. Aber ich mag dynamische Arrays (hier) nicht. Gut gut, die Unit 'Observer' hat uns also die Grundbausteine für das Pattern bereitgestellt. Wie gehen wir damit um? Wir haben also unsere Daten-Klassen, die wir um jeweils ein 'Subject' erweitern und dieses Subjekt (Man könnte es auch 'Änderungsnachricht-Verteil-O-Mat' nennen, aber 'Subject' ist irgendwie kürzer. Gut, schwerer zu verstehen, aber kompakt. Geradlinig. Straff. Drahtig. Sch..Schön. Darauf kommt es an. :freak: Äh.. *vomthemaabschweifweilbikinismitinhaltflanieren* Wo war ich? ach ja. Also, wir erweitern unsere Datenklasse um so ein 'Subject', damit andere Programmteile, die von den Änderungen an dieser Datenklasse informiert werden müssen, dort anmelden können. Dazu implementieren sie so eine Methode vom Typ 'TObserverNotification' und melden sich eben dort an. Ich habe in der Klasse 'TObserverableObject' die Grundfunktionalität bereitgestellt, die eine Datenklasse, die Änderungen weiterverbreiten kann, so benötigt. Wenn Du deine Datenklassen von diesem Objekt ableitest, haben deine Klassen bereits alles, was ein Observerpattern so braucht. Du musst es nur noch anwenden, d.h. die Visualisierungsklassen bzw. Formulare per Subscribe anmelden und fertig. Jeder 'Setter' einer Eigenschaft muss zum Schluss nur die 'Changed'-Methode aufrufen (wenn die Property geändert wurde). Mit 'BeginUpdate' kann man die Benachrichtigung puffern, also mehrere Änderungen vornehmen, ohne das jedesmal alle Subscriber benachrichtigt werden. Das würde ja nerven. Wenn ich also viele Eigenschaften eines Objektes ändern will, rufe ich 'BeginUpdate' auf, ändere wie ein Weltmeister und schließe die Änderungen mit 'EndUpdate' ab. Ich kann das auch sein lassen, dann werden aber bei *jeder* Änderung die Subscriber benachrichtigt. Die Idee von Guido ist natürlich für einige Objekte vielleicht mit weniger Aufwand zu implementieren, aber wenn in deiner Anwendungen viele Objekte durch die Gegend fliegen, die alle irgendwie dargestellt werden, hättest Du bald Probleme mit den ganzen Messages. Ich mach das ab und an genauso, wenn ich nur ein oder zwei Klassen habe, die visualisiert werden müssen, aber wenn es mehr werden :kotz: ... Das Observer-Pattern bietet dir hier eine orthogonale (also gleichförmige), robuste und einfache Möglichkeit an, dieses Chaos zu vermeiden. Bei der komplexen Softwareentwicklung kommt es imho in erster Linie darauf an, robust, einfach, verständlich und damit wartbar und erweiterbar zu programmieren und nicht kurz und knapp (a.k.a 'Quick and Dirty'). |
Re: Formular neu zeichnen erzwingen
Hallo Alzaimar,
Das nenn ich mal eine Beschreibung, warum nicht gleich so! :zwinker: Ich wusste, dass du dir etwas bei diesem TObserverableObject gedacht hast, konnte nur nicht erkennen was. Das kann man bestimmt manchmal recht gut gebrauchen. Wenn ich also meine Klasse von TSubjekt ableite habe ich die selbe Funktion wie bei Guido's Unit und für zusätzliches ein- und ausschalten der sofortigen Chances kann ich dann von TObserverableObject ableiten, so habe ich beide Möglichkeiten (Nicht schlecht H. Specht). Also nochmals danke für die Unit, werde sie am Wochenende mal testen und sagt dir dann noch Bescheid ob es geklappt hat. Wobei ich Guidos Unit nicht schlecht finde die funktioniert bis jetzt tadellos. Ach ja bevor ich es vergesse, könntest du mir bitte 'bikinismitinhalt' an deine nächste Antwort mit dranhängen. Im voraus meine besten Dank dafür. :zwinker: Gruß Dieter |
Re: Formular neu zeichnen erzwingen
Hallo Alzaimar
Ich habe deine Klasse getestet und für einsatzfähig befunden. :zwinker: Ne, Spass beiseite, deine Observer Unit ist einfach Super. Und sie ist genauso leicht und mit dem selben Aufwand wie Guidos TSubjekt zu implementieren Die Idee mit Begin- und Endupdate ist sehr gut besonderst wenn man eine Eingabemaske abschließt und dann die ganzen Änderungen ins Objekt übernimmt, dann hat man nicht die ganzen Änderungsaufrufe der einzelnen Setter sondern nur einen einzigen( einfach Klasse diese Idee). Trotzdem habe ich noch eine Frage und zwar bei TObserverNotification = procedure(Sender, Origin: TObject) of object; Für was steht das Sender, Origin: TObject in diesen Ereignisaufruf. Für welchen Zweck hast du das gemacht, denn ohne Grund steht das da ja nicht. So durchdacht wie diese Unit ist. Was ich auch nicht in der Hilfe gefunden habe ist TMethod obwohl ich angezeigt bekomme, dass sie in der Unit System ist. Vielleicht kannst du mir hierzu auch ein paar Worte sagen. Verzeih mir die vielen Fragen, aber ich möchte es verstehen, und nicht nur ohne zudenken einsetzen. Vielleicht kannst du dir ja am Strand bei 35°C ein schattiges Plätzchen suchen und mir die Fragen beantworten. Ich weis, dass das ein sehr großes Opfer ist, was ich da verlange, aber ich werde dich dafür, dann auch in mein Nachtgebet mit einschließen. :zwinker: Gruß Dieter Ach ja und denke bitte an den ’MädchenImBikini’ Anhang. |
Re: Formular neu zeichnen erzwingen
Hi,
Diese Sache mit dem Inhalt als Anhang gestaltet sich schwierig, weil ich meine Digicam nicht an den Laptop bekomme und ich keinen Bock habe, meinen Laptop als Fotomaten zu verwenden. Das würde auch irgendwie auffallen, wenn ich mit dem Laptop lechzend durch die Gegen wetze und allen Inhalten nachstelle, dabei das Laptop aufgeklappt und von mir weg zu denen hinhalte und hecktisch auf den Space/Enter-Taste haue. Es ist so schon schwer genug, den Aufsehern zu entkommen :freak: Zitat:
|
Re: Formular neu zeichnen erzwingen
Hallo Alzaimar,
danke für die Erklärung des Ereignisses. leider hast du nichts zu TMethode gesagt ich finde einfach nichts darüber weder in der Hilfe noch sonstwo oder weist du auch nicht darüber Bescheid. Aufseher? Welche Aufseher? Seit wann gibt es am Strand der Türkei Aufseher, die gibts doch nur in Schweden. :zwinker: Gruß Dieter |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:22 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