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; } } }
Nederlandse vertaling
U hebt gevraagd om deze site in het Nederlands te bezoeken. Voor nu wordt alleen de interface vertaald, maar nog niet alle inhoud.Als je me wilt helpen met vertalingen, is je bijdrage welkom. Het enige dat u hoeft te doen, is u op de site registreren en mij een bericht sturen waarin u wordt gevraagd om u toe te voegen aan de groep vertalers, zodat u de gewenste pagina's kunt vertalen. Een link onderaan elke vertaalde pagina geeft aan dat u de vertaler bent en heeft een link naar uw profiel.
Bij voorbaat dank.
Document heeft de 02/10/2006 gemaakt, de laatste keer de 07/04/2023 gewijzigd
Bron van het afgedrukte document:https://www.gaudry.be/nl/csharp-gui-tree.html
De infobrol is een persoonlijke site waarvan de inhoud uitsluitend mijn verantwoordelijkheid is. De tekst is beschikbaar onder CreativeCommons-licentie (BY-NC-SA). Meer info op de gebruiksvoorwaarden en de auteur.