Einzelnen Beitrag anzeigen

Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#12

AW: Panel-Komponente entwickelt - Offensichtliche Fehler?

  Alt 5. Sep 2018, 17:07
Und zur Performance, ich würde hier mit InvalidateRect arbeiten,
und im Paint nur das zeichnen, was im übergebenen Rect liegt.
Kannst du mir das etwas erläutern? Wo wird denn im meinem Paint ein Rect übergeben?
Vor dem Aufruf von Paint wird für den Canvas automatisch eine Clipping-Region gesetzt, in der neu zu zeichen ist.
Die Region kann eine beliebige Form haben. Es können weiterhin auch Zeichenbefehle an den Canvas gesendet werden, die darüber hinaus gehen.
Die Zeichenoperationen werden aber nur in diesem Bereich ausgeführt. Das sorgt schon mal für eine Beschleunigung.
Wenn man weiter optimieren muss, im Paint Canvas.ClipRect abfragen und nur die Daten ermitteln und zeichnen, die tatsächlich gebraucht werden.
Okay. Ich habe zur Zeit folgendermaßen.

Ein Thread kümmert sich ums Daten holen und aufbereiten (DB-Abfrage, Texte, Farben, Textstile, etc.). Wenn dieses fertig ist, übergibt er die Daten per Synchronize als Kopie in die Form (dort werden die Daten auch noch an anderen Stellen benötigt).

In der Sychronize-Methode wird als ersten in meiner Komponente ein BeginUpdate ausgeführt, welches ein Neuzeichnen unterbindet (und damit auch die Events OnGetText, etc.). Dann wird die Liste der Form mit den Daten aus dem Thread neu erzeugt. Dann erfolgt das EndUpdate, welches automatisch auch ein Paint beinhaltet.
Da ich nun eh nicht weiß, was sich an den Daten verändert hat (und dabei spielt es ja keine Rolle ob diese nun im Thread verändert werden oder auch in einer Methode in der Form), zeichne ich jedes, ich nennen es mal PanelItem, komplett neu.
Die jeweiligen Farben, Texte, Stile, oder Bitmaps werden ja sowieso nicht in der Komponente gespeichert, sondern während des Zeichnens über ein Event abgefragt. Somit kann ich innerhalb des Paint gar nicht entscheiden, ob nun neu gezeichnet werden müsste oder nicht. Und der Aufwand nun noch festzustellen, was sich denn geändert hat, würde meiner Meinung nach mehr Rechenleistung fressen, als ich dadurch sparen kann.

Dadurch, dass ich nur die Adressen der Objekte in der Komponente speichere, muss ich in der Form natürlich aufpassen, dass während sich die Liste verändert nicht neugezeichnet wird bzw. auch umgekehrt, dass sich während des Neuzeichnens die Liste nicht verändert. In diesem Fall habe ich das über das BeginUpdate/EndUpdate erst einmal sichergestellt. Reicht in dem Fall auch aus, da ich die gesamten Daten immer nur komplett aus der DB lese, sogar wenn nur ein einzelner Datensatz im Programm geändert wird.

Anders wäre das, wenn ich eine Datenänderung erst einmal lokal darstellen möchte, und dann erst später eine komplette Aktualisierung vornehme würde. In dem Fall müsste ich die Komponente über die Änderung informieren. Und dann würde es auch Sinn machen, eínzelne PanelItems zu zeichnen statt des ganzen Panels.

In dem Panel sind zur Zeit bis zu 20 PanelItems (Bei den meisten Installationen sogar weniger). Die größte Anzahl an Clients beläuft sich auf 25. Das ganze dient zur Darstellung von Mitarbeiter-Auftrags-Planung und Verfolgung der aktuellen Arbeitsaufträge und deren Fortschritt. Somit kann man mit einem Aktualisierungsintervall vom 30-60 Sekunden sehr gut Leben. Ich denke nicht, dass jemals ein so hoher Zeichnungsintervall auftreten kann, der eine Echtzeitdarstellung erfordert.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat