Dopo un piccolo periodo di assenza ho deciso di postare alcune parti di codice per la realizzazione di una WebPartChrome custom (anche in seguito alla richiesta da parte di un lettore del blog ).

Nel mio caso ho dovuto realizzare delle webparts con un look&feel completamente custom e questo porta alla necessità di realizzare un WebPartChrome, il quale si occupa del rendering vero e proprio.

Quindi realizziamo la nostra classe MyWebPartChrome che eredita direttamente da WebPartChrome e andiamo a fare l'override del metodo RenderWebPart :

public class MyWebPartChrome : WebPartChrome
{
   ....
   public override void RenderWebPart(HtmlTextWriter writer, WebPart webPart)
   {
      RenderWebPartHeader(writer, webPart)
      RenderPartContents(writer, webPart);
      RenderWebPartFooter(writer, webPart);
   }
   ....
}

Dove i tre metodi richiamati all'interno sono due metodi privati che si occupano di renderizzare parti distinte delle mie web parts (header e footer) e il metodo standard della WebPartChrome per la renderizzazione del contenuto. Per semplifcare ulteriormente la creazione del mio look&feel ho deciso di utilizzare dei templates, ovvero un file HTML che contiene dei semplici segnaposto dove andare a sostituire le parti necessarie per il corretto funzionamento del framework delle webparts (cosa su tutte l'ID del Title, che come accennavo nell'altro post, permette il corretto funzionamento del drag&drop). Avremmo quindi un template di questo tipo :

<div id="[IDWebPart]" class="miaclass1">
    <div id="[IDTitolo]" class="miaclass2">
        [Titolo]</div>
    <div class="miaclass3">
        [Verbi]       
    </div>
</div>
<div> 
    <div class="miaclass4">
  <div style="[Visibilita]">
   [Contenuto]
  </div>
    </div>
    <div class="miaclass5">
    </div>
</div>
<div class="miaclass6">
</div>

Una volta realizzato il mio template sarà compito del mio CustomChrome (o di altro) andare a leggersi il file direttamente da filesystem (con eventuale verifica di data modifica) o come risorsa incorporata. Questo esempio di template viene spezzato in Header e Footer tramite il segnaposto [Contenuto], che indica dove verrà renderizzato il contenuto della web part vera e propria:

....
webPartTemplate = MyTemplateBuilder.Split(new string[] { "[Contenuto]" }, StringSplitOptions.RemoveEmptyEntries);
WEBPART_TEMPLATE_HEADER = webPartTemplate[0];
WEBPART_TEMPLATE_FOOTER = webPartTemplate[1];
....

A questo punto ecco i metodi che renderizzano Header e Footer:

private void RenderWebPartHeader(HtmlTextWriter writer, WebPart webPart)
{
   writer.Write(WEBPART_TEMPLATE_HEADER
      .Replace("[IDWebPart]", GetWebPartChromeClientID(webPart))
      .Replace("[Icona]", webPart.ResolveUrl(webPart.TitleIconImageUrl))
      .Replace("[IDTitolo]", GetWebPartTitleClientID(webPart))
      .Replace("[Titolo]", webPart.Title)
      .Replace("[Verbi]", RenderVerbs(webPart))
      .Replace("[Visibilita]", (webPart.ChromeState == PartChromeState.Minimized)?"display:none;":"")
   );
}

private void RenderWebPartFooter(HtmlTextWriter writer, WebPart webPart)
{
   writer.Write(WEBPART_TEMPLATE_FOOTER);
}

Spero che questo piccolo post possa essere utile per la realizzazione di un Chrome completamente custom, operazione che a mio parere risultà un pò più macchinosa di quanto mi aspettassi, soprattutto data la fatica nella ricerca di materiale e di esempi funzionanti.

PS: ovviamente questo è un esempio scritto di getto e con un pò di taglia/incolla dal progetto che ho realizzato, quindi prendetelo giusto come piccola traccia