Pagina personale di:
Carlo Vecchio
appunti di C#, R, SQL Server, ASP.NET, algoritmi, numeri
Vai ai contenuti

C# - Lavorare con i TreeView

C#
Introduzione
  • L'oggetto TreeView consente di mostrare informazioni aggregate e gerarchiche.
  • Ogni elemento è un 'Nodo' e ha diverse proprietà; le più importanti sono le seguenti:
    • 'Name': è la chiave che identifica il nodo.
    • 'Text': è il testo che viene mostrato.
    • 'ImageKey': è la chiave che punta all'immagine da mostrare.
    • 'SelectedImageKey': è la chiave che punta all'immagine da mostrare se il nodo è selezionato.
    • 'ToolTipText': è il testo da mostrare quando il mouse è sopra al nodo.
  • Le immagini da mostrare nel TreeView, sono contenute in un oggetto ImageList, che va collegato al TreeView.

Esempio
  • Nell'esempio seguente si crea una TreeView a due livelli, che organizza in modo gerarchico degli oggetti di tipo 'Level1' e 'Level2'.
  • Ogni oggetto di tipo Level1 può avere più oggetti di tipo Level2; ci saranno quindi dei nodi di tipo 'Level1' che conterranno i nodi di tipo 'Level2'.
  • Nei nodi di primo livello si vuole aggiungere una immagine con una lettera P; nei nodi di secondo livello si vuole una immagine con la lettera S. Se uno dei nodi è selezionato (sia di primo che di secondo livello), la rispettiva immagine deve avere un colore diverso. In pratica bisogna creare quattro diverse immagini.
  • Nella figura seguente è il risultato finale con i nodi di primo livello chiusi.



Definizione della classe
  • Si definisce la classe 'TreeViewData'. Essa contiene tutte le informazioni sui nodi del TreeView.
  • La classe ha una struttura che ne rende l'utilizzo molto semplice qualora i dati da caricare nel TreeView sia presenti in un Database o in una struttura tabellare simile (per esempio in DataTable).
  • In pratica sono presenti N blocchi di attributi, uno per ogni livello del TreeView. Ogni blocco ha le proprietà che servono al TreeView:
    • Name.
    • Text.
    • ImageKey.
    • SelectedImageKey.
    • ToolTipTex.
  • Nell'esempio in corso, dovendo gestire due livelli, ci sono cinque attributi per il livello 1 e cinque attributi per il livello 2.
  • È presente anche un costruttore che riceve tutti i dieci attributi.

   class TreeViewData
   {
       public string L1_Name { get; set; }
       public string L1_Text { get; set; }   
       public string L1_ImageKey { get; set; }   
       public string L1_SelectedImageKey { get; set; }
       public string L1_ToolTipText { get; set; }
       public string L2_Name { get; set; }
       public string L2_Text { get; set; }
       public string L2_ImageKey { get; set; }
       public string L2_SelectedImageKey { get; set; }
       public string L2_ToolTipText { get; set; }

       public TreeViewData(string l1_name, string l1_text, string l1_ImageKey
           , string l1_SelectedImageKey, string l1_ToolTipText
           , string l2_name, string l2_text, string l2_ImageKey
           , string l2_SelectedImageKey, string l2_ToolTipText)
       {
           L1_Name = l1_name;
           L1_Text = l1_text;
           L1_ImageKey = l1_ImageKey;
           L1_SelectedImageKey = l1_SelectedImageKey;
           L1_ToolTipText = l1_ToolTipText;
           L2_Name = l2_name;
           L2_Text = l2_text;
           L2_ImageKey = l2_ImageKey;
           L2_SelectedImageKey = l2_SelectedImageKey;
           L2_ToolTipText = l2_ToolTipText;
       }
   }

  • Con questa classe vanno generati tanti oggetti, quanti sono i nodi del livello più basso (livello 2 in questo esempio).
  • Per esempio, un nodo del livello 1 che ha tre sotto-nodi di livello 2, viene rappresentato con tre oggetti. In tutti e tre gli oggetti le proprietà del primo blocco sono identiche, mentre le proprietà del secondo blocco sono quelle dei tre sotto-nodi.

