Documentation des outils de DeveloppezDate de publication : 12/09/2006
Par
Florent GABRIEL (homepage)
Une initiation à l'utilisation des DataBinding sur des objets ADO.NET en Visual Basic .NET .
Introduction II. Comment lier un contrôle à une source ? II-A. Instancier un objet Binding II-B. Le lier au contrôle graphique II-C. Et lier et remplir un contrôle graphique liste III. DataBinding et relation III-A. DataRelation III-B. Lier la table parente III-C. Et lier la table enfant III-D. Et enfant vers parent ? IV. BindingManager IV-A. Assure la cohésion des Bindings IV-B. Accéder au BindingManager IV-C. Utiliser le BindingManager IV-C-1. Gérer la position en cours : IV-C-2. Obtenir l'élément en cours : IV-C-3. Valider et annuler les modifications de la ligne en cours IV-C-4. Intercepter un changement de position IV-C-5. CurrencyManager et PropertyManager V. Parse et Format (modifier à la volée) Introduction
Le FrameWork .NET intègre une fonctionnalité destiné à simplifié la vie des humbles programmeurs que nous sommes : le DataBinding. Le DataBinding ("liaison de données") est l'art de lier avec une simplicité déconcertante des source de données tel que des DataTable, des ArrayList ou encore des "Property" d'un objet. Tout l'intérêt (peut-être devrais-je dire "toute la magie") de ces liaisons est qu'elles fonctionnent alors de façon synchronisée: si la source de donnée liée est modifiée, la modification se répercute dans le contrôle, et réciproquement, une modification dans le contrôle entraîne automatiquement une modification dans la source liée. Encore mieux, dans le cas d'une DataTable, lier un contrôle-liste (un ListBox par exemple) va nous permettre de sélectionner la ligne que nous choisissons d'éditer. Le tout en quelques lignes de codes. Ce document est initiation au DataBinding, je me contenterai ici d'exposer les liaisons qui utilisent des sources de données liste. Mais il est bon de savoir que les sources de données peuvent aussi être des "property" d'objet: il est alors possible de lier la "property" Checked (de type booléenne) d'un CheckBox à la "property" Visible d'une fenêtre Form: cocher le CheckBox fera dès lors apparaître la fenêtre, et la décocher la rendra invisible (ceci toujours en une ligne de code). Le langage que j'utilise ici est le Visual Basic, mais ce n'est que pour illustration ... le passage vers un autre langage ne doit pas être bien sorcier. II. Comment lier un contrôle à une source ?II-A. Instancier un objet Binding
La classe Binding permet de faire le lien entre des propriétés d'un contrôle et des membres de sources de données. Il prends trois arguments :
II-B. Le lier au contrôle graphique
Un contrôle graphique peut être lié à plusieurs binding; il gère en faite une collection de Bindings (ControlBindingsCollection) accessible par sa méthode DataBindings. Il est dès lors possible de lier les différentes propriétés d'un contrôle, stockés dans cette collection.
Ainsi, si nous avons un DataTable "maTable", dont nous voulons lier la colonne "maColonne", à un TextBox "monTextBox" :
Il est aussi possible de le coder en une ligne :
II-C. Et lier et remplir un contrôle graphique liste
Dans le cas d'un DataTable, on peut lier un contrôle liste (ListBox, ComboBox ...) à une colonne de cette DataTable. Dès lors, il listera non seulement les champs de la colonne spécifié, mais aussi, comme les liaisons d'une même source (comme nous le verrons dans le chapitre suivant) sont interdépendant, la sélection d'une position dans cette liste conditionnera la position de la ligne en cours d'édition; ligne à laquelle sont peut-être lié à d'autres contrôles de la même source.
Lier un contrôle de liste est différent d'un Binding avec un contrôle simple car il ne s'agit pas simplement d'une propriété d'un contrôle, mais d'ajouter des éléments à une liste. Pour cela, nous devons utiliser deux "Property" du contrôle en question
Ainsi, pour continuer notre exemple, nous souhaitons lier la colonne "maColonneID" à notre contrôle-liste monControleListe :
III. DataBinding et relation
Nous allons voir ici comment "binder" les tables liées par des relations. Les contrôles doivent être liés à une même source de donnée pour assurer une cohésion entre ceux-çi : c'est le DataSet qui permet de contenir plusieurs tables, mais aussi des relations entre ces tables. III-A. DataRelation
Nous allons d'abord créer une relation.
Soit deux tables tableParent et tableEnfant définit ainsi :
La table TABLE_PARENT à la structure : ID représentant l'identifiant (la clef primaire) NOM le nom d'une personne PRENOM et son prénom
Et la table TABLE_ENFANT : ID_PARENT la clef étrangére de la table parent ADRESSE l'adresse NUM_TEL un numéro de téléphone éventuel pour cette adresse
Nous plaçons donc nos tables dans un DataSet :
Nous allons ensuite y ajouter une relation liant nos deux tables. Pour instancier une relation, une syntaxe possible est :
III-B. Lier la table parente
On définit les Bindings concernant les champs de la table "TABLE_PARENT".
Nous devrons utiliser la même source pour la table enfant que pour notre table parent : le DataSet. On peut voir que pour accéder à une colonne d'une table, la syntaxe est la même que pour accéder à une objet d'un objet : la hiérachie se fait par le point :
III-C. Et lier la table enfant
Et enfin, pour afficher la liste des adresses pour la colonne parente en cours,
il faut simplement utiliser la syntaxe "ColonneParent.NomRelation.NomColonneEnfant", ou même "NomRelation.NomColonneEnfant" :
III-D. Et enfant vers parent ?
Maintenant, nous voudrions avoir la liste de toutes les adresses; propriétaires confondus, et le nom du propriétaire pour l'adresse à la position en cours.
Jusqu'à maintenant (version 2 incluse de MSDN), il n'est pas proposé de solution du type : new Binding ( ''Text'' , monDataSource , ''Parent(NomRelation).NomColonneParent'') Microsoft proposes d'étendre la classe TypeDescriptor et d'y faire des surcharges. Méthode certainement extrêmement propre, mais compliqué et longue à mettre en place. Une solution certes moins élégante, mais plus simple est d'ajouter des colonnes calculées à la DataTable enfant :
Une colonne calculée est très intéressante du fait que le résultat se rafraîchit dés qu'une modification est effectuée dans les sources des données utilisées pour le calcul. Mais, le système ne sait pas inverser un calcul, la colonne calculée est Read-Only. Il est par contre possible de modifier les données qui veulent modifier cette colonne calculée (voir ) IV. BindingManagerIV-A. Assure la cohésion des Bindings
Le BindingManager gère la cohésion entre bindings d'une même source. Comme nous l'avons vu précédemment, en liant des contrôles (dont un contrôle de liste) sur une même source de donnée, nous pouvons naviguer dans cette source de données: sélectionner un élément dans le contrôle liste placera les autres contrôles dépendant de cette même source sur cette ligne sélectionné. Et c'est le BindingManager qui gére entre autre la modification de cet index. ![]()
IV-B. Accéder au BindingManager
La méthode BindingContext de la classe Form retourne la collection de tous les BindingManager de cette fenêtre. Pour accéder au BindingManager lié à une source, on utilise la même méthode que pour n'importe quelle autre collection :
Dans l'exemple qui suit :
Et dans le cas du BindingManager lié à une table d'un DataSet :
IV-C. Utiliser le BindingManager
Voici quelques méthodes de la classe BindingManagerBase. IV-C-1. Gérer la position en cours :
Position est une `Property` qui permet d'obtenir ou de spécifier la ligne en cours :
IV-C-2. Obtenir l'élément en cours :
Current renvoie une image de l'élément en cours. Dans le cas d'un DataTable, cette méthode retourne un DataRowView, pour laquelle on peut obtenir la DataRow correspondante par la méthode row. IV-C-3. Valider et annuler les modifications de la ligne en cours
Une ligne d'une DataView bindé n'est pas directement validée après la modification, via des contrôle qui lui sont lié, de ses champs. C'est ce qui est intèressant dans l'utilisation de DataBinding sur un DataView plutôt que sur un DataTable. On peut ainsi annuler les modification avant qu'il ne soit vraiment validé, ou alors forcer la validation :
IV-C-4. Intercepter un changement de position
Un événement PositionChanged est généré dans un BindingManager après qu'un changement de position se soit produit dans celui-çi. On peut intercepter cet événement et le traiter dans une fonction :
Voici deux façons de faire :
IV-C-5. CurrencyManager et PropertyManager
En réalité, la classe BindingManagerBase est virtuelle, elle ne peut pas être instanciée. Elle implémente les méthodes de base et sera étendu par d'autre classes. Ainsi, deux classes héritent de BindingManagerBase : CurrencyManager et PropertyManager :
V. Parse et Format (modifier à la volée)![]()
Il est possible de modifier à la voler la valeur qui transitent entre un contrôle et une source de donnée. Pour ça, on utilise les événements Parse et Format de la classe Binding correspondante.
Il suffit de les intercepter via un AddHandler et de faire les traitements dans la fonction qu'appellera notre AddHandler :
On ajoute ensuite les fonctions correspondantes avec la signature (Object ,ConvertEventArgs) afin de récupérer les données envoyés par l'événement Parse ou Format :
C'est ce deuxième argument de type ConvertEventArgs qui va nous permettre de modifier la valeur en transite. En quelque sorte, c'est un pointeur sur la valeur que nous voulons traiter. Nous pouvons ainsi modifier par sa `Property` Value de type Object, la valeur qui va modifier, dans un cas, le DataSource, ou dans l'autre, le contrôle.
Dans l'exemple qui suit, la source de donnée est de type Date, et nous souhaitons que cette date s'affiche dans un format "12.11.05" .
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur.
La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
|