I'm speaking @ SharePoint & Office Conference 2011

Anche se un po in ritardo, ho il piacere di annunciare che quest'anno sarò speker alla SharePoint & Office Conference 2011 con la sessione: SB323 Web Development Basics for SharePoint, dove parlerò di tutte le tecnologie web che un vero SharePointer deve conoscere.Le iscrizioni sono ancora aperte! :-D 

I'm speaking @ Webtech 2010

JNotify (JQuery Notification Engine)

Vi segnalo la presenza di questa libreria, creata da me, per la gestione di messaggi di notifica all'interno di pagine web.E' sviluppata come plugin per jQuery e supporta jQuery UI per la parte di temi.La potete trovare come progetto open-source su Codeplex qui.

Visualizzare un User Control come se fosse una pagina

Questo post nasce dall’esigenza di utilizzare i controlli utente in accoppiata al plug-in ThickBox per jQuery. Per chi non conoscesse jQuery, sto parlando di una libreria JavaScript open source molto avanzata, leggera, estensibile e di facile utilizzo che permette di aggiungere “behavior” all’html. Essa è balzata agli onori della cronaca perché sia Microsoft che Nokia hanno annunciato il loro supporto rispettivamente in Visual Studio e nel Nokia Web Run-Time Platform. ThickBox è un’estensione a questa libreria, e consente di creare delle finestre modali alla Web 2.0 semplicemente utilizzando link html. Uno delle modalità di utilizzo di ThickBox è quella di aprire appunto un link all’interno di un iframe, permettendo di visualizzare, per esempio in un contesto master-detail, una pagina all’interno della pagina corrente. Un esempio classico è quello del master-detail, abbiamo una GridView e una delle colonne è un link al dettaglio della riga. Bene, ma concentriamoci su cos’è uno user control. Esso è un tipo di controllo composito che funziona come una pagina Web ASP.NET. È possibile aggiungervi markup e controlli server esistenti e definirne le proprietà e i metodi e incorporarlo nelle pagine Web ASP.NET. Esso è praticamente uguale a una pagina ASP.NET ad eccezione di alcune cose: L'estensione del nome file del user control è ASCX. Al posto di una direttiva @ Page, l’user control contiene una direttiva @ Control che definisce la configurazione e altre proprietà. Nell’user control non sono presenti elementi html, body o form, che devono invece trovarsi nella pagina che contiene il controllo. Gli user control non possono essere eseguiti come file autonomi. Quest’ultimo punto è quello che mi ha fatto più riflettere. Abbiamo capito che gli user control sono simili alle Page (tant’è che esiste una guida su come convertire User Control in Page), ma allora perché non posso richiamarli direttamente come se fossero delle Pagine? Se provo a chiamare direttamente un user control questo è il risultato Questo perché come detto precedentemente un user control non è in grado di generare da solo i tag html necessari per il corretto funzionamento cioè html, body e soprattutto form. L’unico modo per risolvere il problema è quello di creare una pagina che faccia da “host” per il nostro controllo, una per ogni controllo che vogliamo visualizzare come se fosse una pagina. L’idea che ho avuto, banale ma efficace, è quella di realizzare una pagina che permetta questo, caricando in modo dinamico il controllo che si vuole visualizzare. Per caricare un user control all’interno di una pagina si utilizza il metodo LoadControl della classe Page, che accetta come parametro il path virtuale del controllo da caricare. 1: String VirtualPath = "~/DateTime.ascx"; 2: UserControl userControl = (UserControl)this.LoadControl(VirtualPath); Il punto ideale dove caricare i controlli all’interno del ciclo di vita della pagina è il Page_Init, perché questo è il punto dove l’albero dei controlli della pagina viene creato e inizializzato. Se vogliamo che il nostro controllo persisti il suo viewstate, dobbiamo aggiungerlo proprio in questo evento, altrimenti si avrà un disallineamento fra i vari postback. Un’altra cosa da ricordare è che dobbiamo aggiungere il controllo dinamicamente alla pagina a ogni caricamento, nel viewstate viene persistito solo lo stato dei controlli e non i controlli stessi. 1: protected override void OnInit(EventArgs e) 2: { 3: base.OnInit(e); 4:  5: String VirtualPath = "~/DateTime.ascx"; 6: UserControl userControl = (UserControl)this.LoadControl(VirtualPath); 7:  8: this.Form.Controls.Add(userControl); 9: } Questo è il metodo classico per poter aggiungere un controllo dinamicamente a una pagina. Il passo successivo è quello di poter chiamare direttamente il controllo, senza passare per una pagina, almeno in apparenza :-) Per questo, basta registrare new web.config un HttpHandler che intercetti una determinata richiesta e la gestisca, per esempio la classe che ho implementato serve per gestire la richiesta “*.ascx.aspx” cioè tutte le richieste che finiscono con .ascx.aspx. Ho scelto l’estensione .aspx perché è già registrata su IIS come estensione gestita dall’isapi di ASP.NET 1: <httpHandlers> 2: ... 3: ... 4: <add verb="*" path="*.ascx.aspx" type="UserControlPage"/> 5: </httpHandlers> La classe deriva da Page e permette semplicemente di confondere il motore di ASP.NET facendogli credere di effettuare una richiesta a una pagina esistente invece che a un controllo ascx. 1: public class UserControlPage: Page 2: { 3: protected override void OnInit(EventArgs e) 4: { 5: base.OnInit(e); 6:  7: HtmlForm form = new HtmlForm(); 8: UserControl userControl = (UserControl)this.LoadControl(this.Request.AppRelativeCurrentExecutionFilePath.Replace(".aspx", "")); 9: 10: form.Controls.Add(userControl); 11: this.Controls.Add(form); 12: } 13:  14: protected override void Render(HtmlTextWriter writer) 15: { 16: writer.Write(@"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd""><html xmlns=""http://www.w3.org/1999/xhtml""><head><title></title></head><body>"); 17: base.Render(writer); 18: writer.Write("</body></html>"); 19: } 20: } Utilizzando la proprietà AppRelativeCurrentExecutionFilePath dell’oggetto Request ricaviamo il VirtualPath della richiesta pervenuta a ASP.NET, a questo punto basta eliminare il suffisso .aspx e avremo il path del controllo da caricare. Tutti i controlli che necessitano di iterazione con l’utente devono essere inseriti all’interno di un form ed essendo la classe UserControlPage una pagina senza markup, bisogna creare un controllo HtmlForm per poter aggiungere il nostro user control in modo corretto. Infine nel metodo Render è stato aggiunto il codice html necessario per rendere la pagina valida. A questo punto per richiamare un controllo e visualizzarlo come una comune pagina ASP.NET basterà indicare il percorso aggiungendo l’estensione “.aspx”Questo è il risultato UserControlPage.zip (38,16 kb)

About the author


Fabio Franzini is Senior Consultant, Software Engineer and Trainer, specializing mainly on SharePoint, ASP.NET, web solutions and in general about everything that revolves around the Microsoft web platform. [more]

Translate

Month List

Page List