Immagini per il TreeView
  • L'oggetto TreeView mostra delle piccole icone di default in corrispondenza dei nodi, sono dei piccoli '+'.
  • Per modificare queste icone si procede così.
  • Disegnare con un qualsiasi editor di icone, due icone per ogni livello. La prima icona sarà mostrata in corrispondenza del rispettivo nodo, la seconda sarà mostrata quando il rispettivo nodo è selezionato.
  • Le immagini possono essere per esempio 48x48 pixel, in formato PNG.
  • In questo esempio ho disegnato le seguenti icone:

        

  • Le immagini precedenti sono poste nella cartella 'Resources' del progetto e rispettivamente hanno i seguenti nomi:
    • Level1.png
    • Level1Selected.png
    • Level2.png
    • Level2Selected.png
  • Attenzione: non basta che le immagini siano 'copiate' nella cartella 'Resources', ma bisogna che siano 'inglobate'. Trascinarle quindi in proprietà del progetto, nel tab 'Resources'.
  • Nell'evento 'Form_Load()' viene preparata una ImageList; essa viene inoltre collegata al TreeView (il cui nome è 'trvData'). Ecco il codice per definire la ImageList (a livello di form) e quello relativo all'evento.

  static ImageList ImgList;

   private void Form1_Load(object sender, EventArgs e)
   {
       // Crea la ImageList e la collega al TreeView.
       ImgList = new ImageList();
       ImgList.Images.Add("ImgLevel1", Properties.Resources.Level1);
       ImgList.Images.Add("ImgLevel1Selected", Properties.Resources.Level1Selected);
       ImgList.Images.Add("ImgLevel2", Properties.Resources.Level2);
       ImgList.Images.Add("ImgLevel2Selected", Properties.Resources.Level2Selected);
       trvData.ImageList = ImgList;

       // Abilita la visualizzazione dei ToolTips.
       trvData.ShowNodeToolTips = true;
   }

