Как заполнить WinForms TreeView из XML-файла, независимо от количества детей и внуков - PullRequest
0 голосов
/ 09 февраля 2019

Извините, если это было опубликовано ранее, но все решения, которые я смог найти, касались только адресованных файлов XML на слое потомков.

У меня есть форма, отображающая древовидную структуру.Вместо того, чтобы редактировать непосредственно в коде, я хочу создать файл XML и заполнить его древовидным представлением.Мой XML похож на это:

<Root>
  <Element>
    <ChildElement>
      <GrandChildElement></GrandChildElement>
      <GrandChildElement></GrandChildElement>
    </ChildElement>
    <ChildElement>
      <GrandChildElement></GrandChildElement>
      <GrandChildElement></GrandChildElement>
    </ChildElement>
  </Element>
  <Element>
    <ChildElement>
      <GrandChildElement></GrandChildElement>
      <GrandChildElement></GrandChildElement>
    </ChildElement>
    <ChildElement>
      <GrandChildElement></GrandChildElement>
      <GrandChildElement></GrandChildElement>
    </ChildElement>
  </Element>
</Root>

GrandChildElements - это интерактивные узлы в моем дереве, которые можно использовать для выбора разных вещей.Остальное используется, чтобы визуально классифицировать их.

Пока мне не удалось найти способ включить элементы GrandChildElements.Заполнение его без GrandChildElements может быть выполнено с помощью рекурсии следующим образом:

private void treeView_Load(object sender, EventArgs e)
{
    XmlDocument xmldoc = new XmlDocument();
    System.IO.FileStream fs = new System.IO.FileStream("treeNodes.xml", FileMode.Open, FileAccess.Read);
    xmldoc.Load(fs);
    XmlNode xmlnode = xmldoc.ChildNodes[1];
    tvKortskab.Nodes.Clear();
    tvKortskab.Nodes.Add(new TreeNode(xmldoc.DocumentElement.Name));
    TreeNode tNode = tvKortskab.Nodes[0];
    AddNode(xmlnode, tNode);
}


 private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
 {
     XmlNode xNode;
     TreeNode tNode;
     XmlNodeList childNodes;
     XmlNodeList subChildNodes;
     if (inXmlNode.HasChildNodes)
     {
         childNodes = inXmlNode.ChildNodes;
         for (int i = 0; i <= childNodes.Count - 1; i++)
         {
             xNode = childNodes[i];
             inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
             tNode = inTreeNode.Nodes[i];
             AddNode(xNode, tNode);
         }
         else
         {
             inTreeNode.Text = inXmlNode.InnerText.ToString();
         }
 }

Я пробовал вложить в него цикл, проверяя, есть ли у дочерних узлов дочерние элементы, и затем добавляя их.Это сработало, но также добавило кучу пустых и дублирующих узлов.

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

Ваша идея была правильной, и вы поступили правильно.

Но в заявлении else вы сделали что-то не так.Вы говорите, что «GrandChildElement» должен показывать InnerText, и этот текст пуст, поэтому вы получаете пустой элемент.Вместо этого вам нужно использовать свойство Name.

if (inXmlNode.HasChildNodes)
{
    childNodes = inXmlNode.ChildNodes;
    for (int i = 0; i <= childNodes.Count - 1; i++)
    {
        xNode = childNodes[i];
        inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
        tNode = inTreeNode.Nodes[i];
        AddNode(xNode, tNode);
    }
}
else
{
    inTreeNode.Text = inXmlNode.Name;
}
0 голосов
/ 09 февраля 2019

Надеюсь, я понимаю, что вы имели в виду.

Поскольку ваши узлы GrandChildren пусты, в следующей строке будет показано пустое значение.

inTreeNode.Text = inXmlNode.InnerText.ToString();

Одно из возможных решений - показать узелимя, если innerText пуст.

inTreeNode.Text = string.IsNullOrEmpty(inXmlNode.InnerText)? inXmlNode.Name :  inXmlNode.InnerText.ToString();

PS: Кстати, у вас была возможная опечатка здесь

XmlNode xmlnode = xmldoc.ChildNodes[1];

Это должно быть

XmlNode xmlnode = xmldoc.ChildNodes[0];

Предыдущий вывод

enter image description here

Новый вывод

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...