The Dark Side of .NET Programming

Il blog di Michele Aponte
posts - 212, comments - 145, trackbacks - 16

Templated User Control

I programmatori Asp.Net Web Form conoscono bene il concetto di User Control grazie al quale è possibile creare dei propri controlli raggruppando quelli già esistenti, non tutti invece conoscono la possibilità di creare dei Templated User Control in cui non siamo noi a creare l’interfaccia che avrà il controllo ma è l’utente del nostro controllo che, attraverso la definizione di un template, può definire il rendering del controllo, un po’ come fa il controllo asp:repeater.

Nonostante possa spaventare a primo impatto, la realizzazione di questi controlli è più semplice di quello che si crede una volta capito il meccanismo. Si parte dai dati che si vogliono rappresentare, supponiamo una news:

   1: using System;
   2:  
   3: namespace WebApplication1
   4: {
   5:     public class News
   6:     {
   7:         public string Titolo { get; set; }
   8:         public DateTime Data { get; set; }
   9:         public string Testo { get; set; }
  10:         public string Link { get; set; }
  11:     }
  12: }

Creiamo uno user control come siamo abituati a fare, aggiungendolo come nuovo item, e nel markup l’unica cosa che dobbiamo fare è creare un PlaceHolder:

   1: <%@ Control Language="C#" AutoEventWireup="true" 
   2:     CodeBehind="NewsTemplateContoller.ascx.cs" 
   3:     Inherits="WebApplication1.UC.NewsTemplateContoller" %>
   4:  
   5: <asp:PlaceHolder id="PlaceHolderNewsTemplate" runat="server">
   6: </asp:PlaceHolder>

Definiamo nel code behind del controllo due property, una del nostro tipo News e l’altra di tipo ITemplate che chiameremo LayoutTemplate:

   1: using System;
   2: using System.Web.UI;
   3:  
   4: namespace WebApplication1.UC
   5: {
   6:     public partial class NewsTemplateContoller : System.Web.UI.UserControl
   7:     {
   8:         [PersistenceMode(PersistenceMode.InnerProperty)]
   9:         [TemplateContainer(typeof(NewsUcContainer))]
  10:         public ITemplate LayoutTemplate { get; set; }
  11:  
  12:         public News News { get; set; }
  13:    }
  14: }

La property ITemplate deve essere decorata con due attributi:

  • PersistenceMode, che specifica come un controlo asp.net persiste le proprietà a design time, nel nostro caso InnerDefaultProperty specifica che le proprietà saranno persistite all'interno del tag di apertura e chiusura del controllo
  • TemplateContainer, che serve a indicare che è un contenitore, nel nostro caso, di contenuti di tipo NewsUcContainer

A questo punto dobbiamo creare il nostro container, che chiameremo NewsContainer e che, oltre ad essere un Control, implementerà l’interfaccia INamingContainer che è vuota e serve solo a marcare la classe come contenitore:

   1: public class NewsUcContainer : Control, INamingContainer
   2: {
   3:     public News News { get; set; }
   4:  
   5:     public NewsUcContainer(News news)
   6:     {
   7:         this.News = news;
   8:     }
   9: }

A questo punto basta implementare il Page_Init del nostro controllo per legare quanto realizzato fino a questo momento:

   1: protected void Page_Init(object sender, EventArgs e)
   2: {
   3:    PlaceHolderNewsTemplate.Controls.Clear();
   4:  
   5:    if(LayoutTemplate != null)
   6:    {
   7:        if (this.News == null) this.News = new News();
   8:        NewsUcContainer container = new NewsUcContainer(this.News);
   9:        this.LayoutTemplate.InstantiateIn(container);
  10:        PlaceHolderNewsTemplate.Controls.Add(container);
  11:    }
  12: }

In pratica svuotiamo il placeholder da eventuali contenuti e se il LayoutTemplate non è vuoto istanziamo il container e lo riversiamo nel LayoutTemplate, dopodichè non ci resta che aggiungere il container ai controlli del placeholder.

Usare il nostro controllo significa come al solito registrarlo nella pagina…

   1: <%@ Register src="UC/NewsTemplateContoller.ascx" tagname="NewsTemplateContoller" tagprefix="uc1" %>

e creare il template per la nostra news all’interno del LayoutTemplate:

   1: <uc1:NewsTemplateContoller ID="NewsTemplateContoller1" runat="server">
   2:     <LayoutTemplate>
   3:         <h3><%
   1: # Container.News.Titolo 
%></h3>
   4:         <p style="font-style:italic"><%
   1: # Container.News.Data.ToString("dd-MM-yyyy") 
%></p>
   5:         <p><%
   1: # Container.News.Testo 
%></p>
   6:         <asp:hyperlink navigateurl='<%# Container.News.Link %>' runat="server" />
   7:     </LayoutTemplate>
   8: </uc1:NewsTemplateContoller>

Bindiamo qualche dato di prova nella Page_Load:

   1: protected void Page_Load(object sender, EventArgs e)
   2: {
   3:     NewsTemplateContoller1.News.Data = DateTime.Now;
   4:     NewsTemplateContoller1.News.Link = "http://www.dotnetcampania.org";
   5:     NewsTemplateContoller1.News.Titolo ="DotNetCampania on line!";
   6:     NewsTemplateContoller1.News.Testo = "Finalmente On Line il primo User Group tutto campano sulle tecnologie .NET ! Nati nel Giugno 2009 e costituitici nel Gennaio 2010 come Associazione no-profit legalmente riconosciuta, ci poniamo come obiettivo quello di riunire tutti gli appassionati di tecnologie .NET residenti in campania; anche se naturalmente possono iscriversi tutti quelli che reputeranno utile fare community con noi.";
   7:     NewsTemplateContoller1.DataBind();
   8: }

Ed ecco il favoloso risultato:

image

Il consiglio è: provateci! Sembra più complicato di quello che effettivamente è quindi non lasciatevi intimorire!

-- Michele

Print | posted on giovedì 22 luglio 2010 02:03 |

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET