С# Treeview проверяет, существует ли узел

Я пытаюсь заполнить древовидную структуру из 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?



        }

Спасибо.


person Darren Young    schedule 23.05.2011    source источник


Ответы (8)


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;
    }
person Vale    schedule 23.05.2011
comment
Я не верю, что это полностью рекурсивно. По сути, он будет искать только непосредственные дочерние узлы. - person Yuck; 23.05.2011
comment
В этом случае можно легко создать рекурсивный метод. - person Vale; 23.05.2011
comment
if (subNode.Text.Equals(key)) { return subNode; } if (subNode.Nodes.Count › 0) { NodeExists(subNode, key); } - person Akvel; 08.02.2012

В зависимости от размера вашего XML-файла вы можете рассмотреть возможность использования связанного List для быстрого поиска. Когда вы добавляете каждый узел в TreeView, также добавляйте его в List.

person Yuck    schedule 23.05.2011

Если ваш XML-документ имеет установленную структуру, в которой «Отделы» всегда будут индексироваться как 1;

ie:

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;

Идея состоит в том, что вы будете вызывать эту функцию каждый раз, когда сталкиваетесь с узлом "Отдел" в своем Xml перед созданием TreeNode.

Полный пример:

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.

person David Anderson    schedule 23.05.2011


Вы можете сделать что-то вроде этого:

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
    }
}
person Alex Mendez    schedule 23.05.2011

Не уверен насчет структуры документа...
Не могли бы вы использовать Linq to 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>
person Vijay Sirigiri    schedule 23.05.2011

Я использую,

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

Эта строка гарантирует, что сначала будет выполнен поиск отдела ценности, и если он не будет найден, он создаст его. Вы должны сделать двойную запись в Add(), чтобы у нее было значение ключа, которое вы можете выполнить поиск с помощью .Nodes[department].

person Chuck Savage    schedule 25.05.2011

Это зависит от структуры вашего ввода. Поскольку вы не показываете, как именно вы добавляете свои подузлы, я могу только указать вам на метод Contains или ContainsKey для Nodes, либо самого treeView1, либо любых добавляемых вами подузлов. Вы должны использовать перегрузку метода Add, чтобы указать имя ключа для упрощения поиска.

person takrl    schedule 23.05.2011