Développement d'un contrôle basé sur un modèle
ASP.NET fournit une fonctionnalité polyvalente appelée modèles qui permet de séparer les données du contrôle de leur présentation. Un contrôle basé sur un modèle ne fournit pas lui-même une interface utilisateur. L'interface utilisateur du contrôle est fournie par un développeur de pages par l'intermédiaire de modèles inline qui permettent à un développeur de pages de personnaliser l'interface utilisateur du contrôle. Si vous ne connaissez pas bien les modèles dans ASP.NET, consultez l'exemple que vous trouverez dans Démarrage rapide ASP.NET —> Web Forms ASP.NET —> Accès et personnalisation des données —> Introduction aux contrôles basés sur un modèle.
Pour développer un contrôle basé sur un modèle
Implémentez l'interface System.Web.UI.INamingContainer. Il s'agit d'une interface de marqueur ne possédant aucune méthode. Elle crée une nouvelle portée d'attribution de nom sous votre contrôle afin que les contrôles enfants possèdent des identificateurs uniques dans l'arborescence d'attribution d'un nom.
public class TemplatedFirstControl : Control,INamingContainer {...}
Appliquez ParseChildrenAttribute à votre contrôle et passez true comme argument. Cela indique à l'analyseur de pages la manière dont il doit analyser les balises des propriétés du modèle lorsque votre contrôle est utilisé par déclaration dans une page ASP.NET. L'étape 3 montre comment définir une propriété de modèle.
Remarque Si votre contrôle dérive de WebControl, vous n'avez pas besoin d'appliquer ParseChildrenAttribute, car WebControl est déjà marqué par cet attribut.
[ ParseChildren(ChildrenAsProperties = true)] public class TemplatedFirstControl : Control, INamingContainer {...}
Pour plus d'informations sur ParseChildrenAttribute, consultez Utilisation de ParseChildrenAttribute.
Définissez une ou plusieurs propriétés de type System.Web.UI.ITemplate. ITemplate possède une méthode InstantiateIn, qui crée des contrôles à l'aide du modèle inline fourni dans la page. Vous n'avez pas besoin d'implémenter la méthode InstantiateIn, puisque l'infrastructure de page ASP.NET s'en charge. Une propriété ITemplate doit posséder un attribut de métadonnées de type System.Web.UI.TemplateContainerAttribute qui indique le contrôle INamingContainer contenant le modèle instancié. Cela est expliqué à l'étape 4. Le fragment de code suivant définit une propriété de modèle.
[TemplateContainer(typeof(FirstTemplateContainer))] public ITemplate FirstTemplate {...}
L'argument de TemplateContainerAttribute est le type du contrôle conteneur au sein duquel vous souhaitez que le modèle soit instancié. Le contrôle conteneur est indépendant du contrôle basé sur un modèle que vous créez. La raison de l'existence d'un conteneur logique réside dans le fait qu'un contrôle basé sur un modèle possède souvent un modèle qui doit être instancié de manière répétée avec des données différentes. Disposer d'un contrôle conteneur différent du contrôle racine basé sur un modèle permet de disposer de ces instances multiples. Le conteneur logique est le INamingContainer immédiat des contrôles enfants au sein du modèle. Pour des informations détaillées sur cette relation, consultez Développement d'un contrôle dépendant basé sur un modèle.
Remarque Le contrôle conteneur proprement dit doit implémenter INamingContainer, car il possède des contrôles enfants qui doivent être nommés de manière unique sur une page.
public class FirstTemplateContainer : Control, INamingContainer {...}
Substituez la méthode CreateChildControls pour créer les contrôles enfants dans le modèle. Cela s'effectue en trois étapes.
- Instanciez le conteneur du modèle.
- Appelez la méthode InstantiateIn de la propriété du modèle et passez-lui le conteneur sous la forme d'un argument. La méthode InstantiateIn (déclarée dans l'interface ITemplate) instancie les éléments du modèle sous la forme de contrôles enfants du conteneur du modèle. Vous n'avez pas besoin d'implémenter la méthode InstantiateIn, puisque l'infrastructure de page ASP.NET s'en charge.
- Ajoutez l'instance du conteneur du modèle à la collection Controls de votre contrôle basé sur un modèle.
Le fragment de code suivant illustre une implémentation de CreateChildControls.
private Control myTemplateContainer; protected override void CreateChildControls () { if (FirstTemplate != null) { myTemplateContainer = new FirstTemplateContainer(this); FirstTemplate.InstantiateIn(myTemplateContainer); Controls.Add(myTemplateContainer); } else { Controls.Add(new LiteralControl(Text + " " + DateTime)); } }
Substitue la méthode OnDataBinding héritée de Control pour appeler la méthode EnsureChildControls. Vous avez ainsi la garantie que les contrôles enfants contenus dans le modèle sont créés avant que l'infrastructure de page essaie d'évaluer des expressions de liaison de données au sein du modèle. Vous devez aussi appeler la méthode OnDataBinding de la classe de base pour vous assurer que les gestionnaires d'événements inscrits sont bien appelés.
protected override void OnDataBinding(EventArgs e) { EnsureChildControls(); base.OnDataBinding(e); }
À l'étape 5, répétez la logique au sein de la méthode CreateChildControls afin d'instancier un modèle pour chacune des propriétés du modèle de votre contrôle.
Pour des exemples de contrôle basés sur un modèle, d'un contrôle conteneur associé au modèle, et d'une page qui utilise le contrôle, consultez Exemple de contrôle basé sur un modèle.