Announcement

Collapse
No announcement yet.

Best practice für DataGridView im VirtualMode

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Best practice für DataGridView im VirtualMode

    Hallo,

    ich würde gerne in Erfahrung bringen, ob ich die Anwendung des VirtualMode richtig verstanden habe.

    Ich habe mir das Code-Beispiel auf den MSDN-Seiten angeschaut, aber ich bin mir nicht sicher, ob ich die Adaption an die echte Anwendung richtig mache.
    MSDN-Link

    Szenario:
    Ich habe ein streng typisiertes DataSet mit einer Tabelle mit ca. 10.000 Zeilen. Der Primärschlüssel der Tabelle ist die Spalte "VarIndex". Ein Thread aktualisiert alle 100ms viele Datensätze der Tabelle.
    In meinem Grid sollen nur etwa 1000 Datensätze der Tabelle sichtbar sein. Im Scope des Grids sind ca. 40 Zeilen.
    Das Formular, in welches das Grid eingebettet ist, lädt zyklisch nur die veränderten Datensätze in ein Dictionary<VarIndex, VarWert>.


    1.) Wie viele der Daten (und welche) muss ich in separaten Strukturen vorhalten?
    Genügt es, wenn ich im Formular ein List<>-Object mit den Indexwerten speichere? Oder brauche ich einen vollständigen Cache, der diese 1000 Datensätze bereit hält?

    2.) Wie füge ich am geschicktesten die Änderungen ein?
    Ich sehe hier das Problem, dass die veränderten Werte im Grid sichtbar gemacht werden müssen, wenn der Betrachter gerade genau mind. eine der veränderten Variablen in seinem Scope hat.


    Ich habe im Netz gesucht, aber ich finde keine Best Practice-Anweisung oder Code-Beispiele, wo mein Problem thematisiert wird.

    Gibt es Vorschläge, Links, Hinweise? Ich bin für alles dankbar.

  • #2
    Beim virtuellen Modus ist es so, dass das Grid per CellValueNeeded-Ereignis die anzuzeigenden Daten anfordert. Der Benutzer könnte also so schnell nach unten scrollen, dass man zuerst Zeilen 1 - 10 angezeigt hat und plötzlich Zeilen 5000 - 5010 anzeigen soll. Das bedeutet, man muss wissen, bei welcher Zeilennummer im Grid man welche Daten anzuzeigen hat. Und zweitens hat man diese Daten dann im Cache oder man muss sie aktuell einlesen.
    Für deinen Fall hieße das: man liest erst mal die ersten 40 Zeilen ein, macht damit die Anzeige und während der User sich das anschaut, lädt man im Hintergrund die restlichen Daten, falls man nicht aktuell lesen sondern cachen will (ich würd's ausprobieren, mit was man sich leichter tut).
    Beim CellValueNeeded-Ereignis kriegt man die Zeilennummer ja als Parameter mit, etwas anderes ist es, wenn man im Hintergrund neue Daten kriegt und wissen will, ob das die gerade angezeigten Daten betrifft. Dazu kann man über FirstDisplayedScrollingRowIndex und DisplayedRowCount herauskriegen, welche Daten gerade angezeigt werden. Liegen neue Daten in diesem Bereich vor, dann macht man eben das Update, ansonsten ist ja keine weitere Aktion nötig.
    Überlegen muss man sich natürlich noch die Sache mit der Sortierung, wie man sowas implementiert, aber erst mal Teil 1 lösen, dann hast du schon mehr Erfahrung und man kann besser über den Teil mit der Sortierung diskutieren.

    bye,
    Helmut

    PS: das hast du ja bereits durchstudiert ?

    Comment


    • #3
      WOW! Danke für die Erklärung, jetzt ist mir einiges klar geworden.

      Ich habe es soweit umgesetzt. Allerdings werden mir die neuen Werte im Grid aktuell nur dann angezeigt, wenn ich gerade die Zelle markiert habe.

      Wie kann ich halbwegs elegant bewirken, dass die manipulierten Werte auch sofort angezeigt werden?

      Aktuell verwende ich folgenden Code, um die Zellen im Grid zu aktualisieren:


      [highlight=c#]
      if (intRowIndexVisible >= intRowIndexUpdate && intRowIndexUpdate <= intRowIndexVisible + this.dgvVariables.DisplayedRowCount(true))
      {
      this.dgvVariables.BeginEdit(false);
      this.dgvVariables.Rows[intRowIndexUpdate].Cells["Value"].Value = variable.Value;
      this.dgvVariables.EndEdit();
      }
      [/highlight]

      Mit einem Refresh() funktioniert es zwar, aber dann habe ich zwei Effekte:
      a) es flackert
      b) die Aktualisierung wird immer langsamer, je mehr ich im Grid nach unten scrolle.
      Zuletzt editiert von TheoFontane; 21.02.2011, 09:58. Reason: Codeformatierung

      Comment


      • #4
        So, hier mal die Lösung, die ich dafür gefunden habe:

        Das Grid wird gar nicht mehr "automatisch beschrieben": ich lasse das Aktualisieren auf Zellebene einfach ganz weg. Stattdessen lasse ich das Grid timergesteuert einfach einen normalen Refresh durchführen. Dabei werden über das CellValueNeeded-Event nur die Zellen abgeholt, die gerade sichtbar sind.

        Falls es (trotz der regen Beteiligung in diesem Forum) doch noch mal einen Experten geben sollte, der die Problematik kennt, dass das Grid immer langsamer updated und immer mehr Ressourcen verschlingt wenn man herunter scrollt, dann möge er/sie doch bitte kurz erklären warum das so ist und wie man den Effekt beheben kann.

        Ich weiß nur, dass ich bei weitem nicht der einzige mit diesem Problem bin (es gibt viele hunderte ähnliche Problembeschreibungen), aber dass es bisher keine einfach zu findende Lösung dafür gibt.

        Comment

        Working...
        X