c# - TreeView 文件夹结构有异常

标签 c# winforms combobox treeview

我有两个 TreeView,每个 TreeView 都会在云端硬盘上生成一个文件夹结构。 该程序只有 1 个 comboBox 来在 2 个驱动器中构建两个 TreeViews。 我只使用一个 comboBox,因为 F:Z:

上几乎每个文件夹都具有相同的名称

我说几乎是因为我有 3 个文件夹,它们的名称相似,但不完全相同。

假设我的 DropDown 看起来像这样:

Book1
Book2
Book3
Book4

所以 Z: 上的目录看起来像上面的示例,因为这是我的 comboBox 的来源

R:看起来像这样:

Book1
Book2
Book3_projects_render
Book4

所以我的代码适用于 Book1、Book2 和 Book4,但是当我单击 DropDown 上的 Book3 并创建 TreeView 结构时,它将在 R 上创建一个新目录:名为 Book3,我想要实现的解决方案是Book3_projects_render 等目录存在异常(exception),因此它不会创建新目录。

我的代码:

public Form1()
{
    InitializeComponent();
    // ...

    loremDropDown.DisplayMember = "Name";
    loremDropDown.ValueMember = "FullName";
    loremDropDown.DataSource = new DirectoryInfo("F:\\").GetDirectories();
}

private void SomeButton_Click(object sender, EventArgs e)
{
    var driveF = "F:\\";
    var driveZ = "Z:\\";
    var selDir = loremDropDown.SelectedValue.ToString();
    var destPathF = selDir.Replace(Path.GetPathRoot(selDir), driveF);
    var destPathZ = selDir.Replace(Path.GetPathRoot(selDir), driveZ);
    var treeSep = pathLorem.PathSeparator;
    var dirSep = Path.DirectorySeparatorChar.ToString();
    var shortcuts = new HashSet<string>();

    foreach (var node in GetCheckedNodes(pathLorem.Nodes))
    {
        var sPath = Path.Combine(destPathF, node.FullPath.Replace(treeSep, dirSep));
        Directory.CreateDirectory(sPath);

        if (node.Level == 0) shortcuts.Add(sPath.TrimStart(driveF.ToArray()));
    }

    foreach (var node in GetCheckedNodes(ipsumPath.Nodes))
    {
        var sPath = Path.Combine(destPathZ, node.FullPath.Replace(treeSep, dirSep));
        Directory.CreateDirectory(sPath);

        if (node.Level == 0) shortcuts.Add(sPath.TrimStart(driveZ.ToArray()));
    }

    foreach (var shortcut in shortcuts)
    {
        var dirF = $"{driveF}{shortcut}";
        var dirZ = $"{driveZ}{shortcut}";

        if (Directory.Exists(dirF) && Directory.Exists(dirZ))
        {
            CreateShortcut(dirF, dirZ);
            CreateShortcut(dirZ, dirF);
        }
    }
}

private void CreateShortcut(string shortcutPath, string targetPath)
{
    WshShell wshShell = new WshShell();
    string fileName = Path.Combine(shortcutPath, $"{Application.ProductName}.lnk");
    IWshShortcut shortcut = (IWshShortcut)wshShell.CreateShortcut(fileName);
    shortcut.TargetPath = targetPath;
    shortcut.Save();
}

最佳答案

在创建目录之前重命名 TreeNode 对象

这是一种根据 Jimi's 重命名给定文件夹的方法建议。

  • 创建 Dictionary<string, string>将目标文件夹作为键,将新名称作为值。
  • 对于每个TreeView控制,将其节点克隆到临时 TreeView更改 .Text目标节点的属性,而不反射(reflect)在主节点上 TreeView控制。设置.Text属性对于获得正确的 .FullPath 是必要的重命名父节点和/或子节点时的属性。
