winforms C# Winform中获取文件夹和文件的TreeView时如何修复双目录

eoigrqb6  于 2022-11-25  发布在  C#
关注(0)|答案(1)|浏览(177)

我在C# Winform中创建了一个文件夹和文件的TreeView,这是我的源代码:

using System.IO;
using System.Linq;

public partial class WindowExplorer : Form
{
    public void LoadFile(TreeNode parent, string path)
    {
        if (Directory.Exists(path))
        {
            string dirName = new FileInfo(path).Name;
            TreeNode dirNode = new TreeNode(dirName);
            parent.Nodes.Add(dirNode);
            string[] subDir = Directory.GetDirectories(path);
            string[] subFile = Directory.GetFiles(path);
            string[] allSubItem = subDir.Concat(subFile).ToArray();
            foreach (string subItem in allSubItem)
            {
                LoadFile(dirNode, subItem);
            }
        }
        if (File.Exists(path))
        {
            string fileName = new FileInfo(path).Name;
            TreeNode fileNode = new TreeNode(fileName);
            parent.Nodes.Add(fileNode);
        }
    }

    private void WindowExplorer_Load(object sender, EventArgs e)
    {
        string path = "D:\\Laravel";
        TreeNode dNode = new TreeNode(new FileInfo(path).Name);
        fileView.Nodes[0].Nodes.Add(dNode);
        LoadFile(dNode, path);
    }
}

Nodes[0]是“我的电脑”节点。我刚刚测试的根是“D:\Laravel”,结果如下:

正如你所看到的,“Laravel”文件夹出现了两次。我不能修复它,虽然我已经尝试删除fileView.Nodes[0].Nodes.Add(dNode);,但没有工作。

mklgxw1f

mklgxw1f1#

在Load事件处理程序中,首先创建一个节点,将其添加到现有的根节点(My Computer),然后将该节点传递给LoadFile()方法。
这个ne节点在传递给方法时会变成根节点TreeNode parent,而方法会使用string path参数将新节点加入其中,因此会复制根节点。
您可以保留根节点,将它传递给方法,沿着成为新子节点或根节点的Path值,例如,

private void WindowExplorer_Load(object sender, EventArgs e)
{
    string path = "D:\\Laravel";

    // Clear the TreeView if necessary / preferable:  
    //  fileView.Nodes.Clear();
    //  var root = fileView.Nodes.Add("My Computer");
    //  LoadFile(root, path);

    LoadFile(fileView.Nodes[0], path);
}

您的LoadFile()方法可能需要进行一些重构,因为它在同一过程中生成了大量字符串并(* synchronized *)查询了文件系统两次。
可以使用DirectoryInfo.GetFileSystemInfos()方法同时检索文件和目录,使用file属性确定文件是否具有FileAttributes.Directory属性,并按文件名排序。
请注意,循环是在IOrderedEnumerable<FileSystemInfo>集合上执行的,因此循环在枚举仍在进行时运行。

public void LoadFile(TreeNode parent, string path)
{
    var dir = new TreeNode(Path.GetFileName(path));
    parent.Nodes.Add(dir);

    var files = new DirectoryInfo(path).GetFileSystemInfos()
        .OrderBy(fsi => fsi.Attributes).ThenBy(fsi => fsi.Name);

    foreach (var file in files) {
        // If the current file is a Directory, recurse its content
        if (file.Attributes.HasFlag(FileAttributes.Directory)) {
            LoadFile(dir, file.FullName);
        }
        else {
            // Not a directory, add the file to the current Node
            dir.Nodes.Add(file.Name);
        }
    }
}

相关问题