Перечислить узлы TreeView в C#
Предыдущие два сообщения показывают два способа перечисления узлов TreeView, которые проверяются. Идея состоит в том, чтобы рекурсивно сканировать узлы дерева и выбрать проверенные.
К сожалению, этот метод нелегко растягивается. Например, если вы хотите найти узлы, которые были расширены, вам нужно будет написать новый код для этого. Новый код будет почти таким же, как старый код, но с другим тестом, чтобы увидеть, должен ли узел быть включен в результат.
В этом примере показано, как вы можете перечислить узлы TreeView для проверки каждого узла. Затем основная программа может проверить, какие узлы ей нужно использовать.
Чтобы упростить использование кода, в примере определены три метода расширения для класса TreeView.
Первые два показаны в следующем коде. Они работают вместе так, чтобы было легче сказать, какой из них я цвет, закодировал их призывы друг к другу.
// Вернуть узлы в этой коллекции и их потомках. public static IEnumerableDescendants( this TreeNodeCollection nodes) { foreach (TreeNode node in nodes) { yield return node; foreach (TreeNode child in node.Nodes.Descendants()) { yield return child; } } } // Вернем этот узел и его потомков. public static IEnumerable Descendants(this TreeNode node) { yield return node; foreach (TreeNode child in node.Nodes.Descendants()) { yield return child; } }
Первый (синий) метод работает на TreeNodeCollection. Он перемещается по узлам в коллекции и вызывает второй (красный) метод для каждого.
Первый (синий) метод работает на TreeNodeCollection. Он проходит через узлы в коллекции и дает каждому узлу перечисление. Затем он вызывает второй (красный) метод для коллекции Nodes каждого узла, чтобы перечислять потомки узла. Он перемещается по возвращенным узлам и дает их.
Второй (красный) метод работает с одним TreeNode. Сначала он дает узел. Затем он использует первый (синий) метод для перечисления потомков узла. Он пересекает потомков и дает их.
В этом выражается общая жалоба на инструкцию yield. Нет простого способа вернуть результаты другого метода IEnumerable. Вместо этого вам нужно выполнить итерацию и вернуть каждое из значений по отдельности.
В этом примере также определяется следующий метод расширения для элемента управления TreeView.
// Возвращает все узлы TreeView. public static IEnumerableDescendants(this TreeView trv) { foreach (TreeNode node in trv.Nodes.Descendants()) yield return node; }
Этот метод просто вызывает предыдущий (синий), чтобы перечислять узлы TreeView в коллекции Nodes элемента управления.
Это, вероятно, самый полезный из трех методов расширения. Фактически вы могли бы сделать два других private, чтобы они не могли использоваться вне класса, который их определяет.
Теперь, когда программа имеет способ перечислить узлы TreeView, для поиска проверяемых узлов используется код, похожий на следующий.
// Список проверочных TreeNodes. private void btnShowChecked_Click(object sender, EventArgs e) { string results = ""; foreach (TreeNode node in trvMeals.Descendants()) { if (node.Checked) results += node.Text + "\n"; } MessageBox.Show(results); }
Этот код использует последний (зеленый) метод расширения для перечисления узлов элемента управления. Если узел проверен, он добавляет его в строку. Когда это будет завершено, программа отобразит строку.