private void SomeButton_Click(object sender, EventArgs e)
{
    var driveF = "C:\\";
    var driveZ = "D:\\";
    var selDir = loremDropDown.SelectedValue.ToString();
    var destPathF = selDir.Replace(Path.GetPathRoot(selDir), driveF);
    var destPathZ = selDir.Replace(Path.GetPathRoot(selDir), driveZ);
    var treeSep = pathLorem.PathSeparator;
    var dirSep = Path.DirectorySeparatorChar.ToString();
    var shortcuts = new HashSet<string>();
    var dirsToRename = new Dictionary<string, string>
    {
        { "Book 4", "Book 1" },
        { "Book 5", "Book 2" },
        { "Book 6", "Book 3" },
        { "Books", "Books 123" }
    };

    using (var tv = new TreeView())
    {
        tv.Nodes.AddRange(pathLorem.Nodes
            .OfType<TreeNode>()
            .Select(n => n.Clone() as TreeNode)
            .ToArray());

        foreach (var node in GetCheckedNodes(tv.Nodes))
        {
            if (dirsToRename.ContainsKey(node.Text)) node.Text = dirsToRename[node.Text];
            var sPath = Path.Combine(destPathF, node.FullPath.Replace(treeSep, dirSep));
            Directory.CreateDirectory(sPath);
            if (node.Level == 0) shortcuts.Add(sPath.TrimStart(driveF.ToArray()));
        }

        tv.Nodes.Clear();
        tv.Nodes.AddRange(ipsumPath.Nodes
            .OfType<TreeNode>()
            .Select(n => n.Clone() as TreeNode)
            .ToArray());

        foreach (var node in GetCheckedNodes(tv.Nodes))
        {
            if (dirsToRename.ContainsKey(node.Text)) node.Text = dirsToRename[node.Text];
            var sPath = Path.Combine(destPathZ, node.FullPath.Replace(treeSep, dirSep));
            Directory.CreateDirectory(sPath);
            if (node.Level == 0) shortcuts.Add(sPath.TrimStart(driveZ.ToArray()));
        }

        foreach (var shortcut in shortcuts)
        {
            var dirF = $"{driveF}{shortcut}";
            var dirZ = $"{driveZ}{shortcut}";

            if (Directory.Exists(dirF) && Directory.Exists(dirZ))
            {
                CreateShortcut(dirF, dirZ);
                CreateShortcut(dirZ, dirF);
            }
        }
    }
}

根据目的地重命名给定的 TreeNode 对象

key 取自 ComboBox控制。

private void btnTest_Click(object sender, EventArgs e)
{
    var driveF = "C:\\";
    var driveZ = "D:\\";
    var selDir = loremDropDown.SelectedValue.ToString();
    var destPathF = selDir.Replace(Path.GetPathRoot(selDir), driveF);
    var destPathZ = selDir.Replace(Path.GetPathRoot(selDir), driveZ);
    var treeSep = pathLorem.PathSeparator;
    var dirSep = Path.DirectorySeparatorChar.ToString();
    var shortcuts = new HashSet<string>();
    var dirsToRename = new Dictionary<string, string>
    {
        { "Book 1", "Book 4" },
        { "Book 2", "Book 5" },
        { "Book 3", "Book 6" }
    };

    foreach (var node in GetCheckedNodes(pathLorem.Nodes))
    {
        var sPath = Path.Combine(destPathF, node.FullPath.Replace(treeSep, dirSep));

        // Comment this if `pathLorem` is not the source of the keys...
        if (dirsToRename.ContainsKey(node.Text))
            sPath = Path.Combine(Path.GetDirectoryName(sPath), dirsToRename[node.Text]);

        Directory.CreateDirectory(sPath);

        if (node.Level == 0) shortcuts.Add(sPath.TrimStart(driveF.ToArray()));
    }

    foreach (var node in GetCheckedNodes(ipsumPath.Nodes))
    {
        var sPath = Path.Combine(destPathZ, node.FullPath.Replace(treeSep, dirSep));

        // Comment this if `ipsumPath` is not the source of the keys...
        if (dirsToRename.ContainsKey(node.Text))
            sPath = Path.Combine(Path.GetDirectoryName(sPath), dirsToRename[node.Text]);

        Directory.CreateDirectory(sPath);

        if (node.Level == 0) shortcuts.Add(sPath.TrimStart(driveZ.ToArray()));
    }

    foreach (var shortcut in shortcuts)
    {
        var dirF = $"{driveF}{shortcut}";
        var dirZ = $"{driveZ}{shortcut}";

        if (Directory.Exists(dirF) && Directory.Exists(dirZ))
        {
            CreateShortcut(dirF, dirZ);
            CreateShortcut(dirZ, dirF);
        }
    }
}

