Работа с элементом управления TreeView в языке c#

c# работа с элементом управления TreeView

Для начала создадим Windows Forms приложение. После чего добавим на форму элемент управления TreeView, который будет заполняться данными из XML файла.

каркас приложения

Добавим в проект XML файл. Если вы не знаете, как это сделать, то можете прочитать об этом здесь

Структура файла:

<?xml version="1.0" encoding="utf-8" ?>
<cars>
<models name = "rusAuto">
<car id="1"> VAZ </car>
<car id="2"> UAZ </car>
</models>
</cars>

Затем добавим ссылку типа XmlDocument и путь к xml файлу.

public partial class MainForm : Form
{
XmlDocument xmlDoc;
string xmlpath = @"..\..\Example.xml";

Заполнение TreeView данными из XML файла

Изобретать чего-то нового не будем, а воспользуемся готовым решением с сайта MSDN и просто скопируем код. После чего первую часть кода поместим в обработчик события Load главной формы.

private void MainForm_Load(object sender, EventArgs e)
{
xmlDoc = new XmlDocument();
xmlDoc.Load(xmlpath);
treeView1.Nodes.Clear();
treeView1.Nodes.Add(new TreeNode(xmlDoc.DocumentElement.Name));
TreeNode rootNode = new TreeNode();
rootNode = treeView1.Nodes[0];
AddNode(xmlDoc.DocumentElement, rootNode);
treeView1.ExpandAll();
}

Затем добавим вторую часть скопированного кода

private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
{
XmlNode xNode;
TreeNode tNode;
XmlNodeList nodeList;
int i;
if (inXmlNode.HasChildNodes)
{
nodeList = inXmlNode.ChildNodes;
for (i = 0; i  1; i++)
{
xNode = inXmlNode.ChildNodes[i];
inTreeNode.Nodes.Add(new TreeNode(xNode.Name));
tNode = inTreeNode.Nodes[i];
AddNode(xNode, tNode);
}
}
else
{
inTreeNode.Text = (inXmlNode.OuterXml).Trim();
}
}

Пробуем запустить приложение, нажимаем кнопку F5.

данные в виде иерархического дерева

Древовидная структура успешно отобразилась и теперь можно переходить к решению часто встречающихся задач.

Работа с элементами

Все примеры этой главы нужно поместить в обработчик события NodeMouseClick элемента управления TreeView.

private void treeView1_NodeMouseClick(object sender,
TreeNodeMouseClickEventArgs e)
{
}

Благодаря второму параметру &#171;e&#187; мы можем получить любую информацию о выделенном элементе в TreeView.

второй параметр

1. Получить название выделенного элемента

e.Node.Text;
Например: MessageBox.Show(e.Node.Text);

результат

2. Получить индекс выделенного элемента

int indexNode =  e.Node.Index;

3. Получить количество дочерних элементов:

int countChildNodes = e.Node.Nodes.Count;

4. Изменить название выделенного элемента

e.Node.Text = "MAZ";

результат

5. Изменить название дочернего элемента

e.Node.Nodes[0].Text = "GAZEL";

новое название

6. Удалить выделенный элемент

e.Node.Remove();

Например, удалим VAZ.

удаление элемента

Следующий метод не обязательно помещать в данный обработчик события, его можно вызвать в любом другом месте кода.

7. очистить TreeView

treeView1.Nodes.Clear();

Все выше описанные действия затрагивают только данные внутри элемента управления TreeView и не как не отражаются в XML файле. То есть, к примеру, удаляя выделенный элемент, вы удаляете его только из коллекции элементов TreeView, но не из файла XML.

Работа с Xml файлом

Теперь рассмотрим пару примеров, как можно взаимодействовать с XML файлом. Но перед этим дополним графический интерфейс нашего приложения, добавив на форму: 2 лейбла, 2 текстовых поля: txtboxAtrName (имя атрибута), txtboxAtrValue (значение атрибута) и кнопку с надписью &#171;изменить&#187;.

GUI

1. Выбрав элемент, мы хотим получить все его атрибуты в виде пары: название и значение.

private void treeView1_NodeMouseClick(object sender, 
TreeNodeMouseClickEventArgs e)
{
//находим узел по имени
XmlNodeList nodes = xmlDoc.GetElementsByTagName(e.Node.Text);
txtboxAtrName.Text = "";
txtboxAtrValue.Text = "";
if (nodes.Count > 0)
{
XmlAttributeCollection atrCol;
atrCol = nodes[e.Node.Index].Attributes;
if (atrCol.Count > 0)
{
//получаем все атрибуты
foreach (XmlAttribute atr in atrCol)
{
txtboxAtrName.Text = atr.Name;
txtboxAtrValue.Text = atr.Value;
}
}
}
}

Например, получим имя и значение атрибута элемента models. Результат на картинке

получение атрибутов

В данном примере для вывода данных используется control Textbox, так как у элементов всего по одному атрибуту. Если же атрибутов будет больше, то используйте другие элементы управления, чтобы получить все значения.

2. Хотим изменить значение какого-либо атрибута в xml файле

private void btnChange_Click(object sender, EventArgs e)
{
if (treeView1.SelectedNode != null)
{
XmlNodeList nodes;
nodes = xmlDoc.GetElementsByTagName(treeView1.SelectedNode.Text);
//получаем индекс
int index = treeView1.SelectedNode.Index;
if (nodes.Count > 0)
{
foreach (XmlAttribute attribute in nodes[index].Attributes)
{
attribute.InnerText = txtboxAtrValue.Text;
}
//вносим изменения в XML файл
xmlDoc.Save(xmlpath);
}
}
}

Принцип работы прост. Выделяем элемент в TreeView и получаем название и значение его атрибута, используя предыдущий пример.

1 шаг

Затем изменим, значение атрибута в textbox.Value и нажмём кнопку &#171;изменить&#187;

2 шаг

Если сейчас открыть добавленный в проект XML файл то появиться надпись, о том, что файл был изменён и будет предложено обновить информацию в нём.

сообщение

Нажимаем кнопку с надписью &#171;YES&#187;, после чего данные внутри XML файла изменяться.

результат

Update

Если загрузка элементов в TreeView происходит слишком медленно, то попробуйте воспользоваться методом BeginUpdate

treeView1.BeginUpdate(); //добавить
treeView1.Nodes.Clear();
treeView1.Nodes.Add(new TreeNode(xmlDoc.DocumentElement.Name));
TreeNode rootNode = new TreeNode();
rootNode = treeView1.Nodes[0];
AddNode(xmlDoc.DocumentElement, rootNode);
treeView1.ExpandAll();
treeView1.EndUpdate(); //добавить

Видео 1.

Видео 2.

Читайте также:

Tags: × ×

12 комментариев

