Frédéric Mélantois
Contrôles ASP.NET 2.0, l'utilisation des régions
Par Frédéric Mélantois publié le 22/08/2006 à 19:46, lu 4978 fois, 4 pages
 2 | Création du contrôle
Création du contrôle
Nous allons créer un contrôle simple qui sera constitué d'une zone de titre et d'une zone de contenu. Le titre ou le contenu seront succeptibles aussi bien de comporter du texte que d'autres contrôles.

La création d'un contrôle composite s'impose donc. Le framework 2.0 nous fournit le contrôle de base CompositeControl qui implémente l'interface InamingContainer qui se charge de donner un ID automatiquement à votre contrôle.

Pour satisfaire l'aspect didactique, utilisons un tableau Html constitué d'une cellule pour le titre et d'une cellule pour le contenu, pour satisfaire à l'aspect didactique. La tendance actuelle étant de proscrire l'utilisation des tableaux, libre à vous d'utiliser d'autres éléments HTML. Il suffit simplement que les éléments (contrôles) possèdent la possibilité d'accepter des attributs (comme nous le verrons un peu plus loin).

Voici notre contrôle de base :
using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;

public class WebCartouche : CompositeControl
{
    private Table _tablo;
    private TableCell _cellContent;
    private TableCell _cellTitle;
        
    protected override void CreateChildControls()
    {
        _tablo = new Table();
        _cellTitle = new TableCell();
        _cellContent = new TableCell();
        
        TableRow tr1 = new TableRow();
        TableRow tr2 = new TableRow();

        tr1.Controls.Add(_cellTitle);
        tr2.Controls.Add(_cellContent);

        _tablo.Controls.Add(tr1);
        _tablo.Controls.Add(tr2);            
    }

    protected override void Render(HtmlTextWriter output)
    {
        if (_tablo == null)
            CreateChildControls();
        _tablo.RenderControl(output);
    }
}
Ajoutons deux templates qui permettront de recevoir textes et contrôles.
private ITemplate _contentTemplate;
[Browsable(false),
PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate ContentTemplate
{
    get
    {
        return _contentTemplate;
    }
    set
    {
        _contentTemplate = value;
        base.ChildControlsCreated = true;
    }
}

private ITemplate _titleTemplate;
[Browsable(false),
PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate TitleTemplate
{
    get
    {
        return _titleTemplate;
    }
    set
    {
        _titleTemplate = value;
        base.ChildControlsCreated = true;
    }
}
La propriété « ChildControlsCreated » permet d'indiquer que les contrôles enfants ont été créés, qu'il n'est pas nécessaire que la méthode « CreateChildControls » soit encore appelée.

Instancions les templates dans les cellules de notre tableau, comme ceci :
protected override void CreateChildControls()
{
    _tablo = new Table();
    _cellTitle = new TableCell();
    _cellContent = new TableCell();
        
    TableRow tr1 = new TableRow();
    TableRow tr2 = new TableRow();

    if (_titleTemplate != null)
    {
        _titleTemplate.InstantiateIn(_cellTitle);
    }
    else if (this.DesignMode)
    {
        /*
         * En mode design, on affiche un texte par defaut pour avoir 
         * une zone selectionnable.
         */
        Literal l = new Literal();
        l.Text = "Le titre";
        _cellTitle.Controls.Add(l);
    }

    if (_contentTemplate != null)
    {
        _contentTemplate.InstantiateIn(_cellContent);
    }
    else if (this.DesignMode)
    {
        //on affiche par defaut pour avoir une zone selectionnable.
        Literal l = new Literal();
        l.Text = "Mon contenu";
        _cellContent.Controls.Add(l);
    }

    tr1.Controls.Add(_cellTitle);
    tr2.Controls.Add(_cellContent);

    _tablo.Controls.Add(tr1);
    _tablo.Controls.Add(tr2);
}
Maintenant, il nous faut définir les « régions » du contrôle manipulables par le designer. Comme nous l'avons vu précédemment, il faut que le contrôle pouvant définir une région possède des attributs. En particulier, la condition suffisante et nécessaire est d'implémenter l'interface IAttributeAccessor.

Afin de pouvoir inventorier les régions du contrôle que l'on souhaite voir s'afficher dans le designer de Visual Studio 2005. Pour cela, on définit une liste interne à l'assembly.
internal List<IAttributeAccessor> regions;
Lors de la création des contrôles enfants, il suffit d'ajouter à la liste les régions de notre choix.

Le code suivant complète la méthode « CreateChildsControls » :
regions = new List<IAttributeAccessor>();
regions.Add(_cellTitle);
regions.Add(_cellContent);
Il ne reste plus qu'à attribuer un contrôle Designer, héritant de CompositeControlDesigner, grâce à l'attribut DesignerAttribute.
[Designer(typeof(WebCartoucheDesigner))]
[ToolboxData("<{0}:WebCartouche runat=server></{0}:WebCartouche>")]
public class WebCartouche : CompositeControl
 
» Démarrer une discussion