remplir treeview à partir d'une liste de chemin

j'essaye de peupler une vue d'arbre à partir d'une liste de chemin de dossier, par exemple:

C:WINDOWSaddins
C:WINDOWSAppPatch
C:WINDOWSAppPatchMUI
C:WINDOWSAppPatchMUI0C
C:WINDOWSMicrosoft.NETFrameworkv2.0.50727
C:WINDOWSMicrosoft.NETFrameworkv2.0.50727MUI
C:WINDOWSMicrosoft.NETFrameworkv2.0.50727MUI09

avec une sortie comme ceci:

├───addins
├───AppPatch
│   └───MUI
│       └───040C
├───Microsoft.NET
│   └───Framework
│       └───v2.0.50727
│           └───MUI
│               └───0409

attention il n'y a pas de "C:WINDOWSMicrosoft.NET" ou "C:WINDOWSMicrosoft.NETFramework dans la liste. J'y travaille depuis presque deux jours et il y a un tas de bugs dans mon code. J'espère que je peux avoir de l'aide d'ici.

Merci.

Eric

19
demandé sur Fredrik Mörk 2009-07-21 01:12:08

8 réponses

private void Form1_Load(object sender, EventArgs e)
    {
        var paths = new List<string>
                        {
                            @"C:\WINDOWS\AppPatch\MUI0C",
                            @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727",
                            @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI",
                            @"C:\WINDOWS\addins",
                            @"C:\WINDOWS\AppPatch",
                            @"C:\WINDOWS\AppPatch\MUI",
                            @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI09"
                        };

        treeView1.PathSeparator = @"\";

        PopulateTreeView(treeView1, paths, '\');
}


private static void PopulateTreeView(TreeView treeView, IEnumerable<string> paths, char pathSeparator)
    {
        TreeNode lastNode = null;
        string subPathAgg;
        foreach (string path in paths)
        {
            subPathAgg = string.Empty;
            foreach (string subPath in path.Split(pathSeparator))
            {
                subPathAgg += subPath + pathSeparator;
                TreeNode[] nodes = treeView.Nodes.Find(subPathAgg, true);
                if (nodes.Length == 0)
                    if (lastNode == null)
                        lastNode = treeView.Nodes.Add(subPathAgg, subPath);
                    else
                        lastNode = lastNode.Nodes.Add(subPathAgg, subPath);
                else
                    lastNode = nodes[0];
            }
        }
    }

alt text

27
répondu ehosca 2012-11-25 11:43:35

réponse d'ehosca correcte, mais il y a un petit problème, quand j'ai changer les chemins d'accès à comme ceci

C:\WINDOWS\AppPatch\MUI0C
D:\WIS\Microsoft.NET\Framework\v2.0.50727
E:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI
C:\WINDOWS\addins
C:\WINDOWS\AppPatch
C:\WINDOWS\AppPatch\MUI
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI09

enter image description here

il va popoulate treeview comme ceci.

mais en ajoutant un peu de code supplémentaire nous pouvons éviter cette situation. J'ai donc changé le code dans Populatetreview

private static void PopulateTreeView(TreeView treeView, string[] paths, char pathSeparator)
        {
            TreeNode lastNode = null;
            string subPathAgg;
            foreach (string path in paths)
            {
                subPathAgg = string.Empty;
                foreach (string subPath in path.Split(pathSeparator))
                {
                    subPathAgg += subPath + pathSeparator;
                    TreeNode[] nodes = treeView.Nodes.Find(subPathAgg, true);
                    if (nodes.Length == 0)
                        if (lastNode == null)
                            lastNode = treeView.Nodes.Add(subPathAgg, subPath);
                        else
                            lastNode = lastNode.Nodes.Add(subPathAgg, subPath);
                    else
                        lastNode = nodes[0];
                }
                lastNode = null; // This is the place code was changed

            }
        }

Maintenant il fonctionne très bien comme ceci

enter image description here

10
répondu Sajitha Nilan 2013-10-12 09:39:50

pour une version linq'y:

public static TreeNode MakeTreeFromPaths(List<string> paths, string rootNodeName = "", char separator = '/')
{
    var rootNode = new TreeNode(rootNodeName);
    foreach (var path in paths.Where(x => !string.IsNullOrEmpty(x.Trim()))) {
        var currentNode = rootNode;
        var pathItems = path.Split(separator);
        foreach (var item in pathItems) {
            var tmp = currentNode.Nodes.Cast<TreeNode>().Where(x => x.Text.Equals(item));
            currentNode = tmp.Count() > 0 ? tmp.Single() : currentNode.Nodes.Add(item);
        }
    }
    return rootNode;
}
9
répondu ykm29 2014-07-21 09:40:08

j'ai pris votre code, et ça marche très bien, mais j'ai juste fait une petite modification pour améliorer la vitesse de charge lorsqu'il est utilisé avec une grande liste de fichiers il semble que l'opération find, et les opérations string sont généralement très lentes

private TreeNode PopulateTreeNode2(string[] paths, string pathSeparator)
    {
        if (paths == null)
            return null;

        TreeNode thisnode = new TreeNode();
        TreeNode currentnode;
        char[] cachedpathseparator = pathSeparator.ToCharArray();
        foreach (string path in paths)            {
            currentnode = thisnode;
            foreach (string subPath in path.Split(cachedpathseparator))
            {
                if (null == currentnode.Nodes[subPath])
                    currentnode = currentnode.Nodes.Add(subPath, subPath);
                else
                    currentnode = currentnode.Nodes[subPath];                   
            }
        }

        return thisnode;
    }

ensuite, vous pouvez utiliser:

string[] paths =  {
                        @"C:\WINDOWS\AppPatch\MUI0C",
                        @"D:\WINDOWS\Microsoft.NET\Framework\v2.0.50727",
                        @"E:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI",
                        @"C:\WINDOWS\addins",
                        @"C:\WINDOWS\AppPatch",
                        @"C:\WINDOWS\AppPatch\MUI",
                        @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MUI09"
                    };
TreeView treeview = new TreeView();
treeview.Nodes.Add(PopulateTreeNode2(paths, "\"));

NOTE: peut-être qu'une vérification de la sensibilité de la chaîne de caractères sera nécessaire dans les deux solutions, afin de prévenir certains dossiers ré créations.

parce qu'une url pourrait être pointant vers le même dossier sur le disque mais épelé différent tel que: Windows; WinDOWs, WINDOWS

4
répondu kaytes 2016-12-11 00:00:43

voici un très vieux code que j'ai utilisé une fois pour créer ASP.NET treeview from code (en supposant que TreeView a un ID de TreeViewFolders):

protected void Page_Load(object sender, EventArgs e)
{
    GenerateTreeView(@"C:\WINDOWS\");
}

private void GenerateTreeView(string rootPath)
{
    GetFolders(System.IO.Path.GetFullPath(rootPath), TreeViewFolders.Nodes);
    TreeViewFolders.ExpandDepth = 1;
}

// recursive method to load all folders and files into tree
private void GetFolders(string path, TreeNodeCollection nodes)
{
    // add nodes for all directories (folders)
    string[] dirs = Directory.GetDirectories(path);
    foreach (string p in dirs)
    {
        string dp = p.Substring(path.Length);
        nodes.Add(Node("", p.Substring(path.Length), "folder"));
    }

    // add nodes for all files in this directory (folder)
    string[] files = Directory.GetFiles(path, "*.*");
    foreach (string p in files)
    {
        nodes.Add(Node(p, p.Substring(path.Length), "file"));
    }

    // add all subdirectories for each directory (recursive)
    for (int i = 0; i < nodes.Count; i++)
    {
        if (nodes[i].Value == "folder")
            GetFolders(dirs[i] + "\", nodes[i].ChildNodes);
    }
}

// create a TreeNode from the specified path, text and type
private TreeNode Node(string path, string text, string type)
{
    TreeNode n = new TreeNode();
    n.Value = type;
    n.Text = text;
    return n;
}
0
répondu Dan Diplo 2012-11-25 11:44:22

ce code alimente le contrôle TreeView des formulaires windows. Il est beaucoup plus simple que les réponses données.

using System;
using System.Windows.Forms;
using System.IO;

// ...
    private void Form1_Load(object sender, EventArgs e)
    {
        treeView1.Nodes.Add(@"C:\");
        treeView1.Nodes[0].Tag = @"C:\";
        Populate((string)treeView1.Nodes[0].Tag, treeView1.Nodes[0]);
    }

    private void Populate(string address, TreeNode rootNode)
    {
        DirectoryInfo[] directories = new DirectoryInfo(address).GetDirectories();
        foreach (DirectoryInfo directory in directories)
        {
            TreeNode newNode = new TreeNode(directory.Name);
            rootNode.Nodes.Add(newNode);
            newNode.Tag = directory.FullName;

            try
            {
                DirectoryInfo[] innerDirectories = new DirectoryInfo(directory.FullName).GetDirectories();
                if (innerDirectories.Length > 0)
                    newNode.Nodes.Add(new TreeNode());

                FileInfo[] innerFiles = new DirectoryInfo(directory.FullName).GetFiles();
                if (innerFiles.Length > 0)
                    newNode.Nodes.Add(new TreeNode());
            }

            catch
            {
                continue;
            }
        }

        FileInfo[] files = new DirectoryInfo(address).GetFiles();
        foreach (FileInfo file in files)
            rootNode.Nodes.Add(file.Name);
    }

    private void treeView1_AfterExpand(object sender, TreeViewEventArgs e)
    {
        if (e.Node.Nodes.Count < 3)
        {
            e.Node.Nodes.Clear();
            Populate((string)e.Node.Tag, e.Node);
        }
    }
0
répondu Mooncat 2017-02-22 05:39:01
private void Form2_Load(object sender, EventArgs e)
{
    treeView1.CheckBoxes = true;

    foreach (TreeNode node in treeView1.Nodes)
    {
        node.Checked = true;
    }

    string[] drives = Environment.GetLogicalDrives();

    foreach (string drive in drives)
    {
        // treeView1.Nodes[0].Nodes[1].Checked = true;
        DriveInfo di = new DriveInfo(drive);
        int driveImage;

        switch (di.DriveType)   
        {
            case DriveType.CDRom:
                driveImage = 3;
                break;
            case DriveType.Network:
                driveImage = 6;
                break;
            case DriveType.NoRootDirectory:
                driveImage = 8;
                break;
            case DriveType.Unknown:
                driveImage = 8;
                break;
            default:
                driveImage = 2;
                break;
        }

        TreeNode node = new TreeNode(drive.Substring(0, 1), driveImage, driveImage);
        node.Tag = drive;

        if (di.IsReady == true)
             node.Nodes.Add("...");

        treeView1.Nodes.Add(node);          
    }

    foreach (TreeNode node in treeView1.Nodes)
    {
        node.Checked = true;
    }
}

private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
    {
        if (e.Node.Nodes.Count > 0)
        {
            if (e.Node.Nodes[0].Text == "..." && e.Node.Nodes[0].Tag == null)
            {
                e.Node.Nodes.Clear();

                string[] dirs = Directory.GetDirectories(e.Node.Tag.ToString());

                foreach (string dir in dirs)
                {
                    DirectoryInfo di = new DirectoryInfo(dir);
                    TreeNode node = new TreeNode(di.Name, 0, 1);
                    node.Checked = true;

                    try
                    {
                        node.Tag = dir;
                        if (di.GetDirectories().Count() > 0)
                            node.Nodes.Add(null, "...", 0, 0).Checked = node.Checked;
                    }
                    catch (UnauthorizedAccessException)
                    {
                        node.ImageIndex = 12;
                        node.SelectedImageIndex = 12;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "DirectoryLister", MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                    }
                    finally
                    {
                        node.Checked = e.Node.Checked;
                        e.Node.Nodes.Add(node);
                    }
                }
            }
        }
    }              
}

private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
    button1.Enabled = false;
    TreeNode node = e.Node;
    bool is_checked = node.Checked;
    foreach (TreeNode childNode in e.Node.Nodes)
    {
        childNode.Checked = e.Node.Checked;
    }
    treeView1.SelectedNode = node;
 }
0
répondu Santosh Kokatnur 2018-03-13 20:52:16

sauf si vous postez le code, il est impossible de déterminer ce qui ne va pas avec lui. Au lieu de passer des jours sur ce pourquoi ne pas utiliser un contrôle tiers tel que le dossier partagé sommaire

-2
répondu logicnp 2009-08-01 16:22:56