Componente TreeView em C# WinForms: Exemplos de Implementação Básica

O controle TreeView é um elemento funadmental em aplicações de desktop Windows Forms (WinForms) quando se precisa exibir dados hierárquicos de forma intuitiva. Ele permite apresentar informações em uma estrutura de árvore expansível e recolhível, onde os usuários podem navegar facilmente entre os nós pai e filho. Este artigo explora as funcionalidades básicas do TreeView em C#, incluindo a construção programática da árvore a partir de dados, manipulação de eventos de seleção e configurações de expansão.

  1. Construção da Estrutura da Árvore

Para popular um TreeView, geralmente começamos com uma fonte de dados que define a relação pai-filho entre os itens. Uma abordagem comum é usar uma lista de objetos que contêm identificadores para o próprio item e para seu pai.

1.1. Definição do Modelo de Dados

Vamos definir uma classe simples para representar os itens que serão exibidos na árvore. Cada item terá um identificador único, um identificador do pai (onde 0 pode indicar um nó raiz), um texto para exibição e um valor associado.


namespace WinFormsApp1
{
   public partial class MainForm : Form
   {
       public MainForm()
       {
           InitializeComponent();
       }

       /// <summary>
       /// Modelo para itens da árvore hierárquica.
       /// </summary>
       public class ItemDeArvore
       {
           /// <summary>
           /// Texto a ser exibido no nó da árvore.
           /// </summary>
           public string TextoExibicao { get; set; }

           /// <summary>
           /// Valor associado ao nó (pode ser usado para dados adicionais).
           /// </summary>
           public string ValorAssociado { get; set; }

           /// <summary>
           /// Identificador único do item.
           /// </summary>
           public int IdUnico { get; set; }

           /// <summary>
           /// Identificador do item pai (0 para nós raiz).
           /// </summary>
           public int IdPai { get; set; }
       }

       // ... (restante do código da classe Form)
   }
}
   

1.2. Preenchendo o TreeView com Dados Recursivamente

A seguir, criaremos um método que simula a obtenção de dados e outro método auxiliar recursivo para construir os nós da árvore. O método principal será acionado por um botão, limpando o TreeView existente e cnostruindo a nova estrutura.


       /// <summary>
       /// Manipulador do clique do botão para construir a árvore.
       /// </summary>
       private void btnCarregarArvore_Click(object sender, EventArgs e)
       {
           // Simulação de uma fonte de dados
           List<ItemDeArvore> listaItens = new List<ItemDeArvore>
           {
               new ItemDeArvore { IdUnico = 1, TextoExibicao = "Avô", IdPai = 0, ValorAssociado = "Valor do Avô" },
               new ItemDeArvore { IdUnico = 2, TextoExibicao = "Pai", IdPai = 1, ValorAssociado = "Valor do Pai" },
               new ItemDeArvore { IdUnico = 3, TextoExibicao = "Filho", IdPai = 2, ValorAssociado = "Valor do Filho" },
               new ItemDeArvore { IdUnico = 4, TextoExibicao = "Filha", IdPai = 2, ValorAssociado = "Valor da Filha" },
               new ItemDeArvore { IdUnico = 5, TextoExibicao = "Tia", IdPai = 1, ValorAssociado = "Valor da Tia" },
               new ItemDeArvore { IdUnico = 6, TextoExibicao = "Primo", IdPai = 5, ValorAssociado = "Valor do Primo" }
           };

           // Chama o método para popular o TreeView
           PopularTreeView(myTreeView, listaItens);
       }

       /// <summary>
       /// Popula um controle TreeView a partir de uma lista de ItemDeArvore.
       /// </summary>
       /// <param name="treeView"></param>O controle TreeView a ser populado.
       /// <param name="dados"></param>A lista de ItemDeArvore que contém os dados.
       private void PopularTreeView(TreeView treeView, List<ItemDeArvore> dados)
       {
           treeView.Nodes.Clear(); // Limpa quaisquer nós existentes

           // Encontra e adiciona os nós raiz (aqueles com IdPai = 0)
           var nosRaiz = dados.Where(item => item.IdPai == 0);

           foreach (var itemRaiz in nosRaiz)
           {
               TreeNode novoNo = CriarNoRecursivo(itemRaiz, dados);
               treeView.Nodes.Add(novoNo);
           }
       }

       /// <summary>
       /// Método recursivo para criar um TreeNode e seus filhos.
       /// </summary>
       /// <param name="itemAtual"></param>O ItemDeArvore atual a ser convertido em TreeNode.
       /// <param name="todosOsDados"></param>A lista completa de todos os ItemDeArvore para encontrar os filhos.
       /// <returns>O TreeNode criado com seus filhos.</returns>
       private TreeNode CriarNoRecursivo(ItemDeArvore itemAtual, List<ItemDeArvore> todosOsDados)
       {
           TreeNode no = new TreeNode(itemAtual.TextoExibicao);
           no.Tag = itemAtual; // Armazena o objeto de dados original no Tag do nó

           // Encontra todos os filhos do itemAtual
           var filhos = todosOsDados.Where(item => item.IdPai == itemAtual.IdUnico);

           foreach (var filho in filhos)
           {
               // Chama recursivamente para criar os nós filhos
               no.Nodes.Add(CriarNoRecursivo(filho, todosOsDados));
           }

           return no;
       }
   
  1. Manipulação de Eventos de Seleção