  1. Сергей says:

    Спасибо за статью. Но данный код неприменим (имхо) для больших файлов, я пробовал его со своими XML файлами.. 6 Мб файл ждал около 20 минут.. потом прервал .. для интереса сейчас оставлю комп думать.. засек время..

    Но часть кода касаемую изменения атрибутов &#8212; взял на заметку.

    p.s. обработка заняла 1 час примерно

    это только для 1 файла&#8230;

  2. Сергей, прочитал комментарий про задачу, завтра пример добавлю, скорее всего, в виде статьи, чтоб было более наглядно. По поводу скорости обработки, да, есть такое.

  3. Получилось значительно увеличить скорость, описание добавил в конце статьи.

  4. Сергей says:

    За скорость огромное спасибо &#8230; я не догадался до такого решения. Но все же есть 1 момент: если у элемента есть дочерние элементы &#8212; то атрибуты самого элемента не рисуются. Это плохо, попробую сам добить код до идеала.

  5. Сергей says:

    p.s. не рисуются в дереве я хотел сказать

  6. Добавил статью с примером. Так же поправлены примеры кода для работы с XML файлом.

  7. Алексей says:

    День добрый.
    Взял на заметку Вашу статью про рекурсию.Большое спасибо. Попробовал под WinForm все работает. А как сделать тоже самое под web? У меня ругается вот на эту строчку inTreeNode.Nodes.Add(new TreeNode(xNode.Attributes[&#171;text&#187;].InnerText));
    Пишет
    &#171;System.Xml.Linq.Extensions.Nodes(System.Collections.Generic.IEnumerable)&#187; является &#171;метод&#187;, который недопустим в данном контексте

    Спасибо

  8. Алексей says:

    Решил свой вопрос. Делюсь знаниями. Все работает.

    private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
    {
    XmlNode xNode;
    TreeNode tNode;
    XmlNodeList nodeList;
    int i;
    if (inXmlNode.HasChildNodes)
    {
    nodeList = inXmlNode.ChildNodes;
    for (i=0; i <= nodeList.Count-1 ; i++)
    {
    xNode = inXmlNode.ChildNodes[i];
    inTreeNode.ChildNodes.Add(new TreeNode(xNode.Attributes["text"].InnerText));
    inTreeNode.SelectAction = TreeNodeSelectAction.None;
    tNode = inTreeNode.ChildNodes[i];
    AddNode(xNode, tNode);
    }
    }
    }
  9. В самой строке кода ошибки нет. Если копипастили код, то нужно проверить, например поставить точку после inTreeNode (вручную) и посмотреть появляется список свойств и методов или нет, как вариант.

    А, ну так проблема в другом. Используется объект типа TreeNode, у которого нет свойства Nodes. Вместо него используется св-во ChildNodes вот и ошибка, это же не объект типа TreeView.

  10. саня says:

    Пример очень хороший, пока не пробывал, но очень необходимо сделать, на против каждого элемента, ну так сказать марки машины, кнопку(3) по которой я бы смог увидеть фото и тд!?

  11. саня says:

    и еще очень важный момент, в целом получается иерархия, так вот можно ли сделать так:
    если я кликну в самый верх, то откроется такая то картинка, если кликну во вторую строчку то откроется другая?

Leave a Reply

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*