Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Работа с TreeView


Автор: Corey 19.7.2011, 12:35
Здравствуйте.
Подскажите, пожалуйста! 
Имеется дерево, нужно, чтобы при выставлении флага в дочернем узле автоматически выделялись все его родительские узлы. И здесь проблема, у меня реализовано, чтобы при выделении флагом родительского узла, автоматически выделялись и дочернии. Т.е. происходит как бы обратная реакция.
Как это можно разрешить?

Автор: Суровый 19.7.2011, 13:10
Corey, 
Самое простое решение - не форсированно выставлять флаги, а сделать проверку выставлены ли они или нет. Если не выставлены - выставить, а если выставлены - ничего не делать, что прекратит запуск обработчиков.

Автор: Corey 19.7.2011, 13:50
Спасибо за ответ.
Но если, допустим, флаги не выставлены и выставляются в соответствии с алгоритмом выставления флагов на родительских узлах. То здесь как раз и срабатывает опять событие AfterCheck с выставленем флагов дочерних, которых совсем не нужно помечать.

Автор: Суровый 19.7.2011, 13:56
Corey, 
Вы не совсем поняли)
Проверку нужно сделать в обоих обработчиках.

Автор: Corey 19.7.2011, 14:42
Но как тогда поставить условие, что выставление флага идет родительского узла (чтоб не помечать его потомков), а не текущего (в этом случае помечаются флагами дочерние). Отписка от событий не помогает, точнее, отписаться получается для пометки родительского, но возобновить подписку не удается

Автор: Суровый 20.7.2011, 10:03
Возможно не очень красивое решение, но больше ничего в голову не лезет.
Обрабатываем событие "клик по ноде"
Код

        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (wasChanged)
            {
                if (e.Node.Checked)
                {
                    foreach (TreeNode node in e.Node.Nodes)
                        checkChilds(node);
                    checkParents(e.Node);
                }
            }
            wasChanged = false;
        }

Переменная wasChanged показывает, привел ли клик по ноде к изменению состояния чекбокса.
Это выполняется следующим кодом:
Код

        private void treeView1_BeforeCheck(object sender, TreeViewCancelEventArgs e)
        {
            wasChanged = true;
        }

Функции checkChilds и checkParents работают рекурсивно:
Код

        private void checkChilds(TreeNode parent)
        {
            parent.Checked = true;
            foreach (TreeNode node in parent.Nodes)
                checkChilds(node);
        }

        private void checkParents(TreeNode node)
        {
            if (node.Parent != null)
            {
                node.Parent.Checked = true;
                checkParents(node.Parent);
            }
        }


Вот такие пироги. Прошу сильно не бить  smile 

Автор: Corey 23.7.2011, 14:01
Спасибо большое за помощь smile Все замечательно работает! Проставляет и пэренты, но вместе с ними отмечает и все остальные низ лежащие узлы  smile 

Автор: Corey 26.7.2011, 15:21
Да, все получилось, еще раз спасибо!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)