Quando um usuário seleciona um nó na árvore, é comum querer exibir informações detalhadas sobre esse nó ou realizar alguma ação. O evento AfterSelect do TreeView é o local ideal para capturar essa interação.


       /// <summary>
       /// Manipulador do evento AfterSelect do TreeView, acionado quando um nó é selecionado.
       /// </summary>
       private void myTreeView_AfterSelect(object sender, TreeViewEventArgs e)
       {
           // Garante que um nó foi realmente selecionado
           if (e.Node == null) return;

           // Recupera o objeto ItemDeArvore associado ao nó selecionado
           ItemDeArvore itemSelecionado = e.Node.Tag as ItemDeArvore;

           if (itemSelecionado != null)
           {
               lblInfoNoSelecionado.Text = $"Nó: {itemSelecionado.TextoExibicao}, Valor: {itemSelecionado.ValorAssociado}";

               // Exibe o caminho dos ancestrais do nó selecionado
               string caminhoAncestrais = ObterCaminhoAncestral(e.Node);
               lblCaminhoAncestral.Text = $"Caminho: {caminhoAncestrais}";
           }
       }

       /// <summary>
       /// Constrói uma string com o caminho completo de um nó até a raiz.
       /// </summary>
       /// <param name="no"></param>O TreeNode do qual o caminho ancestral será obtido.
       /// <returns>Uma string representando o caminho ancestral, e.g., "Avô > Pai > Filho".</returns>
       private string ObterCaminhoAncestral(TreeNode no)
       {
           Stack<string> caminho = new Stack<string>();
           TreeNode noAtual = no;

           while (noAtual != null)
           {
               caminho.Push(noAtual.Text);
               noAtual = noAtual.Parent;
           }

           // Remove o primeiro elemento (o próprio nó selecionado) se não quiser incluí-lo no "caminho ancestral"
           // Se você quer o caminho completo incluindo o nó atual:
           // return string.Join(" > ", caminho.ToList());

           // Se você quer apenas os ancestrais, sem o nó atual:
           if (caminho.Count > 0) caminho.Pop(); // Remove o próprio nó
           return string.Join(" > ", caminho.ToList());
       }
   
  1. Recursos de Expansão e Colapso

O TreeView oferece controle sobre como os nós são exibidos inicialmente e como eles respondem às interações do usuário.

3.1. Expansão Padrão

É possível configurar o TreeView para expandir todos os nós ou apenas os nós de nível superior automaticamente.


       /// <summary>
       /// Expande todos os nós na árvore.
       /// </summary>
       private void ExpandirTudo()
       {
           myTreeView.ExpandAll();
       }

       /// <summary>
       /// Expande apenas os nós de primeiro nível.
       /// </summary>
       private void ExpandirPrimeiroNivel()
       {
           foreach (TreeNode no in myTreeView.Nodes)
           {
               no.Expand();
           }
       }
   

3.2. Expansão/Colapso ao Clicar

Por padrão, o TreeView expande e colapsa nós quando o usuário clica no ícone de seta ou no sinal de mais/menos. Para replicar essa funcionalidade com um clique em qualquer parte do texto do nó, você pode usar o evento NodeMouseClick.


       /// <summary>
       /// Manipulador do evento NodeMouseClick para expandir/colapsar o nó ao clicar.
       /// </summary>
       private void myTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
       {
           if (e.Node != null)
           {
               if (e.Node.IsExpanded)
               {
                   e.Node.Collapse(); // Se já estiver expandido, colapsa
               }
               else
               {
                   e.Node.Expand(); // Se estiver colapsado, expande
               }
           }
       }
   

Tags: C# WinForms treeview UI recursion

Publicado em 10-21 06:13