您可以添加一个控件,例如 DataGridView获取 dirsToRename 的键值对字典而不是硬代码。

创建目录后重命名

您可以通过调用.Move来重命名系统文件或目录。 File 的方法和 Directory 分别为类。

// Rename a file...
File.Move("source", "destination");

// Rename a directory...
Directory.Move("source", "destination");

将选定的目录映射到另一个目录

映射 ComboBox 中的选定目录到另一个目录,更改 destPathFdestPathZ (不是两者)取决于目标目录的位置(例如 Book3_projects_render)。

例如:

private void SomeButton_Click(object sender, EventArgs e)
{
    var driveF = "C:\\";
    var driveZ = "D:\\";
    var selDirInfo = loremDropDown.SelectedItem as DirectoryInfo;
    var selDir = selDirInfo.FullName;
    var destPathF = selDir.Replace(Path.GetPathRoot(selDir), driveF);
    var destPathZ = selDir.Replace(Path.GetPathRoot(selDir), driveZ);
    var treeSep = pathLorem.PathSeparator;
    var dirSep = Path.DirectorySeparatorChar.ToString();
    var shortcuts = new HashSet<string>();
    var exDir = "Book 3";
    var repDir = "Book3_projects_render";
    bool isExDir = selDirInfo.Name == exDir;

    if (isExDir)
    {
        // If `Book3_projects_render` is on F: otherwise comment...
        //destPathF = Path.Combine(Path.GetDirectoryName(destPathF), "Book3_projects_render");

        // If `Book3_projects_render` is on Z: otherwise comment...
        destPathZ = Path.Combine(Path.GetDirectoryName(destPathZ), repDir);
    }

    foreach (var node in GetCheckedNodes(pathLorem.Nodes))
    {
        var sPath = Path.Combine(destPathF, node.FullPath.Replace(treeSep, dirSep));
        Directory.CreateDirectory(sPath);
        if (node.Level == 0) shortcuts.Add(sPath.Substring(driveF.Length));
    }

    foreach (var node in GetCheckedNodes(ipsumPath.Nodes))
    {
        var sPath = Path.Combine(destPathZ, node.FullPath.Replace(treeSep, dirSep));
        Directory.CreateDirectory(sPath);
        if (node.Level == 0) shortcuts.Add(sPath.Substring(driveZ.Length));
    }

    foreach (var shortcut in shortcuts)
    {
        var dirF = $"{driveF}{shortcut}";
        var dirZ = $"{driveZ}{shortcut}";

        if (isExDir)
        {
            // If `Book3_projects_render` is on Z: otherwise switch exDir and repDir...
            dirF = dirF.Replace($@"\{repDir}\", $@"\{exDir}\");
            dirZ = dirZ.Replace($@"\{exDir}\", $@"\{repDir}\");
        }

        if (Directory.Exists(dirF) && Directory.Exists(dirZ))
        {
            CreateShortcut(dirF, dirZ);
            CreateShortcut(dirZ, dirF);
        }
    }
}

关于c# - TreeView 文件夹结构有异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73783249/

相关文章:

c# - 如何在 C# 中使用 HttpClient 读取 webapi 响应

c# - WebBrowser 控件和 Adob​​e Flash 内容

WPF ComboBox SelectedItem

c# - 如何在每个wpf/MVVM组合框行上显示2个字符串?

C# Combobox (Dropdownstyle = Simple) -- 如何在键入时选择项目

C# MySQL 事务提交

C# & MySQL 多字段搜索

c# - protected 字段的符合 CLS 的正确命名约定是什么?

c# - 如何使用组合框中的字典隐藏 UI 输出中的方括号?

c# - 防止标签点击事件作为默认行为