Hallo,
folgender Sachverhalt.
In meinem Programm existiert ein ListView Control. In diesem sind verschiedene Einträge vorhanden, die sich nach einer gewissen Zeit (einstellbar gehen wir jetzt mal von 30 sec. aus) aktualisieren können.
Momentan hab ich es folgendermaßen realisiert: Ein Thread durchläuft die Änderungen und prüft, ob Einträge des ListViews betroffen sind. Danach wird jedes einzelne Element des ListViews ausgewechselt. Vor der Prüfung rufe ich die Funktion SuspendLayout und nachher ResumeLayout des ListViews auf. Nur leider habe ich das Problem, das meine Liste natürlich flakert und sich nur sehr langsam wieder aufbaut.
Meine Frage ist nun: Wie optimiere ich das ganze? Soll ich vorher alle Einträge in eine interne Liste kopieren, hier die Änderungen durchführen, dann den ListView leeren und zum Schluss alle Elemente des ListViews neu setzen? Oder wie sieht der richtige Weg aus?
Danke schon mal für eure Hilfe
Verwende Databinding. Das impliziert, das du alle Angezeigten werte in einer Datenstruktur hast. Dann kannst du die Änderungen nur innerhalb der Datenstruktur durchführen und das Invoke des GUI bei jeder änderung fällt somit weg.
edit: nein ich schreibe blödsinn... natürlich muss man immernoch invoken, da ja die änderung in einem anderen thread erfolgt.
Und damit kann ich alle meine Änderungen durchführen und danach ein globales Refresh durchführen?
Hallo
Durch DataBinding (dank INotifyPropertyChange..) wird das GUI bei Änderungen automatisch benachrichtigt und aktaulisiert sich automatisch.
Beste Grüsse
Diräkt
Ich lese mir gerade mal den msdn Artikel durch. Scheint doch recht angenehm zu sein
Ok habs mir durch gelesen und würde jetzt wie folgt vorgehen.
Wann genau tritt das ListChanged Event der BindingSource ein?
Wahrscheinlich schon in diesem Falle:
for (int i = 0; i < count(zähler); i++)
this.myBindingSource.List[i] = newElement; //Hier beim ersten Durchgang
Was müsste ich denn dafür tun, damit z.B. der ListView erst nach durchlaufen der Schleife erneuert wird, oder bin ich hiermit komplett auf dem Holzweg?
~~Du bist auf dem Holzweg.
Du bindest die Datenstruktur an die Listview. Damit hast du schon mal die GUI Seite fertig.
Danach macht dein Thread nur die Änderungen an der Datenstruktur und nicht an der Bindingsource oder an der Listview.~~
edit: nein ich schreibe blödsinn... natürlich muss man immernoch invoken, da ja die änderung in einem anderen thread erfolgt.
...
Du bindest die Datenstruktur an die Listview. Damit hast du schon mal die GUI Seite fertig.
...
Wie genau mache ich das bzw. wie meinst du das?
Da war ich auch schon drauf gekommen 😃
Leider besitzen meine ListViews keine Eigenschaft DataSource!
Anscheinend muss ich mir ein geerbtes ListView erstellen, welches dieses Modell abbildet!
Ich verwende übrigens DotNET Framework 2.0. Wird wahrscheinlich die Erklärung sein.
Erscheint mir jetzt aber sehr aufwendig für ein, meiner Meinung nach, simples Problem 😕
Hallo zusammen,
reden wir hier von WPF oder WinForms? Weil das WinForms-ListView kein DataBinding unterstützt... du müßtest dann auf das DataGridView wechseln (s.a. Vergleich DatagridView - ListView).
So ich habs jetzt folgendermaßen gelöst.
//Zuerst einmal implementiere ich die Funktion "LockWindowUpdate"
//der "user32.dll"
[DllImport("user32.dll")]
private static extern bool LockWindowUpdate(IntPtr hWndLock);
//Wenn mein Thread jetzt geänderte Daten hat läuft die Methode
//so ab
//Fensterupdate unterdrücken
LockWindowUpdate(this.myListView.Handle);
//Neue Items fürs ListView
this.myListView.Items.Clear();
this.myListView.AddRange(this.myListViewItems);
//Fenster neu zeichnen
LockWindowUpdate(IntPtr.Zero);
So damit bekomme ich nur noch einen Redraw was die ganze Sache annähernd perfekt macht!
Ich finde es vollkommen ok so. Trotzdem Danke für eure Hinweise.
Du kommst nicht zufällig von VB6?
Weil da wird auch immer ein Problem so gelöst, indem man einen schlechten Weg benutzt und das dann mit "geht ja" einfach hinnimmt, statt es vernünftig zu machen.
Das hätte hier auch nicht länger gedauert.
Stichwort VirtualMode
Nein das nicht, ich gebe dir auch Recht, dass mein vorgeschlagener Weg nicht der beste ist.
Aber er funktioniert halt.
Egal auf jeden Fall habe ich mir mal deinen Vorschlag angeschaut und ich werds auf jeden Fall mal ausprobieren 😉. Danke für den Hinweis