1. #1
    U-Labs Elite

    Registriert seit
    28.10.2011
    Beiträge
    559
    Thanked 236 Times in 155 Posts

    Standard FileTree generieren und als TreeView darstellen

    Ich bin derzeit dabei, einen FileTree zu generieren. Hier werden alle Einträge als FileNode gespeichert und beinhalten dann die Childs:

    using System.Collections.Generic;
    using System.IO;

    namespace DSTEd.Core.IO {
    public class FileNode {
    private DirectoryInfo info = null;
    private List<FileNode> children = new List<FileNode>();

    public FileNode(DirectoryInfo info) {
    this.info = info;
    }

    public string GetName() {
    return this.info.Name;
    }

    public string GetPath() {
    return this.info.FullName;
    }

    public void AddChildren(FileNode node) {
    this.children.Add(node);
    }

    public List<FileNode> GetChildrens() {
    return this.children;
    }

    public bool HasChildrens() {
    return this.children.Count > 0;
    }
    }
    }

    using System.Collections.Generic;
    using System.IO;

    namespace DSTEd.Core.IO {
    public class FileSystem {
    private List<FileNode> files = new List<FileNode>();

    public FileSystem(string path) {
    this.files.Add(this.Parse(new DirectoryInfo(path)));
    }

    private FileNode Parse(DirectoryInfo directory) {
    FileNode node = new FileNode(directory);

    foreach (DirectoryInfo dir in directory.GetDirectories()) {
    node.AddChildren(this.Parse(dir));
    }

    foreach (var file in directory.GetFiles()) {
    node.AddChildren(node);
    }

    return node;
    }

    public List<FileNode> GetChildren() {
    return this.files;
    }

    public bool HasChildrens() {
    return this.files.Count > 0;
    }
    }
    }


    Das ganze wird folgendermaßen initiiert:
    FileSystem files = new FileSystem("C:/whatever/sonstwo");
    


    Jetzt möchte ich anhand der rekursiven FileNodes eine TreevIew befüllen:


    TreeView tree = new TreeView();
    foreach (FileNode directory in files.GetChildren()) {
    var item = new TreeViewItem { Header = directory.GetName() };

    if (directory.HasChildrens()) {
    foreach (FileNode d in directory.GetChildrens()) {
    var tt = new TreeViewItem { Header = d.GetName()};

    Items.Add(tt);
    }
    }

    tree.Items.Add(item);
    }


    Jetzt zum Problem:
    Normalerweise müsste ich ja nun auch beim "rendern" das ganze rekursiv gestalten, bekomme da aber einen StackOverflow, obwohl ich auf Childs der FileNodes prüfe, deswegen hab ich das ganze nun erst einmal simple mit einer Schleife gemacht, der mir nur die ersten Childs ausgibt. Hierbei wiederholt der aber komischerweise immer Einträge, die bereits als TreeNode existieren:
    Name:  Tree.PNG
Hits: 40
Größe:  8,2 KB

    Wie kann ich das ganze vernünftig umsetzen?

  2. #2
    U-Labs Elite

    Registriert seit
    28.10.2011
    Beiträge
    559
    Thanked 236 Times in 155 Posts

    Standard AW: FileTree generieren und als TreeView darstellen

    Hier die Lösung, man muss das ganze etwas besser trennen. Ich hatte überall (für Folder UND Files) in einer Liste hinzugefügt, da kam das ganze etwas durcheinander. Der Trick daran ist, dass die Folder wie gewohnt den Typ FileNode bekommen, die auch die Children enthalten, zusätzlich wird für die Files-Ebene eine separate Liste verwendet.

    Und so sieht das ganze nun aus:

    FileNode.cs
    using System.Collections.Generic;
    using System.IO;

    namespace DSTEd.Core.IO {
    public class FileNode {
    private DirectoryInfo info = null;
    private List<FileNode> subdirectories = new List<FileNode>();
    private List<FileInfo> files = new List<FileInfo>();

    public FileNode(DirectoryInfo info) {
    this.info = info;
    }

    public string GetName() {
    return this.info.Name;
    }

    public string GetPath() {
    return this.info.FullName;
    }

    public void AddSubdirectory(FileNode node) {
    this.subdirectories.Add(node);
    }

    public List<FileNode> GetSubdirectories() {
    return this.subdirectories;
    }

    public bool HasSubdirectories() {
    return this.subdirectories.Count > 0;
    }

    public void AddFile(FileInfo file) {
    this.files.Add(file);
    }

    public List<FileInfo> GetFiles() {
    return this.files;
    }

    public bool HasFiles() {
    return this.files.Count > 0;
    }
    }
    }


    FileSystem.cs
    using System.Collections.Generic;
    using System.IO;

    namespace DSTEd.Core.IO {
    public class FileSystem {
    private List<FileNode> directories = new List<FileNode>();

    public FileSystem(string path) {
    this.directories.Add(this.Parse(new DirectoryInfo(path)));
    }

    private FileNode Parse(DirectoryInfo directory) {
    FileNode node = new FileNode(directory);

    foreach (DirectoryInfo dir in directory.GetDirectories()) {
    node.AddSubdirectory(this.Parse(dir));
    }

    foreach (FileInfo file in directory.GetFiles()) {
    node.AddFile(file);
    }

    return node;
    }

    public List<FileNode> GetDirectories() {
    return this.directories;
    }

    public bool HasDirectories() {
    return this.directories.Count > 0;
    }
    }
    }


    Das ganze wird dann in zwei Formen aufgerufen:
    FileSystem files = new FileSystem(path)
    


    Die Klasse holt und befüllt sich damit dann eigenständig. Um das ganze nun zu "rendern", braucht man nur noch rekursiv drüber iterieren:

    foreach (FileNode directory in files.GetDirectories()) {
    this.Render(directory, this.tree); // this.tree ist die jeweilige TreeView
    }



    private TreeViewItem Render(FileNode files, TreeView container) {
    TreeViewItem item = new TreeViewItem { Header = files.GetName() };

    if (files.HasSubdirectories()) {
    foreach (FileNode directory in files.GetSubdirectories()) {
    TreeViewItem root = this.Render(directory, null); // Hier wird "FileNode" (also das directory) rekursiv durchgegangen

    if (container != null) {
    container.Items.Add(root);
    } else {
    item.Items.Add(root);
    }
    }
    }

    if (files.HasFiles()) {
    foreach (FileInfo file in files.GetFiles()) {
    TreeViewItem entry = new TreeViewItem { Header = file.Name };

    entry.MouseRightButtonDown += new MouseButtonEventHandler(delegate (object sender, MouseButtonEventArgs e) {
    Logger.Info("ContextMenu: " + file.FullName);
    });

    entry.PreviewMouseDown += new MouseButtonEventHandler(delegate (object sender, MouseButtonEventArgs e) {
    this.GetCore().GetWorkspace().OpenDocument(file.FullName);
    });

    item.Items.Add(entry);
    }
    }

    return item;
    }


    Ist etwas abgekürzt, da ich das ganze schon ziemlich gut in der UI integriert habe und dementsprechend auch spezielle Features implementiert sind.

    Und so schaut das ganze dann nun am Ende aus:
    111.png

  3. The Following User Says Thank You to Bubble Gum For This Useful Post:

    Negok (25.02.2019)

Ähnliche Themen

  1. VB.Net String() darstellen
    Von milchbubix im Forum .Net
    Antworten: 2
    Letzter Beitrag: 31.10.2015, 12:01
  2. Viele Randoms mit Lambda generieren
    Von Sky.NET im Forum Showroom
    Antworten: 0
    Letzter Beitrag: 03.05.2012, 22:43
  3. [C#] Zufälligen String generieren
    Von Festplatte im Forum .Net
    Antworten: 0
    Letzter Beitrag: 08.01.2012, 01:25
  4. [Java] Nicks generieren
    Von KrT im Forum Sourcecode
    Antworten: 4
    Letzter Beitrag: 30.03.2011, 23:15
Diese Seite nutzt Cookies, um das Nutzererlebnis zu verbessern. Klicken Sie hier, um das Cookie-Tracking zu deaktivieren.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150