2014-10-24 2 views
2

У меня есть флажок в виде дерева и список содержит узлы, подносы и, в некоторых случаях, subnode subnode. Когда пользователь проверяет некоторые элементы, я хочу получить список выбранных элементов.Получить список всех проверенных узлов и его подносов в treeview

Об этом, почему я получаю только selcted пунктов главного узла:

foreach (System.Windows.Forms.TreeNode aNode in tvSastavnica.Nodes) 
     { 
      if (aNode.Checked == true) 
      { 
       Console.WriteLine(aNode.Text); 
      } 
     } 

Как траверс через весь TreeView и получить выбранные элементы в подузлах?

+5

Чтобы понять рекурсию, сначала необходимо понять рекурсию –

+0

Проверьте мое решение и сказать мне, если что-то не понятно! – mybirthname

ответ

3
public void GetCheckedNodes(TreeNodeCollection nodes) 
{ 
    foreach(System.Windows.Forms.TreeNode aNode in nodes) 
    { 
     //edit 
     if(aNode.Checked) 
      Console.WriteLine(aNode.Text); 

     if(aNode.Nodes.Count != 0) 
      GetCheckedNodes(aNode.Nodes); 
    } 
} 

Вы не заглядываете в детские заметки, используя рекурсию, вы можете это сделать.

Вам нужен такой метод! В вашем коде просто вызовите один раз GetCheckedNodes(tvSastavnica.Nodes), и все проверенные узлы должны быть отображены!

+0

Ваше решение очень эффективно, но оно основано на предположении, что проверенный дочерний узел должен также иметь свой родительский элемент. Он, к сожалению, не работает, если проверен глубокий подузел, а его родительский элемент - нет. Поскольку это ограничение не было задано в вопросе, я предлагаю удалить инструкцию «continue» и вернуть проверенный тест, чтобы все дерево было пройдено. – Larry

+0

@ Larry, вы правы, я сделаю редактирование! Спасибо за комментарий ! – mybirthname

7

Если вы хотите LINQ, вы можете создать метод расширения, который пересекает весь TreeView:

internal static IEnumerable<TreeNode> Descendants(this TreeNodeCollection c) 
{ 
    foreach (var node in c.OfType<TreeNode>()) 
    { 
     yield return node; 

     foreach (var child in node.Nodes.Descendants()) 
     { 
      yield return child; 
     } 
    } 
} 

Затем вы можете выполнять все операции, которые вы хотите с помощью LINQ. В вашем случае получить список выбранных узлов легко:

var selectedNodes = myTreeView.Nodes.Descendants() 
        .Where(n => n.Checked) 
        .Select(n => n.Text) 
        .ToList(); 

Преимущество такого подхода в том, что оно является общим.

Однако, поскольку метод Descendant() пересекает все дерево, он может быть немного менее эффективным, чем ответ, заданный @mybirthname, поскольку он заботится только о узлах, которые проверяются вместе с родителями. Я не знаю, включает ли ваш случай использования это ограничение.

EDIT: теперь ответ @mybirthname был отредактирован, он делает то же самое. Теперь у вас есть цикл и решение LINQ, оба являются рекурсивными.

+0

Именно то, что я искал! –

1

мой путь:

void LookupChecks(TreeNodeCollection nodes, List<TreeNode> list) 
{ 
    foreach (TreeNode node in nodes) 
    { 
     if (node.Checked) 
      list.Add(node); 

     LookupChecks(node.Nodes, list); 
    } 
} 

Useage:

var list = new List<TreeNode>(); 
LookupChecks(TreeView.Nodes, list);