Laden...

Füllen eines TreeView blockiert Form

Erstellt von Rainer Wein vor 10 Jahren Letzter Beitrag vor 10 Jahren 1.800 Views
Thema geschlossen
R
Rainer Wein Themenstarter:in
90 Beiträge seit 2008
vor 10 Jahren
Füllen eines TreeView blockiert Form

Hallo zusammen,
ich nutze einen TreeView um die Verzeichnisstruktur einer Archiv-Datei darzustellen. Beim Füllen des TreeViews blockiert jedoch die GUI, da der Vorgang zu lang dauert. Um das blockieren zu vermeiden, wollte ich eigentlich einen BackgroundWorker nutzen. Laut einigen Forenbeiträgen sollte man dies aber nicht unbedingt tun, da man beim Hinzufügen der Nodes jedes Mal Invoken muss und dies den Füllvorgang ausbremsen soll.

Meine Frage ist nun, ob es eine andere Möglichkeit als den Backgroudworker gibt oder ob die Methode optimiert werden kann um ganz darauf zu verzichten? Dazu noch eine kurze Erklärung: Jeder entry repräsentiert eine Datei, die einen String mit der Angabe zum Verzeichnis enthält. Mithilfe der Methode addNodeWithPath() durchsuche ich den Baum rekursiv und prüfe ob das angegebene Verzeichnis bereits existiert. Ist dies nicht der Fall wird erst das Verzeichnis-Node und dann die dazugehörige File-Node erstellt. Da es sich insgesamt um ca. 19000 Einträge handelt und ich bei jeder Datei diesen Vorgang wiederholen muss kann dies natürlich etwas dauern. Sieht jemand eine Möglichkeit diesen Vorgang zu beschleunigen?


public void generateTreeView()
{
      this.file_TREE.BeginUpdate();
      TreeNode folderNode = null;
      TreeNode fileNode = null;
      LsrFile file = null;
   
      for (int i = 0; i < LsrManager.GetFiles().Count; i++)
      {
          file = LsrManager.GetFiles()[i];
          foreach (LsrEntry entry in file.EntryList)
          {
              folderNode = addNodeWithPath(file_TREE.Nodes, entry.DirName);

              fileNode = new TreeNode();
              fileNode.Text = entry.FileName;
              fileNode.Tag = entry;

              if (folderNode != null)
              {
                  folderNode.Nodes.Add(fileNode);
              }
              else
              {
                  file_TREE.Nodes.Add(fileNode);
              }
          }
      }

      this.file_TREE.EndUpdate();
}


private TreeNode addNodeWithPath(TreeNodeCollection nodes, string path)
        {
            var leaf = System.IO.Path.GetFileName(path);

            if (path != leaf)
            {
                nodes = addNodeWithPath(nodes, System.IO.Path.GetDirectoryName(path)).Nodes;
            }

            var node = nodes.Find(leaf, false).FirstOrDefault();

            if (node == null)
            {
                if (leaf != String.Empty)
                {
                    node = nodes.Add(leaf, leaf);
                }
            }
            return node;
        }
4.221 Beiträge seit 2005
vor 10 Jahren

Verzögertes Laden von Daten im TreeView

Oder dessen Base LoadOnDemandTreeView (suche verwenden)

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

5.658 Beiträge seit 2006
vor 10 Jahren

Hi Rainer Wein,

Laut einigen Forenbeiträgen sollte man dies aber nicht unbedingt tun, da man beim Hinzufügen der Nodes jedes Mal Invoken muss und dies den Füllvorgang ausbremsen soll.

Es wird zwar insgesamt langsamer, aber das Benutzerinterface bliebe dafür ansprechbar. Das ist ja dein Ziel wenn ich es richtig verstanden hab.

Da es sich insgesamt um ca. 19000 Einträge handelt und ich bei jeder Datei diesen Vorgang wiederholen muss kann dies natürlich etwas dauern. Sieht jemand eine Möglichkeit diesen Vorgang zu beschleunigen?

Am besten nur die Dateien laden, die auch angezeigt werden. Also nicht beim Start den kompletten TreeView befüllen, sondern nur die oberste Ebene und alle weiteren Ebenen erst beim Ausklappen. So lädst du die Daten häppchenweise, brauchst keinen BackgroundWorker mehr und das BenutzerInterface bleibt trotzdem noch ansprechbar.

Christian

Weeks of programming can save you hours of planning

R
Rainer Wein Themenstarter:in
90 Beiträge seit 2008
vor 10 Jahren

Vielen Dank erst einmal für die Vorschläge.

Zum Thema "Verzögertes Laden von Daten im TreeView" habe ich bedenken, da ich zuvor trotzdem alle Dateien durchlaufen muss um die Ordner-Struktur zu erstellen auch wenn ich zuerst nur die oberste Ebene benötige. Wird dann ein Knoten aufgeklappt, muss ich das ganze wieder durchlaufen. Ich werde es mir trotzdem noch einmal anschauen.

Es wird zwar insgesamt langsamer, aber das Benutzerinterface bliebe dafür ansprechbar. Das ist ja dein Ziel wenn ich es richtig verstanden hab.

Danke für die Bestätigung, testen werde ich trotzdem einmal, vielleicht sind die Auswirkungen ja nicht so gravierend.

Ich hatte vorhin noch eine Idee, vielleicht kann jemand etwas dazu sagen.
Ich erstelle ein HashSet<String> in der nur die Pfade der Ordner zu finden sind. Diese lasse ich dann ganz normal über meine Methode erzeugen. Anschließend durchlaufe ich die Dateien noch einmal und füge die entsprechenden Dateien den Ordnern hinzu. Die hätte theoretisch den Vorteil das ich nicht ständig den Baum durchlaufen müsste. Setzt natürlich voraus dass es eine Möglichkeit gibt ein Node an einer bestimmten Stelle (Pfad) einzufügen.

4.221 Beiträge seit 2005
vor 10 Jahren

Auch das hatten wir schon mal:

Rekursiver TreeView Save/Restore aufgrund des FullPaths

Gruss Programmierhans

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

Hinweis von herbivore vor 10 Jahren

Und insgesamt ist es nur eine weitere Variante von [FAQ] Warum blockiert mein GUI? und [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke). In letzterem wird auch der Fall behandelt, das (für mehrere Nodes) Invoke zusammenzufassen.

Thema geschlossen