Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Benachrichtigung bei Änderung an übergeordnete Elemente (https://www.delphipraxis.net/57468-benachrichtigung-bei-aenderung-uebergeordnete-elemente.html)

Keldorn 21. Nov 2005 20:58


Benachrichtigung bei Änderung an übergeordnete Elemente
 
Hallo

Ich habe z.B. folgende Konstrukte

Code:
Grid
  |-> Objectlist Spalten
                   |-> Objectliste mit Zellen(Tobject)
Das Grid hat eine property, mit dem ich auf ein Zellenobject zugreifen kann. Das Zellenobject hat dann wieder eigene propertys.
Ein Aufruf sieht dann z.B. so aus
Delphi-Quellcode:
Grid.cellvalue[acol,arow].asstring := 'Test';
Mein Problem: wie mache ich dem Grid klar, das sich die Zelle geändert hat? Die Setmethode bei der Cellvalue-property nützt mir nix, da sie nie aufgerufen wird, da ich auf das Object nie direkt zugreife. Also geht die Benachrichtigung nur bei der SetAsString-Methode, dort weiß ich aber das Grid nicht.

Wie macht man so was richtig und elegant? Hinterlegt man bei jedem Zellenobejct noch das grid? Oder hinterlegt man bei jedem „unterobject“ noch das übergeordnete und hangelt man sich dann hoch?

Danke, Frank

sh17 22. Nov 2005 05:44

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
Bau bei Deinem Zellobject ein OnChange-Ereignis ein, bei dem sich dann das Grid registriert.

Keldorn 22. Nov 2005 20:09

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
ok, das hatte ich nicht geschrieben, aber ein Ereignis nützt mir noch weniger. Innerhalb der VCL habe ich das auch noch nicht gesehen. Wenn ich ein ereignis nutze, brauch ich für jede Zelle ein notifyevent und innerhalb des Grid dann wieder eine Procedure, die auf dass ereignis reagiert und z.B. das Neuzeichnen eines Bereichs aufruft. Da kann ich das auch abkürzen, das Grid mit in jeder zelle ablegen und gleich die Proc zum Neuzeichnen aufrufen.
Aber so oder so habe ich eine zusätzliche Variable und dort je nach Gridgröße hundertfach das gleiche hinterlegt. Außerdem weiß die Zelle von ihrer Bildschirmposition nichts, von daher kann sie sich gar nicht selbst neuzeichnen.
Irgendwie sind nur noch Wände :wall:

Khabarakh 22. Nov 2005 20:20

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
Zitat:

Zitat von Keldorn
ok, das hatte ich nicht geschrieben, aber ein Ereignis nützt mir noch weniger. Innerhalb der VCL habe ich das auch noch nicht gesehen.

Dann hast du die Augen aber fest zugedrückt :wink: . Das ist das Standardverfahren in der VCL, eine Referenz auf das übergeordnete Objekt ist eher selten. Beispiel: TImage.Picture.OnChange zeigt auf TImage.PictureChanged.

Keldorn 22. Nov 2005 20:40

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
jepp, das sind in meinen (zugedrückten ;) ) Augen aber auch 2 Paar Schuhe.
1. Paar: ein Tpicture ist für mich nicht zwingend an eine Image gebunden, das kann auch ohne ein drübergeordnetes Image leben, da das das TPicture alleine auch nicht wissen kann, gehts es nur über Ereignisse.
2. Paar: TListcolumns etc. Die machen für sich alleine keinen richtigen sinn und sind immer einem Listview untergeordnet, dort wird nicht mit Ereignissen gearbeitet, dort gehts immer über owner-Eigenschaften.

sh17 24. Nov 2005 08:28

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
Noch ne Idee:

Zitat:

Zitat von Keldorn
Die Setmethode bei der Cellvalue-property nützt mir nix, da sie nie aufgerufen wird, da ich auf das Object nie direkt zugreife. Also geht die Benachrichtigung nur bei der SetAsString-Methode, dort weiß ich aber das Grid nicht.

Setze den Inhalt einer Zelle nicht direkt durch Aufruf der Zelle x,y, sondern lass das Grid den Inhalt der Zelle x,y setzen. Dann weißt das Grid auch welchen Bereich es neu zeichnen soll.

Keldorn 25. Nov 2005 19:27

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
hmm, das ist auch noch ne gute Idee.
Das mit den Ereignissen / Owner lasse ich wieder. Das würde bedeuten, daß ich in jeder zelle die Zellposition und ein Notifyevent/Owner-kompo hinterlegen muß. Das ist mir zuviel Speicher. Außerdem müßte ich dann bei jedem Sortieren und Löschen von Zeilen die Zellpositionen aller Zellen aktualisieren, das wird wohl nix werden.

momentan schwanke ich zwischen:
Variante1 (wie sh17):
das Grid hat die propertys CellValueAsString[x,y], CellValueAsFloat[x,y], CellValueAsInteger[x,y] ...
dann habe ich die Set-methode im Grid und kann die dort das Neuzeichnen der Zelle veranlassen. Die Set und Get-methoden verweisen dann auf die entsprechenden property des hinterlegten Cellvalue-Objekts.
Was mir daran nicht so richtig gefällt, ist die Logik beim zuweisen/abfragen der Werte. Grid.Zelle[x,y].as??? finde ich logischer als Grid.ZelleAs???[x,y]. Außerdem brauch ich dann für jede Property von Cellvalue auch eine entsprechende Property im Grid. Und eigentlich muß das Grid nicht wissen, welche Property Cellvalue bereitstellt.

Variante 2:
es gibt nur eine CellValue[x,y]-property. Das TCellvalue hat noch ein Bool-Feld, das true gesetzt wird, wenn sich die Zelle geändert hat. Bei det GetCellValue-Methode wird am Ende der Boolean-wert abgefragt, die Zelle neugezeichnet und der Bollean wieder false gesetzt.
Somit habe ich nur einen Bool, den ich zusätzlich hinterlege und ein paar Zuweisungen mehr im code.

Aber was nu wirklich am Besten ist, weiß ich immer noch nicht.

sh17 26. Nov 2005 12:51

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
Zu Variante 1.

Ich hab jetzt nicht den Code im Kopf, aber folgender Vorschlag:

Die Eigenschaft Cells[x,y] : TCell des Grids so implementieren, dass das Grid zwar mitbekommt, welche Zelle angefragt wird (bei Zugriff auf Cells[x,y]), dann aber nur die Zelle an sich zurück liefert. Der Zelle kannst Du dann zuweisen, was Du willst.

Elvis 26. Nov 2005 13:13

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
Zitat:

Zitat von Keldorn
Das mit den Ereignissen / Owner lasse ich wieder. Das würde bedeuten, daß ich in jeder zelle die Zellposition und ein Notifyevent/Owner-kompo hinterlegen muß. Das ist mir zuviel Speicher.

Hmpf? :shock: Egal ob direkt die Referenz des Grids oder der Event: In beiden Fällen wären es 4 Byte...:roll:
Wozu muss die Zelle ihre Position kennen? Ich dachte sie kennt die Spalte und Zeile in der sie sich befindet? :gruebel:
Du könntest das Event also in der Zeile auslösen. Diese kann dann entscheiden, ob sie es an ihr Grid weiterleitet...

Keldorn 26. Nov 2005 13:21

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
Zitat:

Zitat von Elvis
Wozu muss die Zelle ihre Position kennen? Ich dachte sie kennt die Spalte und Zeile in der sie sich befindet? :gruebel:
Du könntest das Event also in der Zeile auslösen. Diese kann dann entscheiden, ob sie es an ihr Grid weiterleitet...

Die zelle müßte die Position wissen, das Grid veranlaßt dann das neuzeichnen des entsprechenden Zeichenabschnitts. Somit kommen zu den 4 Bytes noch mal 8 dazu, sind schon 12.
Die Zelle selbst weiß die Position aber nicht, nur das Grid.

sh17 27. Nov 2005 12:31

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
oder Du machst es wie bei virtuellen Komponenten, Du rufst Grid.Repaint auf. Ist natürlich nichts automatisches

Keldorn 27. Nov 2005 18:22

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
Zitat:

Zitat von sh17
Ich hab jetzt nicht den Code im Kopf, aber folgender Vorschlag:
Die Eigenschaft Cells[x,y] : TCell des Grids so implementieren, dass das Grid zwar mitbekommt, welche Zelle angefragt wird (bei Zugriff auf Cells[x,y]), dann aber nur die Zelle an sich zurück liefert. Der Zelle kannst Du dann zuweisen, was Du willst.

oups, hatte deine Antort übersehen. Wenn ich dich verstnaden habe, geht das aber eben nicht. wenn ich das als
Delphi-Quellcode:
Property CellValue[ACol, ARow: Integer]:TcellValue read GetcellValue write SetCellValue
mache, wird bei einem Aufruf Grid.cellvalue[x,y].blabla:=blabla beim Grid nur die getmethode aufgerufen, nicht die set-methode. und in der Getmethode muß ich dann wissen, ob die Zelle neugezeichnet werden muß oder nicht, ich kann sie dort nicht immer neuzeichnen, da cellvalue auch bei Drawtext aufgerufen wird. Ich wäre so ganz schnell in einer Endlosschleife.

Zitat:

oder Du machst es wie bei virtuellen Komponenten, Du rufst Grid.Repaint auf. Ist natürlich nichts automatisches
geht auch nicht. Erstens habe ich das sicherlich Geschwindigkeitsproblem, wenn ich bei einer einzelnen Zelländerung immer das ganze Grid neuzeichne, außerdem kann ich so schlecht unterscheiden, ob es überhaupt neu gezeichnet werden muß. Ich würde immer Grid.repaint aufrufen, auch wenn die Zelle nicht im sichtbaren Bereich liegt.

Mfg Frank

sh17 28. Nov 2005 05:38

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
Zitat:

Zitat von Keldorn
geht auch nicht. Erstens habe ich das sicherlich Geschwindigkeitsproblem, wenn ich bei einer einzelnen Zelländerung immer das ganze Grid neuzeichne, außerdem kann ich so schlecht unterscheiden, ob es überhaupt neu gezeichnet werden muß. Ich würde immer Grid.repaint aufrufen, auch wenn die Zelle nicht im sichtbaren Bereich liegt.
Mfg Frank

Naja, das ist ja gerade das virtuelle. Das Grid bekommt Repaint und zeichnet den "sichtbaren" Bereich neu. Der ist ja nicht so groß. Wenn die geänderte Zelle nicht im sichtbaren Bereich war, ist das ja nicht schlimm-

Keldorn 2. Dez 2005 20:38

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
Sorry für die späte Antwort, aber in der Woche bin ich nicht zu meinem Problem gekommen
Zitat:

Zitat von sh17
Das Grid bekommt Repaint und zeichnet den "sichtbaren" Bereich neu. Der ist ja nicht so groß. Wenn die geänderte Zelle nicht im sichtbaren Bereich war, ist das ja nicht schlimm-

Doch , das ist schlimm ;), wenn bei einer Änderung einer nichtsichtbaren Zelle trotzdem immer das Grid beugezeichnet wird.

Aber so richtig weiter bin ich immer noch nicht. die Variante propertys CellValueAsString[x,y], CellValueAsFloat[x,y], CellValueAsInteger[x,y]..., die dann auf die entsprechenden CellValuepropertys zugreift ist wahrscheinlich doch am Besten.

Meine Idee mit einer Boolean-property bei TCellvalue geht natürlich auch nicht :wall:, da der Bool innerhalb von TCellvalue erst gesetzt wird, wenn GetCells komplett durchgelaufen ist. Eine Abfrage dort hat gar keinen Sinn.

sh17 3. Dez 2005 19:59

Re: Benachrichtigung bei Änderung an übergeordnete Elemente
 
vielleicht sehe ich das ganze ja falsch:

Du hast ein Object "Grid", was Deine Daten in Form von Zellen hält. Zum Benutzer hin ist nur ein kleiner Bereich sichtbar (wie z.B. beim StringGrid). Dieser Bereich muss vom Grid gezeichnet werden.

Warum musst Du alles neu zeichnen, wenn eine nicht sichtbare Zelle geändert wird.

Würde uns ein Screenshot weiterhelfen?


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:12 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz