1. #1

    Registriert seit
    28.10.2011
    Beiträge
    625
    Thanked 279 Times in 168 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: 310
Größe:  8,2 KB

    Wie kann ich das ganze vernünftig umsetzen?

  2. #2

    Registriert seit
    28.10.2011
    Beiträge
    625
    Thanked 279 Times in 168 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:
    Klicke auf die Grafik für eine größere Ansicht 

Name:	111.PNG 
Hits:	103 
Größe:	235,0 KB 
ID:	9343

  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.