ID значения в TreeView, поиск TreeNode по ключу

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

Обычно простого значения в виде текста недостаточно. Если мы связываем наш TreeView с базой данных и он служит нам, например, деревом разделов каталога, то для нормальной работы программы нам нужно иметь в коллекции не только название раздела, но и его первичный ключ.
Чтобы было понятнее, я приведу пример с подзапросами, однако на практике лучше получить один массив данных и работать только с ним.

Выстраиваем TreeView с ключом и значением

Предположим, что у нас есть некий набор данных DataTable sections полученный из базы, его структура будет состоять из ключа (int), названия раздела (nvarchar), ключа родительского раздела (int).
Для начала получим только разделы верхнего уровня:

select id, section_name from sections where parent_id is null

В качестве ячейки для идентификатора используем Tag:

for(int i = 0; i < sections.Rows.Count; i++)
{
//Заполняем родителей:
    treeView1.Nodes.Add((string)sections.Rows[i].ItemArray[1]).Tag = sections.Rows[i].ItemArray[0];
//Ищем дочерние разделы для заполнения:
    fillnode((int)sections.Rows[i].ItemArray[0], treeView1.Nodes[i]);
}

Выстроить полноценное многоуровневое дерево с неизвестным количеством уровней нам поможет рекурсия:

private void fillnode(int id, TreeNode node) {
//Сначала получаем список дочерних разделов. Метод getDataTable абстрактный.
    DataTable dt = getDataTable("select id, section_name, parent_id from product_sections where parent_id = @id", id);
    for(int j = 0; j < dt.Rows.Count; j++)
    {
        node.Nodes.Add((string)dt.Rows[j].ItemArray[1]).Tag = dt.Rows[j].ItemArray[0];
        fillnode((int)dt.Rows[j].ItemArray[0], node.Nodes[j]);
    }
}

Поиск TreeNode по значению Tag

Теперь разберёмся как найти TreeNode и открыть его, если нам известен только ключ (Tag).
Поскольку в TreeView мы сталкиваемся с вложенными коллекциями, искать получится только полным рекурсивным перебором:

private void FindByTag(TreeNodeCollection Nodes, int tagValue)
{
    for (int i = 0; i< Nodes.Count;i++) {
//Не забываем, что в этом примере в Tag мы записывали числовой первичный ключ!
        if ((int)Nodes[i].Tag == tagValue)
        {
//Раскрываем нужный пункт 
            sectionsTree.SelectedNode = Nodes[i];
            sectionsTree.SelectedNode.EnsureVisible();
            sectionsTree.SelectedNode.Expand();
        }
        else {
//Запускаем рекурсию
            FindByTag(Nodes[i].Nodes, tagValue);
        }
    }
}

 

Добавить комментарий

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

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.