DarioSantarelli.Blog("UgiDotNet");

<sharing mode=”On” users=”*” />
posts - 176, comments - 105, trackbacks - 3

My Links

News


This is my personal blog. These postings are provided "AS IS" with no warranties, and confer no rights.




Tag Cloud

Archives

Post Categories

My English Blog

[Silverlight 2] Simulare una MasterPage

Allo stato attuale, Silverlight 2 non possiede un modello di programmazione built-in per gestire il concetto di MasterPage così come avviene in ASP.NET a partire dalla versione 2.0. Ad ogni modo, per ovviare a tale mancanza, l'implementazione di una semplice soluzione custom che simula l'interazione tra una pagina "Master" e più pagine "Content" in Silverlight 2 non è poi così difficile.
L'obiettivo è fondamentalmente quello di definire un PlaceHolder all'interno di una pagina Master (che funge da RootVisual) in cui caricare e visualizzare varie pagine di contenuto. Per ottenere questo risultato vengono dunque definiti due UserControl: MasterPage e ContentPage.

- MasterPage
Supponiamo di definire la master page come un semplice UserControl, avente ad esempio il seguente classico layout:

<Grid x:Name="LayoutRoot">
 
<Grid.RowDefinitions>
   
<RowDefinition Height="100" />
   
<RowDefinition/>

  </Grid.RowDefinitions>

 

  <!-- Header -->

  <StackPanel Grid.Row="0" ... ></StackPanel>

       

  <Grid Grid.Row="1">

     <Grid.ColumnDefinitions>

        <ColumnDefinition Width="150" />

        <ColumnDefinition />

     </Grid.ColumnDefinitions>

 

    <!-- Left Column -->

    <StackPanel Grid.Column="0" ...>

      ...
   
</StackPanel>

           

    <!-- Center Column -->

    <StackPanel x:Name="ContentPagePlaceHolder" Grid.Column="1" ... />           

  </Grid>

</Grid>


Come si può notare, abbiamo un header (StackPanel) e due colonne di una Grid (una a sinistra per il menu ed una centrale per il contenuto). La colonna centrale contiene uno StackPanel nominato ContentPagePlaceHolder che funge appunto da PlaceHolder per le nostre pagine di contenuto.
Ecco una sintesi dell'implementazione della MasterPage:

public partial class MasterPage : UserControl

{

  public MasterPage()

  {

    InitializeComponent();

    LoadContentPages("contentPages.xml");

  }

 

  private void LoadContentPages(string contentPagesFile)

  {

     XDocument xDoc = XDocument.Load(contentPagesFile);

     foreach (XElement node in xDoc.Element("ContentPages").Descendants("Page"))

     {

       ContentPage page = Activator.CreateInstance(Type.GetType(node.Attribute("type").Value)) as ContentPage;

       page.PageName = node.Attribute("name").Value;    

       page.Visibility = Visibility.Collapsed;

       ContentPagePlaceHolder.Children.Add(page);

     }

   }

 

   public ContentPage GetContentPage(string pageName)

   {

     return ContentPagePlaceHolder.Children.OfType<ContentPage>().Single(p => p.PageName == pageName);

   }

 

   public void ViewContentPage(string pageName)

   {

      ViewContentPage(GetContentPage(pageName));

   }

 

   public void ViewContentPage(ContentPage page)

   {

     IEnumerable<ContentPage> contentPages = ContentPagePlaceHolder.Children.OfType<ContentPage>();

     foreach (ContentPage contentPage in contentPages)

     {

       if (!contentPage.Equals(page)) contentPage.Visibility = Visibility.Collapsed;

       else contentPage.Visibility = Visibility.Visible;

     }         

   } 

}


Tramite il metodo LoadContentPages(...) popoliamo semplicemente il ContentPagePlaceHolder con le content pages del nostro progetto che in questo caso specifichiamo in un file XML contentPages.xml:

<?xml version="1.0" encoding="utf-8" ?>

<ContentPages>

  <Page name="Page1" type="MasterPageSilverlight.Page1"></Page>

  <Page name="Page2" type="MasterPageSilverlight.Page2"></Page>

  <Page name="Page3" type="MasterPageSilverlight.Page3"></Page>
  ...

</ContentPages>


Poi, tramite il metodo ViewContentPage(...)  implementiamo il meccanismo di visualizzazione di una specifica ContentPage, che in questo caso è realizzato sfruttando la proprietà Visibility di ciascuna content page pre-caricata nel ContentPagePlaceHolder.

- ContentPage
La classe ContentPage rappresenta una pagina di contenuto visualizzabile all'interno del ContentPagePlaceHolder definito nella MasterPage. Per questa classe potremmo definire le seguenti proprietà:

  • Master: la MasterPage che contiene la ContentPage
  • PageName: il nome delle ContentPage che la identifica univocamente all'interno di un ContentPagePlaceHolder 
  • PageData: un dictionary utilizzabile per passare dati tra ContentPage 

public class ContentPage : UserControl
{

  public MasterPage Master

  {

    get { return Application.Current.RootVisual as MasterPage; }

  }

       

  public string PageName { get; set; }

 

  public Dictionary<string, object> PageData { get; set; }

 

  public ContentPage()

  {

    this.PageData = new Dictionary<string, object>();               

  }

}


Esempio di utilizzo

A questo punto abbiamo un semplice programming model per "switchare" content page sia a partire dalla MasterPage contenitore che a partire da una ContentPage contenuta nel ContentPagePlaceHolder della Master.
In particolare, 
- all'interno della MasterPage possiamo selezionare la ContentPage da visualizzare nel  ContentPagePlaceHolder nel modo seguente:

ContentPage contentPage = GetContentPage("Page2");

page.PageData["Info"] = "MyData..."; // Eventuale passaggio di dati alla pagina

ViewContentPage(contentPage);


- all'interno di una ContentPage, invece, possiamo utilizzare la reference alla MasterPage che la contiene per comunicare con un'altra ContentPage sorella:

ContentPage page = Master.GetContentPage("Page2");
page.PageData["Info"] = "MyData..."; // Eventuale passaggio di dati alla pagina
Master.ViewContentPage(page);

Technorati Tag: ,

Print | posted on giovedì 22 gennaio 2009 16:58 | Filed Under [ Silverlight ]

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET