Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   TMS TDBAdvGrid und regelm. Refresh (https://www.delphipraxis.net/171581-tms-tdbadvgrid-und-regelm-refresh.html)

Medium 13. Nov 2012 14:55

TMS TDBAdvGrid und regelm. Refresh
 
Tach zam!

Ich habe hier einen gewöhnlichen Fall von Query->DataSource->DBGrid, wobei das Grid das TDBAdvGrid von TMS ist. Die Daten in dem Grid sollen alle 2 Sekunden aktualisiert werden, also habe ich einen TTimer der alle 2sec ein Refresh der Query auslöst.

Leider versucht das Grid immer die Selektion möglichst in die Mitte des Grids zu schubsen, weshalb es fürchterlich flackert wenn man gerade im Grid scrollt und ein Refresh kommt. Auch möchte ich, dass der User sein Grid in der Position behält, in die er es selbst gescrollt hat, und es eben nicht zur Selektion hüpft (die möglicherweise schon ausserhalb des sichtbaren Bereichs liegt).
Das Verhalten hat zudem auch den Nebeneffekt, dass nur die ersten paar X Zeilen (X ist scheinbar willkürlich) mit Text gefüllt werden, die darunter bleiben leer. Bis man scrollt oder das Grid sonstwie zum Aktualisieren bringt.

Ich nutze abgesehen von Bands keine besonderen Dinge, kein OwnerDraw, nix. BeginUpdate/EndUpdate hat keinen Effekt, und auch Enable-/DisableControls vom Query nicht. Wie wäre o.g. Verhalten am besten abstellbar? Besten Dank schon mal!

Sir Rufo 13. Nov 2012 16:22

AW: TMS TDBAdvGrid und regelm. Refresh
 
Wenn du mich fragst, wie das am besten abzustellen ist ... nimm ein normales Grid und lass dir die Daten damit anzeigen. Dann hast du das selber in der Hand, was und wie die Aktualisierung in das Grid kommt. Und natürlich auch die Positionierung.

Ja, das ist umständlich und aufwändig, aber das andere ist nervig :)

p80286 13. Nov 2012 16:37

AW: TMS TDBAdvGrid und regelm. Refresh
 
@Sir Rufo :thumb::thumb:

Nur soo umständlich ist es auch nicht, eine Stringliste mit den Ergebnissen, jedes Feld durch ; getrennt von der Query holen und für das Schreiben in das Grid mit Delimited Text aufbereiten, das wäre mit 10 Zeilen locker zu erreichen.

Gruß
K-H

rapante 13. Nov 2012 18:20

AW: TMS TDBAdvGrid und regelm. Refresh
 
Hy,
dieses Verhalten hatte mich auch immer gestört...
So sollte die Position erhalten bleiben:
Delphi-Quellcode:

rowdelta := -1 + DBGrid.Row;
row := DBGrid.DataSource.DataSet.RecNo;

DBGrid.DataSource.DataSet.DisableControls;

DBGrid.DataSource.DataSet.Refresh;

DBGrid.DataSource.DataSet.RecNo := row;
DBGrid.DataSource.DataSet.MoveBy(-rowDelta);
DBGrid.DataSource.DataSet.MoveBy(rowDelta);

DBGrid.DataSource.DataSet.EnableControls;

Medium 13. Nov 2012 23:58

AW: TMS TDBAdvGrid und regelm. Refresh
 
Sir Rufo und p80286, das mag wohl alles sein, in einem relativ neuen Projekt. Leider ist dies Pflege eines fertigen. Zudem wird es ein ungleich größerer Aufwand, für andere Grids im Projekt die Suchleiste, das Grouping, die fertige Druckfunktion und so Nettigkeiten selbst zu bauen. (Sollen ja dann doch alle möglichst ähnlich im Design sein, und das Standard Grid dort hin zu prügeln ist nochmals ein ziemlicher Akt.) Um das alles nicht tun zu müssen, kauft man sich letztlich doch Komponenten :?

Ich hatte gehofft, dass es ggf. noch eine Möglichkeit gibt, das Dataset weniger... "invasiv" zu refreshen, so dass das Control wirklich einfach nur unterm Poppo die Daten geändert bekommt, oder so etwas wie ein
Delphi-Quellcode:
if not myGrid.IsScrolling then myQuery.Refresh;
kombiniert mit einem
Delphi-Quellcode:
myGrid.CenterSelection := false;
:)

@rapante: Das versuche ich morgen! Merci!

haentschman 14. Nov 2012 06:05

AW: TMS TDBAdvGrid und regelm. Refresh
 
Moin...8-)

Idee: Im OnScroll des Datasets wirfst du einen Timer an der dir ein Flag setzt. Im OnTimer setzt du das Flag zurück. Refresh nur wenn Flag nicht gesetzt ist. Damit kannst du scrollen ohne das aktualisiert wird. Achtung: OnScroll wird imho auch ausgelöst beim Laden der Daten bei jedem Datensatz. ggf. müßte die Timergeschichte dabei unterbunden werden.

Medium 20. Nov 2012 09:30

AW: TMS TDBAdvGrid und regelm. Refresh
 
Ich bin heute endlich wieder dazu gekommen mich darum zu kümmern. Leider mit keinem Erfolg auf ganzer Linie. Ich habe alle Vorschläge hier ausprobiert, aber das Grid bleibt felsenfest bei deinem Rumgezuckel. Before/AfterScroll waren auch meine Favoriten, leider bezieht sich das aber auch nur auf das DataSet - heisst: Wenn ich im Grid den Scrollbalken noch "in der Hand" habe, wird dennoch das Refresh durchgeführt, da der Zeitraum zwischen den Events ja leider nur das gaaanz kurze Stück genau beim Wechsel des aktiven Datensatzes ist.

Auch der TMS Support konnte mir keinen Lösungsweg aufzeigen. (Sind Refreshes in Grids mit Scrollbalken so exotisch!?)

Meine bisher letzte Idee war es OnMouseDown/Up meinen Timer zu schalten, nur leiiider wird das Event nur bei Klicks im Clientbereich des Grids ausgelöst, nicht auf dem Scrollbalken. Wie könnte ich denn da evtl. dran kommen?

shmia 20. Nov 2012 10:38

AW: TMS TDBAdvGrid und regelm. Refresh
 
Zitat:

Zitat von Medium (Beitrag 1191996)
Sind Refreshes in Grids mit Scrollbalken so exotisch!?

Eigentlich schon!
Wenn du alle 2 Sekunden ein Dataset refreshst und damit alle 2 Sekunden die immer gleiche SQL-Query absendest missbrauchst du die Datenbank für einen Zweck für die sie nicht konstruiert wurde.

Eine Datenbank ist kein Subsystem dass man im Pollingbetrieb ständig abfragen sollte.
Dein Problem ist also nicht das Grid, sondern die Ursache liegt viel tiefer am Design deiner Anwendung.

Medium 20. Nov 2012 11:42

AW: TMS TDBAdvGrid und regelm. Refresh
 
Ich wüsste nicht wirklich, wie ich die folgende Situation ohne jetzt Mannwochen in ein eigens dafür entwickeltes Subsystem sonst sinnvoll abbilden sollte:

Teilnehmer: Eine bzw. mehrere S7 SPS, ein Server, N Clients

Unser Serversprogramm pollt ständig Informationen aus der SPS, und speichert Werte in die SQL DB. (Welche Werte wann wo in welche Tabellen sollen ist wiederum in einer Tabelle hinterlegt.) Unter diesen Daten befinden sich alle möglichen Dinge: Anlagenzustände, Behälterfüllstände, Rezept-Daten, Analogmesswerte (z.B: Temperaturen, Drücke), Wägedaten, einfach alles, was in einer industriellen Produktionsanlage so anfällt.
Die Clients haben die Aufgabe, diese Daten in eine für die Bediener sinnvolle Form zu bringen und darzustellen. Darunter sind visuelle Komponenten zur Anzeige von Zuständen, und auch eine ganze Latte an Tabellen. Konkret geht es mir hier besonders um die Behälter-Tabelle, in der alle Behälter gelistet sind, mitsamt ihren Füllständen, aktuellen Stoffen und anderen ihnen zugehörigen Randdaten, von denen sich einige stets ändern.
Wenn der Bediener jetzt diese Tabelle offen hat, und etwas im Prozess passiert, oder ein anderer Client ändert etwas, so muss auch ein gerade woanders betrachtetes Grid diese Änderungen unbedingt wiederspiegeln. Die einzige Stelle, an der die Änderung passiert ist, ist die Datenbank, und diese muss Maßgeblich bleiben, weil sich auch Routinen im Server darauf beziehen. Und MySQL bietet imho kein Eventsystem, also muss ich das, so glaube ich zu wissen, doch pollen. Und selbst mit Eventsystem: Die Änderungen würden ebenfalls oft genug (öfter sogar) statt finden, und beim Refresh wieder das Problem beim scrollen verursachen.

Ein ähnliches Eventsystem habe ich im Server für die visuellen Komponenten gebaut: Es wird nur bei Änderungen in die DB geschrieben, und an die Clients via TCP mitgeteilt in welcher Tabelle sich bei welchen SatzIDs etwas geändert hat. Nur das hilft mir ja auch nicht weiter, da ich im Grid ja nicht nur einzelne Zeilen updaten kann.

stahli 20. Nov 2012 11:55

AW: TMS TDBAdvGrid und regelm. Refresh
 
Bleibt denn die Anzahl und Reihenfolge der "Messstände" i.d.R. gleich?
Oder ändern die sich oft?
Die Daten werden nur angezeigt - oder?

Vielleicht wäre es günstiger, die Daten in einem Stringgrid oder ListBox oder in Panels innerhalb einer Scrollbox (jedes Panel könnte eine Id erhalten und den zugehörigen Datensatz repräsentieren) darzustellen.
Du musst zwar die Darstellung dann von Hand veranlassen, hast aber mehr Kontrolle.

(Wurde, glaube ich, schon mal empfohlen.)


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:39 Uhr.
Seite 1 von 2  1 2      

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