Grazie alle
Visual Studio Extension for WSS 1.0 (ed alla successiva 1.1 CTP) ora in Visual Studio abbiamo disponible anche un tipo di progetto Web Part. Il template risolve brillantemente tutte le problematiche di packaging e deployment delle web part ma aggiunge poco o niente allo sviluppo vero e proprio delle web part. Come per le precedenti web part di WSS 2.0 ci ritroviamo ad usare Visual Studio più o meno come un Notepad avanzato con tanto di intellisense ma nessuno supporto allo sviluppo visuale. Realizzare una applicazione web part senza tutte le facilitazioni che si hanno nello sviluppo webforms normale è a volte una vera tortura, almeno per me
. Come ben sapete le Web Part sono fondamentalmente degli user control ed addirittura dalla versione WSS 3.0 esse derivano dalle Web Part native di Asp.Net 2.0. Da questa considerazione sin dalla versione WSS 2.0 per opera di
Fons Sonnemans, Jan Tielens e Patrick Tisseghem si è andata affermando una tecnica di incapsulamento degli User Control (.ascx) sviluppati in maniera "visuale" all'interno di un progetto Web Part Sharepoint. La famosissima Web Part SmartPart di Jan Tielens è sicuramente una delle Web Part più usate al mondo. Si tratta tuttavia di Wrapper generici anche se molto potenti. Se si ha la necessità di rendere il proprio lavoro una Web Part "vera" l'uso dei Wrapper diventa difficoltoso se non improponibile. Quella che descrivo nelle prossime righe non è altro che una semplificazione della tecnica che sta dietro ad un Wrapper generico che ci permette di sfruttare la potenza e la comodità della programmazione webform "visuale" in unione con le funzionalità di deployment del template Web Part delle Visual Studio Extension for Visual Studio 2005. Vi includo tutto il codice C# (le VSeWSS supportano per ora solo C# per il template Web Part). Buon divertimento.
using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
namespace UserControlWebPartWrapper
{
// per ogni WebPart deve essere generato un GUID specifico
[Guid("578672ae-748f-4990-b6ef-150e386f3ea6")]
public class UserControlWebPart : System.Web.UI.WebControls.WebParts.WebPart
{
//Possiamo usare la nostra Web Part come wrapper generico per user controls
//oppure decidere di modificare a runtime la locazione degli user controls stessi
//a tale scopo viene usata la variabile strUCtoLoad per indicare lo user control da caricare
//completo di percorso. Va ovviamente creata una property configurabile nella Tool Part
//di Sharepoint che l'utente editore della pagina userà per configurare la Web Part stessa.
private string strUCtoLoad = "/usercontrols/myUserControl.ascx";
//Le Web Part ovviamente possono avere delle propriertà configurabili tramite la Tool Part di
//configurazione propria di Sharepoint.
private string strMyCustomWebPartProperty1 = "";
//La sezione seguente illustra come creare una UI per visualizzare/gestire le proprietà nella Tool Part
//Se queste proprietà sono hard-coded nella Web Part questa sezione può essere esclusa o commentata
//Come accennato prima possiamo decidere di consentire all'editor della pagine di indicare lo User Control
//da caricare. Questa sezione va usata anche se stiamo creando un wrapper generico.
[WebBrowsable(true), Personalizable(true), WebDisplayName("User Control to Load")]
public string UCtoLoad
{
get { return strUCtoLoad; }
set { strUCtoLoad = value; }
}
//Definizione di altre proprietà esposte tramite la Tool Part
[WebBrowsable(true), Personalizable(true), WebDisplayName("My Custom Web Part Property 1")]
public string strMyCustomWebPartProperty1
{
get { return strMyCustomWebPartProperty1; }
set { strMyCustomWebPartProperty1 = value; }
}
//Qui istanziamo lo User Control.
//Si possono usare due tecniche diverse. Se quello che andiamo a creare è un Wrapper generico
//possiamo usare il codice seguente
private System.Web.UI.UserControl uc = new System.Web.UI.UserControl();
//E' da notare che in questo caso non ha molto senso il fatto di creare gli elementi per la gestione
//delle proprietà custom nella Tool Part
//Se il wrapper è invece specifico per uno User Control potere dichiarare direttamente
//la classe origine ed avere quindi accesso diretto a tutte le proprietà ed tutti i metodi
//dello User Control. Questo è il caso più frequente.
private myAssembly.MyUserControl uc = new myAssembly.MyUserControl();
//Definiamo una stringa per accogliere eventuali messaggi di errore
private string errMsg = "";
//L'override di OnInit è OBBLIGATORIO dato che serve alla gestione del ciclo di vita della
//pagina stessa.
protected override void OnInit(EventArgs e)
{
try
{
//Come accennato possiamo avere un wrapper generico oppure un wrapper specifico per
//uno specifico User Control
//questo codice va usato se abbiambo un wrapper generico (usiamo un oggetto Syste.Web.UI.UserControl)
uc = (System.Web.UI.UserControl)Page.LoadControl(strUCtoLoad);
//questo codice va usato se abbiamo un wrapper specifico per uno specifico User Control
uc = (myAssembly.MyUserControl)Page.LoadControl(strUCtoLoad);
//in questa sezione potete anche passare i valori delle proprietà impostate nella Tool Part
//allo User Control. Si possono anche passare i contesti di esecuzione della Web Part (Site, Web) ecc.
//Esempio: us.MyCustomProperty1=strMyCustomProperty1;
//Aggiungiamo quindi il controllo alla collection dei controlli.
this.Controls.Add(uc);
}
catch (Exception exOI)
{
//in errMsg abbiamo l'eventuale messaggio relativo ad una eccezione verificatasi
//durante l'OnInit
errMsg = exOI.ToString();
}
}
//Invocazione del metodo Render per visualizzare la web part del browser
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
this.EnsureChildControls();
try
{
uc.RenderControl(writer);
}
//In caso di eccezione visualizziamo il relativo messaggio
catch (Exception ex)
{
errMsg += ex.Message;
}
writer.Write(errMsg);
}
}
}