Canalblog
Editer l'article Suivre ce blog Administration + Créer mon blog
Publicité
MSDOTNET
15 octobre 2007

Customs controls : Notions

Cet article fait suite à celui sur les Customs Controls hérités. Vous y trouverez les informations nécessaires au développement d'un Custom Control qui s'appuie sur l'assemblage de contrôles existant.

Introduction

Les Customs Controls sont des contrôles serveur ASP.NET que n’importe qui peut développer. Ils vous permettent de contrôler totalement le rendu et les fonctionnalités du contrôle.
De plus, contrairement aux Users Controls (ou contrôles utilisateurs), ils peuvent être développés dans une librairie et donc être réutilisés dans plusieurs projets à la fois.

Sachez qu’il existe également des Customs Controls pour les WinFoms mais cet article s’attachera à montrer le développement destiné au Web (ASP.NET).

Maintenant que nous avons vu comment développer des Customs Controls Hérités nous allons nous intéresser aux Customs Controls Composites.
Ces contrôles assemblent plusieurs autres contrôles existants pour fournir de nouvelles possibilités.

Convention

Contrôle Composite : Contrôle qui contient d’autres contrôles
Contrôle Composant : Contrôle qui constitue un contrôle composite.

De quoi hériter ?

Nous allons hériter de System.Web.UI.WebControl. Cette classe nous fournira toutes les propriétés et méthodes pour pouvoir développer notre Custom Control Composite.

De plus, nous allons implémenter l’interface INamingContainer qui permet de générer des ID unique pour les contrôles composants.
Prenons un exemple pour expliquer le fonctionnement et l’utilité de cette interface :
Dans un contrôle composite vous mettez une TextBox à laquel vous assigner l’ID txtTitre. En plaçant votre contrôle sur une WebForm le serveur générera une page html avec un champ de saisi dont l’ID sera exactement txtTitre.
Maintenant, imaginons que vous placer le même contrôle composite une deuxième fois sur la même WebForm, le serveur va générer un second champ de saisie avec un ID txtTitre et vous obtiendrez une erreur vous expliquant qu’un identifiant de contrôle doit être unique.
L’interface INamingContainer va fournir à votre contrôle composite la capacité de générer des ID unique en les nommant de la façons suivante : [IDDuControleComposite]_[IDDuControleComposant]_[TrigrammeDuType]
Ce qui donnera dans notre cas (avec l’ID du contrôle composite qui vaut MonControle) : MonControle_txtTitre_txt.

Voici un exemple de déclaration de classe d’un contrôle composite :

public class ValideTextBox : System.Web.UI.WebControls.WebControl, INamingContainer

Ne pas perdre la mémoire (bis)

Dans notre premier article sur les Customs Controls Hérités nous avons vu la problématique concernant la gestion des états d’un Custom Control pendant ça durée de vie.
Nous avions alors vu une première possibilité qui consistait à utiliser le ViewState pour sauvegarder ces états.

Ici nous allons découvrir une nouvelle technique qui s’appuie sur les contrôles existants.

Explication

Les Customs Controls Composites ont la particularité de contenir d’autres contrôles qui gèrent eux-mêmes leurs états.
Il suffira donc de s’appuyer sur ces contrôles qui le composent pour garder en mémoire l’état de son Custom Control.

Mise en application

Etape 1 : Déclarer le ou les contrôles composants
Exemple :

protected TextBox    innerTextBox;
protected CustomValidator   innerCustomValidator;
protected RangeValidator   innerRangeValidator;
protected RegularExpressionValidator innerRegularExpressionValidator;
protected RequiredFieldValidator  innerRequiredFieldValidator;

Etape 2 : Créer les contrôles
Pour cette étape, nous avons besoin de surcharger (override) la méthode CreateChildControls pour, comme sont nom l’indique, créer les contrôles composants au moment opportun.
Voici un exemple :

protected override void CreateChildControls()
{
   // TextBox creation
   innerTextBox.ID = "txt";
   innerTextBox.TextChanged += new EventHandler(innerTextBox_TextChanged);
   this.Controls.Add(innerTextBox);
        /* ... */
}

Comme vous pouvez le voir, on vient ajouter (Methode Add) le contrôle composant à la liste des contrôles (Controls).
Remarquez également que l’on s’abonne à un évènement. La gestion des évènements est vue un peu plus bas.

Etape 3 : Rendre accessible les propriétés des contrôles
En s’arrêtant à l’étape 2, l’utilisateur du contrôles composite n’aurait aucun accès aux contrôles le composant. Généralement, on voudra donner la possibilité de modifier les propriétés des ces derniers.
Comme d’habitude nous allons passer par les propriétés.
Voici un exemple :

[Browsable(true), Category("Appearance"),
Description("The text content of the TextBox control.")]
public string Text
{
   get
   {
      EnsureChildControls();
      return innerTextBox.Text;
   }
   set
   {
      this.EnsureChildControls();
      innerTextBox.Text = value;
   }
}

Remarquez l’appel à la méthode EnsureChildControls. Elle permet de vérifier si oui ou non les contrôles composants ont déjà été créés (est-ce que un appel à CreateChildControls a déjà été fait ?)
Il faut systématiquement faire appel à cette méthode au risque de tomber sur une exception Object not set reference !

Cas particulier des évènements

Très souvent, vous voudrez également rendre disponible un évènement d’un contrôle composant. Pour se faire, il suffit de s’abonner à l’évènement souhaité (voir l’étape 2), de créer la méthode cible de cette évènement et de rendre disponible l’évènement en déclarant public un EventHandler adéquate.
Voici un exemple :

[Browsable(true), Category("Action"),
Description("Fired when the text property has been changed.")]
public event EventHandler TextChanged;
private void innerTextBox_TextChanged(object sender, EventArgs e)
{
   if(TextChanged != null)
   {
      TextChanged(sender, e);
   }
}

Conclusion

Comme vous pouvez le voir dans l’exemple ci-dessus, nous ne faisons appel à aucun moment au ViewState. Les contrôles composants vont gérer eux mêmes leurs états.

Afficher les contrôles composants

Nous avons maintenant un contrôle composite avec des contrôles le composant. Nous avons rendu disponible certaines propriétés. Mais nous n’avons toujours pas indiqué comment afficher ces contrôles.
Pour ce faire, il suffit de surcharger (override) la méthode Render.
Plutôt qu’un long discourt, voici un exemple :

protected override void Render(HtmlTextWriter writer)
{
   writer.Write("<table><tr><td>");
   innerTextBox.RenderControl(writer);
   writer.Write("</td><td>");
   if(innerCompareValidator.Enabled)
   {
      innerCompareValidator.RenderControl(writer);
   }
   if(innerCustomValidator.Enabled)
   {
      innerCustomValidator.RenderControl(writer);
   }
   if(innerRangeValidator.Enabled)
   {
      innerRangeValidator.RenderControl(writer);
   }
   if(innerRegularExpressionValidator.Enabled)
   {
      innerRegularExpressionValidator.RenderControl(writer);
   }
   if(innerRequiredFieldValidator.Enabled)
   {
      innerRequiredFieldValidator.RenderControl(writer);
   }
   writer.Write("</td></tr></table>");
}

Remarquez l’utilisation de la méthode RenderControl qui va aller écrire son propre contenu HTML dans le HtmlTextWriter.

Publicité
Publicité
Commentaires
MSDOTNET
Publicité
Publicité