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) { }
Благодаря второму параметру «e» мы можем получить любую информацию о выделенном элементе в 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 (значение атрибута) и кнопку с надписью «изменить».
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 и получаем название и значение его атрибута, используя предыдущий пример.
Затем изменим, значение атрибута в textbox.Value и нажмём кнопку «изменить»
Если сейчас открыть добавленный в проект XML файл то появиться надпись, о том, что файл был изменён и будет предложено обновить информацию в нём.
Нажимаем кнопку с надписью «YES», после чего данные внутри 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.
Читайте также:
Спасибо за статью. Но данный код неприменим (имхо) для больших файлов, я пробовал его со своими XML файлами.. 6 Мб файл ждал около 20 минут.. потом прервал .. для интереса сейчас оставлю комп думать.. засек время..
Но часть кода касаемую изменения атрибутов — взял на заметку.
p.s. обработка заняла 1 час примерно
это только для 1 файла…
Сергей, прочитал комментарий про задачу, завтра пример добавлю, скорее всего, в виде статьи, чтоб было более наглядно. По поводу скорости обработки, да, есть такое.
Получилось значительно увеличить скорость, описание добавил в конце статьи.
За скорость огромное спасибо … я не догадался до такого решения. Но все же есть 1 момент: если у элемента есть дочерние элементы — то атрибуты самого элемента не рисуются. Это плохо, попробую сам добить код до идеала.
p.s. не рисуются в дереве я хотел сказать
Добавил статью с примером. Так же поправлены примеры кода для работы с XML файлом.
День добрый.
Взял на заметку Вашу статью про рекурсию.Большое спасибо. Попробовал под WinForm все работает. А как сделать тоже самое под web? У меня ругается вот на эту строчку inTreeNode.Nodes.Add(new TreeNode(xNode.Attributes[«text»].InnerText));
Пишет
«System.Xml.Linq.Extensions.Nodes(System.Collections.Generic.IEnumerable)» является «метод», который недопустим в данном контексте
Спасибо
Решил свой вопрос. Делюсь знаниями. Все работает.
В самой строке кода ошибки нет. Если копипастили код, то нужно проверить, например поставить точку после inTreeNode (вручную) и посмотреть появляется список свойств и методов или нет, как вариант.
А, ну так проблема в другом. Используется объект типа TreeNode, у которого нет свойства Nodes. Вместо него используется св-во ChildNodes вот и ошибка, это же не объект типа TreeView.
Пример очень хороший, пока не пробывал, но очень необходимо сделать, на против каждого элемента, ну так сказать марки машины, кнопку(3) по которой я бы смог увидеть фото и тд!?
и еще очень важный момент, в целом получается иерархия, так вот можно ли сделать так:
если я кликну в самый верх, то откроется такая то картинка, если кликну во вторую строчку то откроется другая?
пример