Cet article se concentre sur la façon d’utiliser le contrôle TreeView. Le contrôle TreeView possède des fonctions riches et peut être utilisé dans de nombreuses situations. Résumé : Décrit comment ajouter une fonctionnalité de liaison de données au contrôle TreeView. Il s'agit de l'un des exemples de développement de contrôles Microsoft Windows. Vous pouvez lire cet article conjointement avec l’article de présentation associé.
Introduction
Dans la mesure du possible, vous devez commencer avec des contrôles disponibles dans le commerce ; car les contrôles Microsoft® Windows® Forms fournis incluent tellement de codage et de tests qu'il serait inutile de les abandonner et de repartir de zéro. Sur cette base, dans cet exemple, j'hériterai d'un contrôle Windows Forms existant, TreeView, puis je le personnaliserai. Lorsque vous téléchargez le code du contrôle TreeView , vous obtenez également des exemples de développement de contrôles supplémentaires, ainsi qu'un exemple d'application qui montre comment utiliser le TreeView amélioré avec d'autres contrôles liés aux données.
Conception d'une arborescence de liaison de données
Pour les développeurs Windows, l'ajout d'une liaison de données au contrôle TreeView est un problème courant, mais comme il existe une différence majeure entre TreeView et d'autres contrôles (tels que ListBox ou DataGrid ) (c'est-à-dire que TreeView affiche des données hiérarchiques), le contrôle de base. pas encore pris en charge (c'est-à-dire que nous devons encore l'utiliser). Étant donné une table de données, il est clair comment afficher ces informations dans un ListBox ou un DataGrid , mais utiliser la nature en couches d' un TreeView pour afficher les mêmes données n'est pas si simple. Personnellement, j'ai appliqué de nombreuses méthodes différentes lors de l'affichage des données à l'aide de TreeView , mais il existe une méthode qui est la plus couramment utilisée : regrouper les données dans le tableau selon certains champs, comme le montre la figure 1.
Figure 1 : Affichage des données dans TreeView
Dans cet exemple, je vais créer un contrôle TreeView dans lequel je peux transmettre un ensemble de données plat (illustré dans la figure 2) et produire facilement les résultats présentés dans la figure 1.
Figure 2 : Ensemble de résultats plats contenant toutes les informations nécessaires pour créer l'arborescence illustrée à la figure 1
Avant de commencer à coder, j'ai proposé une conception pour le nouveau contrôle qui gérerait cet ensemble de données particulier et, j'espère, qu'il fonctionnerait dans de nombreuses autres situations similaires. Ajoutez une collection de groupes suffisamment grande pour créer une hiérarchie utilisant la plupart des données plates, dans laquelle vous spécifiez un champ de regroupement, un champ d'affichage et un champ de valeur pour chaque niveau de hiérarchie (un ou tous les champs doivent être identiques). Afin de transformer les données affichées dans la figure 2 en TreeView illustré dans la figure 1, mon nouveau contrôle vous oblige à définir deux niveaux de regroupement, Publisher et Title, et à définir pub_id comme champ de regroupement du groupe Publisher et title_id comme champ de regroupement. du groupe Titre. Outre les champs de regroupement, vous devez également spécifier des champs d'affichage et de valeur pour chaque groupe afin de déterminer le texte qui s'affiche sur le nœud de groupe correspondant et la valeur qui identifie de manière unique le groupe spécifique. Lorsque vous rencontrez ce type de données, utilisez pub_name/pub_id et title/title_id comme champs d'affichage/valeur pour ces deux groupes. Les informations sur l'auteur deviennent les nœuds feuilles de l'arborescence (les nœuds à la fin de la hiérarchie de regroupement), et vous devez également spécifier les champs ID ( au_id ) et afficher ( au_lname ) pour ces nœuds.
Lors de la création d’un contrôle personnalisé, déterminer comment le programmeur utilisera le contrôle avant de commencer le codage contribuera à rendre le contrôle plus efficace. Dans ce cas, j'aimerais que le programmeur (étant donné les données affichées précédemment et le résultat souhaité) puisse réaliser le regroupement avec quelques lignes de code comme ceci :
| Avec DbTreeControl .ValueMember = au_id .DisplayMember = au_lname .DataSource = myDataTable.DefaultView .AddGroup (Éditeur, pub_id, pub_name, pub_id) .AddGroup (Titre, titre_id, titre, titre_id) Terminer par |
Remarque : ce n'est pas la dernière ligne de code que j'ai écrite, mais elle est similaire. Lors du développement du contrôle, j'ai réalisé que je devais associer l'index d'image dans l'ImageList associé au TreeView à chaque niveau de regroupement, j'ai donc dû ajouter un paramètre supplémentaire à la méthode AddGroup .
Pour réellement construire l'arborescence, je vais parcourir les données et rechercher les modifications apportées aux champs (spécifiés comme valeurs de regroupement pour chaque regroupement) tout en créant de nouveaux nœuds de regroupement si nécessaire et un nœud feuille pour chaque élément de données. En raison du regroupement de nœuds, le nombre total de nœuds sera supérieur au nombre d'éléments dans la source de données, mais il y aura exactement un nœud feuille pour chaque élément dans les données sous-jacentes.
Figure 3 : nœuds de groupe et nœuds feuilles
La distinction entre les nœuds feuilles et les nœuds de groupe (illustré dans la figure 3) sera importante pour le reste de cet article. J'ai décidé de traiter ces deux types de nœuds différemment, de créer des nœuds personnalisés pour chaque type de nœud et de déclencher différents événements en fonction du type de nœud sélectionné.
Implémenter la liaison de données
La première étape de l’écriture du code pour ce contrôle consiste à créer le projet et la classe de départ correspondante. Dans cet exemple, je crée d'abord une nouvelle bibliothèque de contrôles Windows, puis je supprime la classe UserControl par défaut et je la remplace par une nouvelle classe qui hérite du contrôle TreeView :
Classe publique dbTreeControl
Hérite de System.Windows.Forms.TreeView
À partir de ce moment, je vais concevoir un contrôle qui peut être placé sur un formulaire et avoir l'apparence et les fonctionnalités d'un TreeView classique. L'étape suivante consiste à commencer à ajouter le code requis pour gérer la nouvelle fonctionnalité ajoutée au TreeView , à savoir la liaison et le regroupement des données.
Ajouter une propriété DataSource
Toutes les fonctionnalités de mon nouveau contrôle sont importantes, mais deux problèmes clés dans la création de contrôles complexes liés aux données sont la gestion des propriétés DataSource et la récupération d'éléments individuels de chaque objet de la source de données.
Créer une routine d'attribut
Tout d’abord, tout contrôle utilisé pour implémenter une liaison de données complexe doit implémenter une routine de propriété DataSource et conserver les variables membres appropriées :
| m_DataSource privé en tant qu'objet _ Propriété publique DataSource() en tant qu'objet Obtenir Retourner m_DataSource Fin Obtenir Définir (valeur ByVal en tant qu'objet) Si la valeur n'est rien, alors cm = Rien GroupageChanged() Autre Sinon (la valeur TypeOf est IList ou _ La valeur TypeOf est IListSource) Alors 'n'est pas une source de données valide à cet effet Lancer un nouveau System.Exception (source de données invalide) Autre Si la valeur TypeOf est IListSource alors Atténuer myListSource en tant que IListSource maListeSource = CType (Valeur, IListeSource) Si myListSource.ContainsListCollection = True Alors Lancer un nouveau System.Exception (source de données invalide) Autre 'Oui, oui. c'est une source de données valide m_DataSource = Valeur cm = CType(Me.BindingContext(Valeur), _ Gestionnaire de devises) GroupageChanged() Fin si Autre m_DataSource = Valeur cm = CType(Me.BindingContext(Valeur), _ Gestionnaire de devises) GroupageChanged() Fin si Fin si Fin si Ensemble de fin Propriété de fin |
Les objets pouvant être utilisés comme sources de données pour des liaisons de données complexes sont généralement pris en charge. Cette interface expose les données sous la forme d'une collection d'objets et fournit plusieurs propriétés utiles, telles que Count . Mon nouveau contrôle TreeView nécessite un objet IList dans sa liaison, mais l'utilisation d'une autre interface fonctionne bien car elle fournit un moyen pratique d'obtenir un objet IList ( GetList ). Lors de la définition de la propriété DataSource , je détermine d'abord si un objet valide est fourni, c'est-à-dire un objet qui prend en charge IList ou IListSource . Ce que je veux vraiment, c'est un IList , donc si l'objet ne prend en charge que IListSource (par exemple DataTable ), alors j'utiliserai la méthode GetList() de cette interface pour obtenir le bon objet.
Certains objets qui implémentent IListSource (tels que DataSet ) contiennent en réalité plusieurs listes représentées par la propriété ContainsListCollection . Si cette propriété est True , GetList renverra un objet IList représentant une liste (contenant plusieurs listes). Dans mon exemple, j'ai décidé de prendre en charge les connexions directes aux objets IList ou IListSource qui ne contiennent qu'un seul objet IList et d'ignorer les objets qui nécessitent un travail supplémentaire pour spécifier une source de données, telle qu'un DataSet .
Remarque : Si vous souhaitez prendre en charge de tels objets ( DataSet ou similaire), vous pouvez ajouter une propriété supplémentaire (telle que DataMember ) pour spécifier une sous-liste spécifique pour la liaison.
Si la source de données fournie est valide, le résultat final est une instance créée ( cm = Me.BindingContext(Value) ). Étant donné que cette instance sera utilisée pour accéder à la source de données sous-jacente, aux propriétés de l'objet et aux informations d'emplacement, elle est stockée dans des variables locales.
Ajouter des propriétés de membre d'affichage et de valeur
Avoir une DataSource est la première étape dans la mise en œuvre d’une liaison de données complexe, mais le contrôle doit savoir quels champs ou propriétés spécifiques des données seront utilisés comme membres d’affichage et de valeur. Le membre Display sera utilisé comme titre du nœud d’arborescence, tandis que le membre Value est accessible via la propriété Value du nœud. Ces propriétés sont toutes des chaînes représentant des noms de champs ou de propriétés et peuvent être facilement ajoutées au contrôle :
| m_ValueMember privé en tant que chaîne m_DisplayMember privé sous forme de chaîne _ Propriété publique ValueMember() sous forme de chaîne Obtenir Retourner m_ValueMember Fin Obtenir Définir (valeur ByVal sous forme de chaîne) m_ValueMember = Valeur Ensemble de fin Propriété de fin _ Propriété publique DisplayMember() sous forme de chaîne Obtenir Retourner m_DisplayMember Fin Obtenir Définir (valeur ByVal sous forme de chaîne) m_DisplayMember = Valeur Ensemble de fin Propriété de fin |
Dans ce TreeView , ces propriétés représenteront uniquement les membres Display et Value des nœuds feuilles, et les informations correspondantes pour chaque niveau de regroupement seront spécifiées dans la méthode AddGroup .
Utilisation de l'objet CurrencyManager
Dans la propriété DataSource évoquée précédemment, une instance de la classe CurrencyManager est créée et stockée dans une variable de niveau classe. La classe CurrencyManager accessible via cet objet est un élément clé de l'implémentation de la liaison de données car elle possède des propriétés, des méthodes et des événements qui activent les fonctions suivantes :
Récupérer la valeur de l'attribut/du champ
L'objet CurrencyManager vous permet de récupérer des valeurs de propriété ou de champ, telles que la valeur d' un champ DisplayMember ou ValueMember , à partir d'un élément individuel dans une source de données via sa méthode GetItemProperties . Utilisez ensuite un objet PropertyDescriptor pour obtenir la valeur d'un champ ou d'une propriété spécifique sur un élément de liste spécifique. L'extrait de code suivant montre comment créer ces objets PropertyDescriptor et comment utiliser la fonction GetValue pour obtenir la valeur de propriété d'un élément dans la source de données sous-jacente. Notez la propriété List de l'objet CurrencyManager : elle donne accès à l'instance IList à laquelle le contrôle est lié :
| Atténuer myNewLeafNode en tant que TreeLeafNode Dim currObject en tant qu'objet currObject = cm.List (currentListIndex) Si Me.DisplayMember <> AndAlso Me.ValueMember <> Alors 'Ajouter un nœud feuille ? Dim pdValue As System.ComponentModel.PropertyDescriptor Dim pdDisplay en tant que System.ComponentModel.PropertyDescriptor pdValue = cm.GetItemProperties()(Me.ValueMember) pdDisplay = cm.GetItemProperties()(Me.DisplayMember) monNouveauNoeudFeuille = _ Nouveau TreeLeafNode(CStr(pdDisplay.GetValue(currObject)), _ objetcurr, _ pdValue.GetValue(currObject), _ indexListeActuel) |
GetValue ignore le type de données sous-jacent de la propriété lors du renvoi d'un objet, la valeur de retour doit donc être convertie avant de l'utiliser.
Synchronisez les contrôles liés aux données
Le CurrencyManager possède une autre fonctionnalité majeure : en plus de fournir un accès aux sources de données liées et aux propriétés des éléments, il permet d'utiliser le même DataSource pour coordonner la liaison de données entre ce contrôle et tout autre contrôle. Cette prise en charge peut être utilisée pour garantir que plusieurs contrôles liés simultanément à la même source de données restent sur le même élément de la source de données. Pour mon contrôle, je veux m'assurer que lorsqu'un élément est sélectionné dans l'arborescence, tous les autres contrôles liés à la même source de données pointent vers le même élément (le même enregistrement, la même ligne ou même le même tableau, si vous le souhaitez). penser en termes de base de données). Pour ce faire, je remplace la méthode OnAfterSelect dans le TreeView de base. Dans cette méthode (qui est appelée après la sélection du nœud de l'arborescence), je définis la propriété Position de l'objet CurrencyManager sur l'index de l'élément actuellement sélectionné. L'exemple d'application fourni avec le contrôle TreeView illustre comment les contrôles de synchronisation facilitent la création d'interfaces utilisateur liées aux données. Pour faciliter la détermination de la position dans la liste de l'élément actuellement sélectionné, j'ai utilisé une classe TreeNode personnalisée ( TreeLeafNode ou TreeGroupNode ) et stocké l'index de liste de chaque nœud dans la propriété Position que j'ai créée :
| Remplacements protégés Sub OnAfterSelect _ (ByVal et As System.Windows.Forms.TreeViewEventArgs) Dim tln comme TreeLeafNode Si TypeOf e.Node est TreeGroupNode alors tln = FindFirstLeafNode (e.Node) Dim groupArgs comme nouveau groupTreeViewEventArgs(e) RaiseEvent AfterGroupSelect (groupArgs) ElseIf TypeOf e.Node est TreeLeafNode alors Dim leafArgs comme nouveau leafTreeViewEventArgs(e) RaiseEvent AfterLeafSelect (leafArgs) tln = CType (e.Node, TreeLeafNode) Fin si Si ce n'est pas le cas, ce n'est rien, alors Si cm.Position <> tln.Position Alors cm.Position = tln.Position Fin si Fin si MaBase.OnAfterSelect(e) Fin du sous-marin |
Dans l'extrait de code précédent, vous avez peut-être remarqué une fonction appelée FindFirstLeafNode , que je souhaite présenter brièvement ici. Dans mon TreeView , seuls les nœuds feuilles (les nœuds finaux de la hiérarchie) correspondent aux éléments du DataSource , tous les autres nœuds ne sont utilisés que pour créer la structure de regroupement. Si je veux créer un contrôle lié aux données performant, je dois toujours sélectionner un élément correspondant au DataSource , donc chaque fois que je sélectionne un nœud de groupe, je trouve le premier nœud feuille sous le groupe, comme si ce nœud était le sélection actuelle. Vous pouvez consulter l’exemple en action, mais pour l’instant, n’hésitez pas à l’utiliser.
| Fonction privée FindFirstLeafNode (ByVal currNode As TreeNode) _ En tant que nœud TreeLeaf Si TypeOf currNode est TreeLeafNode alors Renvoie CType (currNode, TreeLeafNode) Autre Si currNode.Nodes.Count > 0 Alors Renvoie FindFirstLeafNode(currNode.Nodes(0)) Autre Ne rien renvoyer Fin si Fin si Fonction de fin |
La définition de la propriété Position de l'objet CurrencyManager synchronise les autres contrôles avec la sélection actuelle, mais lorsque la position des autres contrôles change, le CurrencyManager génère également des événements afin que la sélection change en conséquence. Pour être un bon composant lié aux données, la sélection doit se déplacer à mesure que l'emplacement de la source de données change, et l'affichage doit être mis à jour lorsque les données d'un élément sont modifiées. Il existe trois événements déclenchés par CurrencyManager : CurrentChanged , ItemChanged et PositionChanged . Le dernier événement est assez simple ; l'un des objectifs de CurrencyManager est de maintenir un indicateur de position actuelle pour la source de données afin que plusieurs contrôles liés puissent tous afficher le même enregistrement ou élément de liste, et cet événement est déclenché chaque fois que la position change. Les deux autres événements se chevauchent parfois et la distinction est moins nette. Ce qui suit décrit comment utiliser ces événements dans des contrôles personnalisés : PositionChanged est un événement relativement simple et ne sera pas décrit ici ; lorsque vous souhaitez ajuster l'élément actuellement sélectionné dans un contrôle complexe lié aux données (tel que Tree), veuillez utiliser The ; événement. L'événement ItemChanged est déclenché chaque fois qu'un élément de la source de données est modifié, tandis que CurrentChanged est déclenché uniquement lorsque l'élément actuel est modifié.
Dans mon TreeView , j'ai constaté que chaque fois que je sélectionnais un nouvel élément, les trois événements étaient déclenchés, j'ai donc décidé de gérer l'événement PositionChanged en modifiant l'élément actuellement sélectionné et de ne rien faire avec les deux autres. Il est recommandé de convertir la source de données en IBindingList (si la source de données prend en charge IBindingList ) et d'utiliser l'événement ListChanged à la place, mais je n'ai pas implémenté cette fonctionnalité.
| Private Sub cm_PositionChanged (ByVal expéditeur en tant qu'objet, _ ByVal et As System.EventArgs) gère cm.PositionChanged Dim tln comme TreeLeafNode Si TypeOf Me.SelectedNode est TreeLeafNode alors tln = CType (Me.SelectedNode, TreeLeafNode) Autre tln = FindFirstLeafNode (Me.SelectedNode) Fin si Si tln.Position <> cm.Position Alors Me.SelectedNode = FindNodeByPosition (cm.Position) Fin si Fin du sous-marin Fonction de surcharge privée FindNodeByPosition (index ByVal en tant qu'entier) _ En tant que TreeNode Renvoie FindNodeByPosition (index, Me.Nodes) Fonction de fin Fonction de surcharge privée FindNodeByPosition (index ByVal As Integer, _ ByVal NodesToSearch As TreeNodeCollection) As TreeNode Dim i comme entier = 0 Dim currNode comme TreeNode Dim tln comme TreeLeafNode Faire pendant que je < NodesToSearch.Count currNode = NoeudsVersRecherche(i) je += 1 Si TypeOf currNode est TreeLeafNode alors tln = CType(currNode, TreeLeafNode) Si tln.Position = index Alors Retourner le nœud courant Fin si Autre currNode = FindNodeByPosition (index, currNode.Nodes) Si ce n'est pas le cas, currNode n'est rien alors Retourner le nœud courant Fin si Fin si Boucle Ne rien renvoyer Fonction de fin |
Convertir DataSource en arbre
Après avoir écrit le code de liaison de données, je peux ajouter le code pour gérer les niveaux de regroupement, créer l'arborescence en conséquence, puis ajouter des événements, des méthodes et des propriétés personnalisés.
Groupe de gestion
Pour configurer une collection de groupes, le programmeur doit créer les fonctions AddGroup , RemoveGroup et ClearGroups . Chaque fois que la collection de groupes est modifiée, l'arborescence doit être redessinée (pour refléter la nouvelle configuration), j'ai donc créé une procédure générique, GroupingChanged , qui peut être appelée par divers codes dans le contrôle lorsque les circonstances changent et que l'arborescence doit être forcée à être reconstruit :
| TreeGroups privés en tant que nouveau ArrayList() Public Sub RemoveGroup (groupe ByVal en tant que groupe) Si ce n'est pas le cas treeGroups.Contains(group) Alors treeGroups.Remove(groupe) GroupageChanged() Fin si Fin du sous-marin Surcharges publiques Sub AddGroup (groupe ByVal en tant que groupe) Essayer treeGroups.Add(groupe) GroupageChanged() Attraper Fin Essayer Fin du sous-marin Surcharges publiques Sub AddGroup (nom ByVal As String, _ ByVal groupBy As String, _ ByVal displayMember As String, _ ByVal valueMember As String, _ ByVal imageIndex sous forme d'entier, _ ByVal selectedImageIndex As Integer) Dim myNewGroup As New Group (nom, groupBy, _ displayMember, valeurMember, _ imageIndex, sélectionnéImageIndex) Moi.AddGroup (monNouveauGroupe) Fin du sous-marin Fonction publique GetGroups() As Group() Retourner CType(treeGroups.ToArray(GetType(Group)), Group()) Fonction de fin |
arbre couvrant
La reconstruction proprement dite de l'arborescence est effectuée par une paire de processus : BuildTree et AddNodes . Le code de ces deux processus étant trop long, cet article ne les liste pas tous, mais tente de résumer leur comportement (vous pouvez bien entendu télécharger le code complet si vous le souhaitez). Comme mentionné précédemment, les programmeurs peuvent interagir avec ce contrôle en configurant une série de groupes, puis en utilisant ces groupes dans BuildTree pour déterminer comment configurer les nœuds de l'arborescence. BuildTree efface la collection de nœuds actuelle, puis parcourt l'intégralité de la source de données pour traiter le regroupement de premier niveau (éditeur mentionné dans l'exemple et le diagramme plus haut dans cet article), en ajoutant un nœud pour chaque valeur de regroupement différente (en utilisant les données de l'exemple, pour chaque Ajoutez un nœud avec une valeur pub_id ), puis appelez AddNodes pour remplir tous les nœuds du regroupement de premier niveau. AddNodes s'appelle de manière récursive pour gérer autant de niveaux que nécessaire, en ajoutant des nœuds de groupe et des nœuds feuilles si nécessaire. Utilisez deux classes personnalisées basées sur TreeNode pour distinguer les nœuds de groupe et les nœuds feuilles, et fournissez les attributs correspondants pour les deux types de nœuds.
Événements TreeView personnalisés
Chaque fois qu'un nœud est sélectionné, TreeView déclenche deux événements : BeforeSelect et AfterSelect . Mais sous mon contrôle, je voulais rendre les événements des nœuds de groupe et des nœuds feuilles différents, j'ai donc ajouté mes propres événements BeforeGroupSelect/AfterGroupSelect et BeforeLeafSelect/AfterLeafSelect . En plus des événements de base, j'ai également déclenché une classe de paramètres d'événement personnalisée :
| Événement public BeforeGroupSelect _ (expéditeur ByVal en tant qu'objet, ByVal et en tant que groupTreeViewCancelEventArgs) Événement public AfterGroupSelect _ (expéditeur ByVal en tant qu'objet, ByVal et en tant que groupTreeViewEventArgs) Événement publicBeforeLeafSelect _ (expéditeur ByVal en tant qu'objet, ByVal et As leafTreeViewCancelEventArgs) Événement public AfterLeafSelect _ (expéditeur ByVal en tant qu'objet, ByVal et en tant que leafTreeViewEventArgs) Remplacements protégés Sub OnBeforeSelect _ (ByVal et As System.Windows.Forms.TreeViewCancelEventArgs) Si TypeOf e.Node est TreeGroupNode alors Dim groupArgs comme nouveau groupTreeViewCancelEventArgs(e) RaiseEvent BeforeGroupSelect (CObj (Moi), groupArgs) ElseIf TypeOf e.Node est TreeLeafNode alors Dim leafArgs comme nouveau leafTreeViewCancelEventArgs(e) RaiseEvent BeforeLeafSelect(CObj(Me), leafArgs) Fin si MaBase.OnBeforeSelect(e) Fin du sous-marin Remplacements protégés Sub OnAfterSelect _ (ByVal et As System.Windows.Forms.TreeViewEventArgs) Dim tln comme TreeLeafNode Si TypeOf e.Node est TreeGroupNode alors tln = FindFirstLeafNode (e.Node) Dim groupArgs comme nouveau groupTreeViewEventArgs(e) RaiseEvent AfterGroupSelect (CObj (Moi), groupArgs) ElseIf TypeOf e.Node est TreeLeafNode alors Dim leafArgs comme nouveau leafTreeViewEventArgs(e) RaiseEvent AfterLeafSelect (CObj (Moi), leafArgs) tln = CType (e.Node, TreeLeafNode) Fin si Si ce n'est pas le cas, ce n'est rien, alors Si cm.Position <> tln.Position Alors cm.Position = tln.Position Fin si Fin si MaBase.OnAfterSelect(e) Fin du sous-marin |
Les classes de nœuds personnalisées ( TreeLeafNode et TreeGroupNode ) et les classes de paramètres d'événement personnalisés sont incluses dans le code téléchargeable.
Exemple d'application
Pour bien comprendre tout le code de cet exemple de contrôle, vous devez comprendre comment il fonctionne dans votre application. L'exemple d'application inclus utilise la base de données pubs.mdb Access et illustre comment le contrôle Tree peut être utilisé avec d'autres contrôles liés aux données pour créer des applications Windows. Les fonctionnalités clés à noter dans ce cas incluent la synchronisation de l'arborescence avec d'autres contrôles liés et la sélection automatique des nœuds de l'arborescence lors de l'exécution d'une recherche sur la source de données.
Remarque : Cet exemple d'application (nommé TheSample) est inclus dans le téléchargement de cet article.
Figure 4 : Application de démonstration pour TreeView lié aux données
résumé
Le contrôle Tree lié aux données décrit dans cet article ne convient pas à tous les projets qui nécessitent un contrôle Tree pour afficher les informations de base de données, mais il introduit une méthode pour personnaliser le contrôle à des fins personnelles. N’oubliez pas que tout contrôle complexe lié aux données que vous souhaitez créer aura en grande partie le même code que le contrôle Tree et que vous pouvez simplifier le développement futur du contrôle en modifiant le code existant.