【问题标题】:C# Treeview checking if node existsC# Treeview 检查节点是否存在
【发布时间】:2011-08-31 02:54:16
【问题描述】:

我正在尝试从 XmlDocument 填充树视图。 树的根设置为“脚本”,从根开始下一级应该是 XML 脚本中的“部门”。我可以从 XML 文档中获取数据没有问题。我的问题是当循环通过 XmlDocument 并将节点添加到根节点时,我想确保如果一个部门已经在树视图中,那么它不会再次添加。我还应该补充一点,每个部门还有一个脚本列表,需要成为该部门的子节点。

到目前为止我的代码是:

        XmlDocument xDoc = new XmlDocument();
        xDoc.LoadXml(scriptInformation);
        TreeNode t1;
        TreeNode rootNode = new TreeNode("Script View");
        treeView1.Nodes.Add(rootNode);
        foreach (XmlNode node in xDoc.SelectNodes("//row"))
        {
            t1 = new TreeNode(node["DEPARTMENT"].InnerXml);
           //How to check if node already exists in treeview?



        }

谢谢。

【问题讨论】:

    标签: c# winforms treeview


    【解决方案1】:
    if(treeView1.Nodes.ContainsKey("DEPARTMENT")){
    //...
    }
    

    编辑:递归方法:

     bool exists = false;
            foreach (TreeNode node in treeView1.Nodes) {
                if (NodeExists(node, "DEPARTMENT"))
                    exists = true;
            }
        private bool NodeExists(TreeNode node, string key) {
            foreach (TreeNode subNode in node.Nodes) {
                if (subNode.Text == key) {
                    return true;
                }
                if (node.Nodes.Count > 0) {
                    NodeExists(node, key);
                }
            }
            return false;
        }
    

    【讨论】:

    • 我不相信这是完全递归的。实际上,它只会搜索直接子节点。
    • 在这种情况下可以轻松创建递归方法。
    • if (subNode.Text.Equals(key)) { return subNode; } if (subNode.Nodes.Count > 0) { NodeExists(subNode, key); }
    【解决方案2】:

    根据您的 XML 文件的大小,您可以考虑使用关联的List 进行快速查找。当您将每个节点添加到 TreeView 时,也将其添加到 List

    【讨论】:

      【解决方案3】:

      如果您的 XML 文档有一个固定的结构,其中“部门”的索引始终为 1;

      即:

      index:[0] Scripts
          index:[1] Department
              index:[2] Script
          index:[1] Department2
              index:[2] Script
      

      然后你可以将下面的代码封装成一个方法,其中'name'是一个字符串参数,返回类型是布尔值。

      foreach (TreeNode node in uxTreeView.Nodes[0].Nodes) {
          if (node.Name.ToLower() == name.ToLower()) {
              return true;
          }
      }
      return false;
      

      我们的想法是,在创建 TreeNode 之前,每次在 Xml 中遇到“部门”节点时都将调用该函数。

      完整示例:

      private bool DepartmentNodeExists(string name) {
          foreach (TreeNode node in uxTreeView.Nodes[0].Nodes) {
              if (node.Name.ToLower() == name.ToLower()) {
                  return true;
              }
          }
          return false;
      }
      

      最后,简单方法:

      private bool DepartmentNodeExists(string name) {
          if (uxTreeView.Nodes[0].ContainsKey(name)) {
              return true;
          }
          else {
              return false;
          }
      }
      

      这些都只是重构并封装到它们自己的命名方法中,你当然可以调用:

      if (uxTreeView.Nodes[0].ContainsKey(name)) {
          // do not create TreeNode
      }
      

      ...在解析 XML 期间。 PS。这些示例都假设您已经在 TreeView 中创建了第一个根节点并将其添加到 TreeView。

      【讨论】:

        【解决方案4】:
        【解决方案5】:

        你可以这样做:

        TreeNode parentNode = t1.Parent;
        if (parentNode != null}
        {
            if(parentNode.Nodes.Cast<TreeNode>().ToList().Find(t => t.Text.Equals(node["DEPARTMENT"].InnerXml) == null)
            {
                //Add node
            }
        }
        else
        {
            bool isFound = true;
            if (treeView1.Nodes.Cast<TreeNode>().ToList().Find(t => t.Text.Equals(node["DEPARTMENT"].InnerXml) == null)
            {
                isFound = false;
            }
        
            if(!isFound)
            {
                //Add node
            }
        }
        

        【讨论】:

          【解决方案6】:

          不确定文档结构...
          难道你不能使用 Linq to Xml,加载文档并获取不同的行(行 = 部门?)并只考虑那些元素来创建 TreeNode?它比尝试查找是否已添加具有此类文本的节点更有效。 例如:

           var rows =      (  from row  in XDocument.Load(document).Root.Elements("row")
                              select row
                           ).Distinct(new SampleElementComparerOnNameAttribute());
          

          这里 EqualityComparer 是在“name”属性值上进行的,假设文档结构为

          <rows><row name='dep1'><script>script1</script><script>script2</script></row><row name='dep1'><script>script3</script><script>script4</script></row></rows>
          

          【讨论】:

            【解决方案7】:

            我用过,

            string department = node["DEPARTMENT"].InnerXml;
            TreeNode node = parentNode.Nodes[department] ?? parentNode.Nodes.Add(department, department);
            

            该行保证将首先查找价值部门,如果没有找到它会创建它。您必须在 Add() 中进行双重输入,这样它就会有一个键值,您可以使用 .Nodes[department]. 进行查找

            【讨论】:

              【解决方案8】:

              这取决于您输入的结构。由于您没有显示您添加子节点的确切方式,我只能将您指向Nodes 属性的ContainsContainsKey 方法,treeView1 本身或您添加的任何子节点.您应该使用 Add 方法的重载来指定键名以简化查找。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-04-16
                • 1970-01-01
                • 1970-01-01
                • 2017-06-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-08-16
                相关资源
                最近更新 更多