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
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.