2011-05-23 369 views
1

我試圖從XmlDocument填充一個樹形視圖。 樹的根被設置爲「腳本」,並且從根目錄開始,下一級應該是XML腳本中的「部門」。我可以從XML文檔中獲取數據沒有問題。我的問題是,當循環遍歷XmlDocument並向根節點添加節點時,我想確保如果一個部門已經在樹視圖中,那麼它不會再被添加。我還應該補充一點,每個部門都有一個需要成爲部門子節點的腳本列表。C#TreeView檢查節點是否存在

到目前爲止我的代碼是:

 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? 



     } 

感謝。

回答

2
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; 
    } 
+0

執行查找。我不相信這是完全遞歸的。實際上,它只會搜索直接的子節點。 – Yuck 2011-05-23 12:29:31

+0

在這種情況下,可以很容易地創建遞歸方法。 – Vale 2011-05-23 12:38:38

+0

if(subNode.Text.Equals(key)) return subNode; (subNode.Nodes.Count> 0) { } NodeExists(subNode,key); } – Akvel 2012-02-08 17:06:31

0

這取決於您輸入的結構。由於您沒有顯示如何正確添加子節點,因此我只能將您指向ContainsNodes屬性的Nodes屬性的方法,即treeView1本身或您添加的任何子節點。您應該使用Add方法的重載來指定密鑰名稱以簡化查找。

1

根據您的XML文件的大小,你可以考慮使用相關的List快速查找。當您將每個節點添加到TreeView時,也將其添加到List

1

你可以做這樣的事情:

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 
    } 
} 
1

如果你的XML文檔有一組結構,其中「部門」總是以1被索引;

即:

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

然後,你可以封裝下面的代碼,其中「名稱」是一個字符串參數和返回值類型爲布爾的方法。

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

想法是每次在創建TreeNode之前遇到Xml中的'Department'節點時,都會調用該函數。

完整的示例:

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中。

1

不知道有關文檔結構的...
你不能使用LINQ到XML,加載文檔,並獲得不同的行(行=部門?),並考慮只有那些創建TreeNode的元素?它比試圖找到具有這種文本的節點是否已被添加更有效。 例如:

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

這裏EqualityComparer是在 「名稱」 屬性值假設文檔結構做成

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

我用,

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

該行保證一個價值部門的查詢將首先完成,如果沒有找到它會創建它。您必須在Add()中進行雙重輸入,因此它將具有一個鍵值,您可以使用.Nodes[department].