Desarrollar un control basado en plantilla
ASP.NET proporciona una característica versátil denominada plantillas, que permite separar los datos del control de su presentación. Los controles basados en plantilla no proporcionan por sí mismos una interfaz de usuario. La interfaz de usuario del control la proporciona un programador de páginas mediante plantillas en pantalla, que permiten al programador personalizar la interfaz de usuario del control. Si no está familiarizado con las plantillas de ASP.NET, vea el ejemplo en Tutorial rápido de ASP.NET —> Formularios Web Forms ASP.NET — > Acceso a datos y Personalización —> Introducción a controles con plantilla.
Para crear un control basado en plantilla
Implemente la interfaz System.Web.UI.INamingContainer. Se trata de una interfaz de marcador que no tiene ningún método. Crea un ámbito de asignación nuevo bajo su control para que los controles secundarios tengan identificadores únicos en el árbol de asignación.
public class TemplatedFirstControl : Control,INamingContainer {...}
Aplique ParseChildrenAttribute al control y pase true como argumento. Esto indica al analizador de páginas cómo analizar las etiquetas de propiedades de plantilla cuando se utiliza el control de manera declarativa en una página ASP.NET. En el paso 3 se indica cómo definir una propiedad de plantilla.
Nota Si su control deriva de WebControl, no tiene que aplicar ParseChildrenAttribute ya que WebControl ya está marcado con este atributo.
[ ParseChildren(ChildrenAsProperties = true)] public class TemplatedFirstControl : Control, INamingContainer {...}
Para obtener más información sobre ParseChildrenAttribute, vea Utilizar ParseChildrenAttribute.
Defina una o más propiedades del tipo System.Web.UI.Itemplate. ITemplate tiene un método, InstantiateIn, que crea controles utilizando la plantilla facilitada en pantalla en la página. No es necesario que implemente el método InstantiateIn; el marco de trabajo de páginas ASP.NET proporciona la implementación. Una propiedad ITemplate debe tener un atributo de metadatos tipo System.Web.UI.TemplateContainerAttribute que indique el control INamingContainer que almacenará plantilla para la que se ha creado una instancia. Se explica en el paso 4. El fragmento de código siguiente define una propiedad de plantilla.
[TemplateContainer(typeof(FirstTemplateContainer))] public ITemplate FirstTemplate {...}
El argumento de TemplateContainerAttribute es el tipo de control contenedor dentro del cual va a crear una instancia de la plantilla. El control contenedor es independiente del control basado en plantilla que está creando. La razón de tener un contenedor lógico es que un control basado en plantilla a menudo tiene una plantilla que requiere la creación continua de instancias con distintos datos. Al disponer de un control contenedor distinto al control raíz basado en plantilla se pueden crear dichas instancias múltiples. El contenedor lógico es el INamingContainer inmediato de los controladores secundarios dentro de la plantilla. Esta relación se explica con más detalle en Desarrollar un control de enlace de datos basado en plantilla.
Nota El control contenedor debe implementar INamingContainer por sí mismo, ya que dispone de controles secundarios a los que se deben asignar nombres únicos en una página.
public class FirstTemplateContainer : Control, INamingContainer {...}
Reemplace el método CreateChildControls para crear los controles secundarios en la plantilla. Esto se realiza en tres pasos.
- Cree una instancia del contenedor de plantillas.
- Invoque el método InstantiateIn de la propiedad de plantilla y pásele el contenedor como argumento. El método InstantiateIn (declarado en la interfaz ITemplate) crea una instancia de los elementos de la plantilla como controles secundarios del contenedor de plantillas. No es necesario que implemente el método InstantiateIn; el marco de trabajo de páginas ASP.NET proporciona la implementación.
- Agregue la instancia del contenedor de plantillas a la colección Controls del control basado en plantilla.
En el siguiente fragmento de código se muestra una implementación 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)); } }
Reemplace el método OnDataBinding heredado de Control para invocar el método EnsureChildControls. Así se garantiza que los controles secundarios de la plantilla se creen antes de que el marco de trabajo de páginas intente evaluar alguna expresión de enlace de datos dentro de la plantilla. También debe llamar al método OnDataBinding de la clase base para asegurarse de que se invocan los controladores de eventos registrados.
protected override void OnDataBinding(EventArgs e) { EnsureChildControls(); base.OnDataBinding(e); }
En el paso 5, repita la lógica del método CreateChildControls para crear una instancia de una plantilla para cada propiedad de plantilla del control.
Para ver ejemplos de un control basado en plantilla, un control contenedor asociado para la plantilla y una página que utiliza el control, vea Ejemplo de control basado en plantilla.