Caricamento del TreeView
  • Ecco codice completo per caricare il TreeView.
  • Il primo passo è quello di pulire il TreeView.

   trvData.Nodes.Clear();

  • Adesso si definisce una lista contenente gli oggetti di tipo 'TreeViewData'.
  • Gli oggetti inseriti in lista, come spiegato sopra, sono:
    • Primo nodo livello 1 / Primo sotto-nodo livello 2.
    • Primo nodo livello 1 / Secondo sotto-nodo livello 2.
    • Primo nodo livello 1 / Terzo sotto-nodo livello 2.
    • Secondo nodo livello 1 / Quarto sotto-nodo livello 2.
    • Secondo nodo livello 1 / Quinto sotto-nodo livello 2.
    • Secondo nodo livello 1 / Sesto sotto-nodo livello 2.

   // Lista dati.
   List<TreeViewData> lstData = new List<TreeViewData>();
   lstData.Add(new TreeViewData("KEY_LEVEL1_1", "Testo livello 1, primo oggetto.", "ImgLevel1", "ImgLevel1Selected", "Tool Tip livello 1, primo oggetto.", "KEY_LEVEL2_1", "Testo livello 2, primo oggetto.", "ImgLevel2", "ImgLevel2Selected", "Tool Tip livello 2, primo oggetto."));
   lstData.Add(new TreeViewData("KEY_LEVEL1_1", "Testo livello 1, primo oggetto.", "ImgLevel1", "ImgLevel1Selected", "Tool Tip livello 1, primo oggetto.", "KEY_LEVEL2_2", "Testo livello 2, secondo oggetto.", "ImgLevel2", "ImgLevel2Selected", "Tool Tip livello 2, secondo oggetto."));
   lstData.Add(new TreeViewData("KEY_LEVEL1_1", "Testo livello 1, primo oggetto.", "ImgLevel1", "ImgLevel1Selected", "Tool Tip livello 1, primo oggetto.", "KEY_LEVEL2_3", "Testo livello 2, terzo oggetto.", "ImgLevel2", "ImgLevel2Selected", "Tool Tip livello 2, terzo oggetto."));
   lstData.Add(new TreeViewData("KEY_LEVEL1_2", "Testo livello 1, secondo oggetto.", "ImgLevel1", "ImgLevel1Selected", "Tool Tip livello 1, secondo oggetto.", "KEY_LEVEL2_4", "Testo livello 2, quarto oggetto.", "ImgLevel2", "ImgLevel2Selected", "Tool Tip livello 2, quarto oggetto."));
   lstData.Add(new TreeViewData("KEY_LEVEL1_2", "Testo livello 1, secondo oggetto.", "ImgLevel1", "ImgLevel1Selected", "Tool Tip livello 1, secondo oggetto.", "KEY_LEVEL2_5", "Testo livello 2, quinto oggetto.", "ImgLevel2", "ImgLevel2Selected", "Tool Tip livello 2, quinto oggetto."));
   lstData.Add(new TreeViewData("KEY_LEVEL1_2", "Testo livello 1, secondo oggetto.", "ImgLevel1", "ImgLevel1Selected", "Tool Tip livello 1, secondo oggetto.", "KEY_LEVEL2_6", "Testo livello 2, sesto oggetto.", "ImgLevel2", "ImgLevel2Selected", "Tool Tip livello 2, sesto oggetto."));

  • Nel codice seguente viene elaborata la lista 'lstData'.
  • Il nodo di livello 1 viene creato solo se l'oggetto i-esimo è diverso dal precedente (relativamente al 'Name' del livello 1).
  • Il nodo di livello 2 viene invece sempre creato ed aggiunto al nodo di livello 1 in elaborazione.

   if (lstData.Count > 0)
   {
       string previousKey = String.Empty;
       TreeNode t1 = new TreeNode();   // Generico nodo Livello 1.
       TreeNode t2 = new TreeNode();   // Generico nodo Livello 2.

       for (int i = 0; i < lstData.Count; i++)
       {
           // Se cambiato il nodo di Livello 1...
           if (lstData[i].L1_Name != previousKey)
           {
               // Si crea un nodo di Livello 1.
               t1 = new TreeNode();
               t1.Name = lstData[i].L1_Name;
               t1.Text = lstData[i].L1_Text;
               t1.ImageKey = lstData[i].L1_ImageKey;
               t1.SelectedImageKey = lstData[i].L1_SelectedImageKey;
               t1.ToolTipText = lstData[i].L1_ToolTipText;
               // Aggiunta del nodo al TreeView.
               trvData.Nodes.Add(t1);
           }

           // Nodo del Livello 2.
           t2 = new TreeNode();
           t2.Name = lstData[i].L2_Name;
           t2.Text = lstData[i].L2_Text;
           t2.ImageKey = lstData[i].L2_ImageKey;
           t2.SelectedImageKey = lstData[i].L2_SelectedImageKey;
           t2.ToolTipText = lstData[i].L2_ToolTipText;
           // Aggiunta del TreeNode al Livello 1 corrente.
           t1.Nodes.Add(t2);

           previousKey = lstData[i].L1_Name;
       }
   }

Conclusioni
  • A questo punto il TreeView è correttamente caricato.
  • Ogni nodo ha un nome (proprietà 'Name') e un testo (proprietà 'Text'); avendo impostato anche la proprietà 'ToolTipText', ponendo il puntatore del mouse sopra un qualsiasi nodo, se ne vedrà il valore.
  • Per sapere quale nodo è selezionato è sufficiente fare riferimento alla proprietà 'SelectedNode', per esempio:

   label1.Text = trvData.SelectedNode.Name;

  • Nell'immagine seguente, TreeView con in nodi aperti. Si è inoltre selezionato il nodo presente nella seconda riga, lo si riconosce dall'icona verde.
  • Nella parte superiore della form, la stringa "KEY_LEVEL2_1" indica appunto il nome del nodo selezionato.






© 2020 Carlo Vecchio
Torna ai contenuti