Aggiungere controlli ad una pagina ASP.NET con supporto per gli eventi usando XSLT

di Andrea Zani, in ASP.NET 2.0, System.Xml,

XSLT è molto comodo per la creazione di documenti in qualsiasi formato partendo da un documento XML. Alcune difficoltà si presentano quando all'interno dell'output della trasformazione vogliamo inserire dei server control con i relativi eventi.

Grazie al method "ParseControl" della classe Page, possiamo inserire nella nostra pagina dinamicamente i tag per i controlli.

Nell'esempio allegato a questo script è presente un file XML con questa struttura:

<?xml version="1.0" encoding="utf-8" ?>
<controls>
  <textbox required="true" name="name" description="Name" />
  <textbox required="true" name="surname" description="Surame" />
  <radiobuttonlist name="sex" description="Sex">
  <select>Male</select>
  <select>Female</select>
  </radiobuttonlist>
  <dropdownlist name="age" description="Age">
  <select>Under 18</select>
  <select>18-35</select>
  <select>35-60</select>
  <select>Over 60</select>
  </dropdownlist>
</controls>

Ho creato dei tag personalizzati per l'inserimento automatico di TextBox (con l'opzionale controllo RequiredFieldControl), DropDownList e RadioButtonList.

Grazie al file di trasformazione allegato possiamo creare la nostra pagina con i relativi controlli in modo completamente dinamico. Questo codice in C# inserisce il codice prodotto dalla trasformazione all'interno di un controllo PlaceHolder:

XslCompiledTransform transform = new XslCompiledTransform();
transform.Load(Server.MapPath("CreateControlsx.xslt"));
XmlWriterSettings ws = transform.OutputSettings.Clone();
ws.CheckCharacters = false;
StringWriter stw = new StringWriter();
XmlWriter sw = XmlWriter.Create(stw, ws);
transform.Transform(Server.MapPath("ObjectFormx.xml"), sw);
string result = stw.ToString();

result = result.Replace("xmlns:asp=\"remove\"", "");
Control ctrl = Page.ParseControl(result);
ph1.Controls.Add(ctrl);

Uno dei primi problemi che dobbiamo affrontare è l'impossibilità di inserire direttamente nel file XSLT l'eventuale codice per collegare i controlli ai rispettivi eventi, come, in questo caso, il click sul Button.
Per ovviare a questo, subito dopo l'inserimento nel codice della pagina, ci è sufficiente esaminare tutti i controlli inseriti alla ricerca del nostro button, e solo in quel momento aggiungere l'evento:

foreach (Control c in ph1.Controls[0].Controls)
{
   Button b = c as Button;
   if (b == null) continue;
   b.Click += clickeda;
}

protected void clickeda(object o, EventArgs e)
{
   ProcessForm();
}

Ora che abbiamo risolto il problema dell'inserimento da XSLT dei controlli e la gestione degli eventi, rimane un ultimo problema, l'accesso ai dati dal form visualizzato all'utente. Questo è possibile con questo codice:

private void ProcessForm()
{
  StringBuilder sb=new StringBuilder();
  XElement doc = XElement.Load(Request.MapPath("ObjectFormx.xml"));
  IEnumerable<XElement> controls = doc.Elements();
  foreach (XElement x in controls)
  {
    string item = x.Attribute("name").Value;
    object ctrl = FindControl(item);
    if (ctrl is TextBox)
    {
      sb.Append("TextBox '");
      sb.Append(item);
      sb.Append("' value= '");
      sb.Append(((TextBox)ctrl).Text);
      sb.Append("'<br />");
    }
    ...
  }
  msg.Text = sb.ToString();
}

Così come abbiamo inserito i controlli, possiamo leggerne la struttura e con il metodo FindControl cercare i controlli appena inseriti.

Vale ovviare la stessa considerazione che si fa quando si inserisce un controllo dinamicamente da codice: anche in questo caso è necessario ricreare tutti i controlli nell'evento "Page_Init" della nostra pagina.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi