You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TreeView从数据库加载文件夹时根目录重复问题求助

解决TreeView加载目录时重复根目录的问题

在使用C# TreeView实现文件夹浏览器时,需为文件管理器添加根文件夹,通过数据库加载目录结构,但数据库(80GB)无法修改路径列。现有代码处理Root\example这类路径时,会生成Root\Root\Example的重复根目录结构。

问题根源分析

问题出在这段路径前缀处理逻辑:

if (cartella.StartsWith("Root\\") == false && cartella != "Root")
    cartella = "Root\\" + cartella;

代码已经手动创建了名为"Root"的根节点,同时又给原本就以Root\开头的路径再添加Root\前缀,导致拆分路径后,第一个节点"Root"会被添加到已有的根节点下,形成嵌套的Root\Root结构。


解决方案

核心思路:先统一处理路径,移除所有路径开头的Root\或Root,转为相对根节点的路径,再直接将子节点添加到已创建的根节点下,彻底避免重复前缀问题。

修改后的完整代码

private void PopulateTreeView()
{
    int idPortafoglioValue = 0;
    if (Request.QueryString["id"] != null)
        idPortafoglioValue = int.Parse(Request.QueryString["id"]);
    string strsql = "SELECT DISTINCT cartella FROM TblPortafogli_Documenti WHERE idportafoglio =" + idPortafoglioValue + creaWhere();
    DataTable dt = Funzioni.OttieniTabellaDalDataBase(strsql);
    List<string> cartelleCreate = new List<string>();
    TreeView.Nodes.Clear(); // 清空现有节点

    // 创建根节点
    TreeNode rootNode = new TreeNode("Root");
    TreeView.Nodes.Add(rootNode);

    if (dt.Rows.Count == 0)
    {
        return;
    }
    else
    {
        foreach (DataRow dr in dt.Rows)
        {
            string cartella = dr["cartella"].ToString();
            string dir = "";

            // 统一替换路径分隔符
            if (cartella.Contains("/"))
                cartella = cartella.Replace('/', '\\');

            // 移除路径开头的Root\或Root,转为相对根节点的路径
            if (cartella.StartsWith("Root\\"))
                cartella = cartella.Substring("Root\\".Length);
            else if (cartella == "Root")
                cartella = "";

            TreeNode currentNode = rootNode;
            // 拆分路径并创建节点,跳过空条目避免无效节点
            foreach (string stringa in cartella.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries))
            {
                dir += (dir == "" ? "" : "\\") + stringa;
                // 检查当前节点下是否已存在目标子节点
                var existingNode = currentNode.ChildNodes.Cast<TreeNode>().FirstOrDefault(n => n.Value == dir);
                if (existingNode == null)
                {
                    existingNode = new TreeNode(stringa, dir);
                    currentNode.ChildNodes.Add(existingNode);
                    cartelleCreate.Add(dir);
                }
                // 移动到下一级节点继续构建
                currentNode = existingNode;
            }
        }
    }
    TreeView.CollapseAll();
}

额外优化

原有的trovaNodo递归查找方法可以直接移除,新逻辑通过FirstOrDefault直接在当前节点的子节点中查找,代码更简洁高效。


关键改进点

  1. 路径归一化:将所有路径转为相对根节点的形式,彻底避免重复添加Root前缀
  2. 节点构建逻辑优化:从已创建的根节点开始逐层构建子节点,确保目录结构正确
  3. 空条目过滤:使用StringSplitOptions.RemoveEmptyEntries避免拆分空路径时生成无效节点
  4. 直接查找节点:替代递归查找,提升代码可读性与执行效率

内容的提问来源于stack exchange,提问作者Zakkwylde84

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 20:03:12