Afficher un arbre dans une fenêtre en C#
Nous avons vu comment récupérer les informations d'une classe par réflexion, et comment peupler un arbre avec ces données, et nous avons vu comment afficher ces arbres dans la console. Nous avons aussi vu comment créer une fenêtre pour notre application, et comment sélectionner le fichier à analyser.
Maintenant, nous allons voir comment afficher les arbres dans notre fenêtre.
Ajouter un TreeView
Nous allons utiliser un composant TreeView, qui appartient à System.Windows.Forms.
Dans l'onglet Solution Explorer de Visual Studio, nous devons sélectionner notre fichier Form1.cs, qui s'ouvrira par défaut en mode design.
Dans l'onglet Toolbox, nous pouvons sélectionner un composant TreeView, et le glisser à l'aide de la souris (drag and drop) directement sur la représentation de la fenêtre. Comme dans le cas d'un éditeur graphique, nous pouvons déplacer le TreeView pour le positionner correctement sur la fenêtre de notre application, puis sélectionner un des coins du TreeView, et l'étendre jusqu'au moment ou sa taille nous convient.
Nous pouvons modifier le nom du composant pour lui donner un nom significatif dans le code (par exemple classInfoTreeView).
Construire le TreeView
Nous avons donc une fenêtre avec un composant TreeView, mais ce dernier est vide. Nous pouvons doublecliquer sur notre menu File/Open de notre fenêtre en mode design et Visual Studio nous place directement dans notre méthode fileToolStripMenuItem_Click (qui jusqu'ici permettait l'affichage du nom du fichier sélectionné).
A cet endroit, nous allons faire appel à une méthode (que nous pouvons appeler fillTreeView()) qui permettra de peupler le TreeView avec les TreeNodes que nous récupérons gràce à notre classe ClassInfo.
Code c# (Form1.cs fileToolStripMenuItem_Click) (6 lignes)
private void fileToolStripMenuItem_Click(object sender, EventArgs e) { openFileDialog.ShowDialog(); fillAndDisplayPathLabel(); fillTreeView(); }
Code c# (Form1.cs fillTreeView) (6 lignes)
private void fillTreeView() { classInfoTreeView.Nodes.Clear(); classInfoTreeView.Nodes.Add(ClassInfo.getFileName(openFileDialog.FileName)); classInfoTreeView.Nodes[0].Nodes.AddRange(ClassInfo.getInfos(openFileDialog.FileName)); }
Ce n'est pas plus compliqué que ça.
Les différents nœuds de l'arbre sont automatiquement représentés en couleur, car la couleur est définie dans la classe ClassInfo au moment de la création des TreeNodes.
Cette manière de procéder est pratique et rapide, mais nous pouvons toutefois douter de la pertinence de notre choix de laisser la responsabilité de la présentation (le choix des couleurs) dans la classe qui appartient plus au modèle qu'à la vue.
Tous les codes
Code c# (Program.cs) (19 lignes)
using System; using System.Collections.Generic; using System.Windows.Forms; namespace ClassExplorer { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); } } }
Code c# (Form1.cs) (178 lignes)
using System; using System.Collections; using System.Text; using System.Reflection; using System.IO; using System.Windows.Forms; using System.Drawing; namespace ClassExplorer { class ClassInfo { public static TreeNode[] getInfos(String classPath) { try { Assembly assembly = Assembly.LoadFrom(classPath); Type[] types = assembly.GetTypes(); foreach (Type type in types) { if (type.IsClass) classesTreeNode.Nodes.Add(getClassNode(type)); else if (type.IsEnum) enumsTreeNode.Nodes.Add(type.Name); else if (type.IsInterface) interfacesTreeNode.Nodes.Add(type.Name); } } catch (Exception e) { } TreeNode[] infos = { classesTreeNode, enumsTreeNode, interfacesTreeNode }; return infos; } public static String getFileInfos(String classPath) { str.Append("\n\nInfos :"); str.Append("\nCreation time : "); str.Append(f.CreationTime); str.Append("\nLast access : "); str.Append(f.LastAccessTime); str.Append("\nAttributes : "); str.Append(f.Attributes); str.Append("\nFullName : "); str.Append(f.FullName); return str.ToString(); } public static String getFileName(String classPath) { return f.Name; } private static TreeNode getClassNode(Type type) { MethodInfo[] methodsInfos = type.GetMethods( BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly ); if (methodsInfos.Length > 0) { methodsNode.ForeColor = System.Drawing.Color.Blue; foreach (MethodInfo methodInfo in methodsInfos) { methodsNode.Nodes.Add(getMethodNode(methodInfo)); } classNode.Nodes.Add(methodsNode); } else classNode.Nodes.Add("No methods available"); ConstructorInfo[] constructorsInfos = type.GetConstructors( BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly ); if (constructorsInfos.Length > 0) { constructorsNode.ForeColor = System.Drawing.Color.Green; foreach (ConstructorInfo constructorInfo in constructorsInfos) { constructorsNode.Nodes.Add(getConstructorNode(constructorInfo)); } classNode.Nodes.Add(constructorsNode); } else classNode.Nodes.Add("No constructors available"); FieldInfo[] fieldsInfos = type.GetFields( BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly ); if (fieldsInfos.Length > 0) { fieldsNode.ForeColor = System.Drawing.Color.Navy; foreach (FieldInfo fieldInfo in fieldsInfos) { fieldsNode.Nodes.Add(getFieldNode(fieldInfo)); } classNode.Nodes.Add(fieldsNode); } else classNode.Nodes.Add("No fields available"); PropertyInfo[] propsInfos = type.GetProperties( BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly ); if (propsInfos.Length > 0) { foreach (PropertyInfo propInfo in propsInfos) { propsNode.Nodes.Add(propInfo.Name); } classNode.Nodes.Add(propsNode); } else classNode.Nodes.Add("No properties available"); return classNode; } private static TreeNode getConstructorNode(ConstructorInfo constructorInfo) { if (constructorInfo.IsPrivate) constrStr.Append("Private "); else if (constructorInfo.IsStatic) constrStr.Append("Static "); else if (constructorInfo.IsPublic) constrStr.Append("Public "); constrStr.Append(constructorInfo.Name); constructorNode.ForeColor = System.Drawing.Color.GreenYellow; ParameterInfo[] paramInfos = constructorInfo.GetParameters(); foreach (ParameterInfo paramInfo in paramInfos) { constructorNode.Nodes.Add( String.Format("{0} {1}", paramInfo.ParameterType.ToString(), paramInfo.Name) ); } return constructorNode; } private static TreeNode getMethodNode(MethodInfo methodInfo) { if (methodInfo.IsPrivate) methodStr.Append("Private "); else if (methodInfo.IsStatic) methodStr.Append("Static "); else if (methodInfo.IsPublic) methodStr.Append("Public "); methodStr.Append(methodInfo.Name); methodNode.ForeColor = System.Drawing.Color.Red; ParameterInfo[] paramInfos = methodInfo.GetParameters(); foreach (ParameterInfo paramInfo in paramInfos) { methodNode.Nodes.Add( String.Format("{0} {1}", paramInfo.ParameterType.ToString(), paramInfo.Name) ); } return methodNode; } private static TreeNode getFieldNode(FieldInfo fieldInfo) { if (fieldInfo.IsPrivate) fieldStr.Append("Private "); else if (fieldInfo.IsStatic) fieldStr.Append("Static "); else if (fieldInfo.IsPublic) fieldStr.Append("Public "); fieldStr.Append(fieldInfo.Name); fieldNode.ForeColor = System.Drawing.Color.DarkGreen; return fieldNode; } } }
Code c# (Form1.Designer.cs) (110 lignes)
using System.Windows.Forms; namespace ClassExplorer { partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.toolStrip1.SuspendLayout(); this.SuspendLayout(); // // toolStrip1 // this.fileToolStripButton}); this.toolStrip1.Name = "toolStrip1"; this.toolStrip1.TabIndex = 0; this.toolStrip1.Text = "toolStrip1"; // // fileToolStripButton // this.fileToolStripButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; this.fileToolStripMenuItem}); this.fileToolStripButton.Image = ((System.Drawing.Image)(resources.GetObject("fileToolStripButton.Image"))); this.fileToolStripButton.ImageTransparentColor = System.Drawing.Color.Magenta; this.fileToolStripButton.Name = "fileToolStripButton"; this.fileToolStripButton.Text = "File"; // // fileToolStripMenuItem // this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; this.fileToolStripMenuItem.Text = "Open..."; // // filePathLabel // this.filePathLabel.AutoSize = true; this.filePathLabel.Name = "filePathLabel"; this.filePathLabel.TabIndex = 1; this.filePathLabel.Visible = false; // // openFileDialog // this.openFileDialog.Filter = "Executable files (.exe)|*.exe|Dynamic librairies (.dll)|*.dll"; // // classInfoTreeView // this.classInfoTreeView.Name = "classInfoTreeView"; this.classInfoTreeView.TabIndex = 2; // // Form1 // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.classInfoTreeView); this.Controls.Add(this.filePathLabel); this.Controls.Add(this.toolStrip1); this.Name = "Form1"; this.Text = "My Class Explorer"; this.toolStrip1.ResumeLayout(false); this.toolStrip1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private ToolStrip toolStrip1; private ToolStripDropDownButton fileToolStripButton; private ToolStripMenuItem fileToolStripMenuItem; private Label filePathLabel; private OpenFileDialog openFileDialog; private TreeView classInfoTreeView; } }
Code c# (ClassInfo.cs) (178 lignes)
using System; using System.Collections; using System.Text; using System.Reflection; using System.IO; using System.Windows.Forms; using System.Drawing; namespace ClassExplorer { class ClassInfo { public static TreeNode[] getInfos(String classPath) { try { Assembly assembly = Assembly.LoadFrom(classPath); Type[] types = assembly.GetTypes(); foreach (Type type in types) { if (type.IsClass) classesTreeNode.Nodes.Add(getClassNode(type)); else if (type.IsEnum) enumsTreeNode.Nodes.Add(type.Name); else if (type.IsInterface) interfacesTreeNode.Nodes.Add(type.Name); } } catch (Exception e) { } TreeNode[] infos = { classesTreeNode, enumsTreeNode, interfacesTreeNode }; return infos; } public static String getFileInfos(String classPath) { str.Append("\n\nInfos :"); str.Append("\nCreation time : "); str.Append(f.CreationTime); str.Append("\nLast access : "); str.Append(f.LastAccessTime); str.Append("\nAttributes : "); str.Append(f.Attributes); str.Append("\nFullName : "); str.Append(f.FullName); return str.ToString(); } public static String getFileName(String classPath) { return f.Name; } private static TreeNode getClassNode(Type type) { MethodInfo[] methodsInfos = type.GetMethods( BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly ); if (methodsInfos.Length > 0) { methodsNode.ForeColor = System.Drawing.Color.Blue; foreach (MethodInfo methodInfo in methodsInfos) { methodsNode.Nodes.Add(getMethodNode(methodInfo)); } classNode.Nodes.Add(methodsNode); } else classNode.Nodes.Add("No methods available"); ConstructorInfo[] constructorsInfos = type.GetConstructors( BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly ); if (constructorsInfos.Length > 0) { constructorsNode.ForeColor = System.Drawing.Color.Green; foreach (ConstructorInfo constructorInfo in constructorsInfos) { constructorsNode.Nodes.Add(getConstructorNode(constructorInfo)); } classNode.Nodes.Add(constructorsNode); } else classNode.Nodes.Add("No constructors available"); FieldInfo[] fieldsInfos = type.GetFields( BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly ); if (fieldsInfos.Length > 0) { fieldsNode.ForeColor = System.Drawing.Color.Navy; foreach (FieldInfo fieldInfo in fieldsInfos) { fieldsNode.Nodes.Add(getFieldNode(fieldInfo)); } classNode.Nodes.Add(fieldsNode); } else classNode.Nodes.Add("No fields available"); PropertyInfo[] propsInfos = type.GetProperties( BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly ); if (propsInfos.Length > 0) { foreach (PropertyInfo propInfo in propsInfos) { propsNode.Nodes.Add(propInfo.Name); } classNode.Nodes.Add(propsNode); } else classNode.Nodes.Add("No properties available"); return classNode; } private static TreeNode getConstructorNode(ConstructorInfo constructorInfo) { if (constructorInfo.IsPrivate) constrStr.Append("Private "); else if (constructorInfo.IsStatic) constrStr.Append("Static "); else if (constructorInfo.IsPublic) constrStr.Append("Public "); constrStr.Append(constructorInfo.Name); constructorNode.ForeColor = System.Drawing.Color.GreenYellow; ParameterInfo[] paramInfos = constructorInfo.GetParameters(); foreach (ParameterInfo paramInfo in paramInfos) { constructorNode.Nodes.Add( String.Format("{0} {1}", paramInfo.ParameterType.ToString(), paramInfo.Name) ); } return constructorNode; } private static TreeNode getMethodNode(MethodInfo methodInfo) { if (methodInfo.IsPrivate) methodStr.Append("Private "); else if (methodInfo.IsStatic) methodStr.Append("Static "); else if (methodInfo.IsPublic) methodStr.Append("Public "); methodStr.Append(methodInfo.Name); methodNode.ForeColor = System.Drawing.Color.Red; ParameterInfo[] paramInfos = methodInfo.GetParameters(); foreach (ParameterInfo paramInfo in paramInfos) { methodNode.Nodes.Add( String.Format("{0} {1}", paramInfo.ParameterType.ToString(), paramInfo.Name) ); } return methodNode; } private static TreeNode getFieldNode(FieldInfo fieldInfo) { if (fieldInfo.IsPrivate) fieldStr.Append("Private "); else if (fieldInfo.IsStatic) fieldStr.Append("Static "); else if (fieldInfo.IsPublic) fieldStr.Append("Public "); fieldStr.Append(fieldInfo.Name); fieldNode.ForeColor = System.Drawing.Color.DarkGreen; return fieldNode; } } }
English translation
You have asked to visit this site in English. For now, only the interface is translated, but not all the content yet.If you want to help me in translations, your contribution is welcome. All you need to do is register on the site, and send me a message asking me to add you to the group of translators, which will give you the opportunity to translate the pages you want. A link at the bottom of each translated page indicates that you are the translator, and has a link to your profile.
Thank you in advance.
Document created the 02/10/2006, last modified the 07/04/2023
Source of the printed document:https://www.gaudry.be/en/csharp-gui-tree.html
The infobrol is a personal site whose content is my sole responsibility. The text is available under CreativeCommons license (BY-NC-SA). More info on the terms of use and the author.