Impostazione della pagina master a livello di codice (VB)
Esamina l'impostazione della pagina master della pagina del contenuto a livello di codice tramite il gestore eventi PreInit.
Introduzione
Poiché l'esempio inaugurale in Creazione di un layout a livello di sito tramite pagine master, tutte le pagine del contenuto hanno fatto riferimento dichiarativo alla relativa pagina master tramite l'attributo MasterPageFile
nella @Page
direttiva . Ad esempio, la direttiva seguente @Page
collega la pagina del contenuto alla pagina Site.master
master :
<%@ Page Language="C#" MasterPageFile="~/Site.master"... %>
La classe nello spazio dei System.Web.UI
nomi include una MasterPageFile
proprietà che restituisce il percorso alla pagina master della pagina del contenuto. Si tratta di questa proprietà impostata dalla @Page
direttiva .Page
Questa proprietà può essere utilizzata anche per specificare a livello di codice la pagina master della pagina del contenuto. Questo approccio è utile se si vuole assegnare dinamicamente la pagina master in base a fattori esterni, ad esempio l'utente che visita la pagina.
In questa esercitazione viene aggiunta una seconda pagina master al sito Web e si decide in modo dinamico quale pagina master usare in fase di esecuzione.
Passaggio 1: Esaminare il ciclo di vita della pagina
Ogni volta che una richiesta arriva al server Web per una pagina ASP.NET che è una pagina di contenuto, il motore di ASP.NET deve unire i controlli Contenuto della pagina nei controlli ContentPlaceHolder corrispondenti della pagina master. Questa fusione crea una singola gerarchia di controlli che può quindi procedere nel ciclo di vita tipico della pagina.
La figura 1 illustra questa fusione. Il passaggio 1 nella figura 1 mostra le gerarchie iniziali di contenuto e controllo pagina master. Alla fine finale della fase PreInit i controlli Contenuto nella pagina vengono aggiunti ai ContentPlaceHolders corrispondenti nella pagina master (passaggio 2). Dopo questa fusione, la pagina master funge da radice della gerarchia dei controlli fusi. Questa gerarchia di controlli fusi viene quindi aggiunta alla pagina per produrre la gerarchia dei controlli finali (passaggio 3). Il risultato netto è che la gerarchia di controllo della pagina include la gerarchia dei controlli fusi.
Figura 01: Le gerarchie di controllo della pagina master e della pagina del contenuto vengono unite insieme durante la fase PreInit (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 2: Impostazione dellaMasterPageFile
proprietà dal codice
Il contenuto della pagina master in questa fusione dipende dal valore della Page
proprietà dell'oggetto MasterPageFile
. L'impostazione dell'attributo nella @Page
direttiva ha l'effetto MasterPageFile
netto dell'assegnazione Page
della proprietà della MasterPageFile
proprietà durante la fase di inizializzazione, che è la prima fase del ciclo di vita della pagina. In alternativa, è possibile impostare questa proprietà a livello di codice. Tuttavia, è fondamentale che questa proprietà venga impostata prima che venga eseguita la fusione nella figura 1.
All'inizio della fase PreInit l'oggetto genera l'evento Page
PreInit
e chiama il relativo OnPreInit
metodo. Per impostare la pagina master a livello di codice, è possibile creare un gestore eventi per l'evento o eseguire l'override PreInit
del OnPreInit
metodo . Di seguito vengono esaminati entrambi gli approcci.
Per iniziare, aprire Default.aspx.vb
, il file di classe code-behind per la home page del sito. Aggiungere un gestore eventi per l'evento della PreInit
pagina digitando il codice seguente:
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
End Sub
Da qui è possibile impostare la MasterPageFile
proprietà . Aggiornare il codice in modo che assegni il valore "~/Site.master" alla MasterPageFile
proprietà .
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
Me.MasterPageFile = "~/Site.master"
End Sub
Se si imposta un punto di interruzione e si inizia con il debug, si noterà che ogni volta che la Default.aspx
pagina viene visitata o ogni volta che è presente un postback a questa pagina, il Page_PreInit
gestore eventi viene eseguito e la MasterPageFile
proprietà viene assegnata a "~/Site.master".
In alternativa, è possibile eseguire l'override del Page
metodo della OnPreInit
classe e impostare la MasterPageFile
proprietà. Per questo esempio, non impostiamo la pagina master in una determinata pagina, ma piuttosto da BasePage
. Tenere presente che è stata creata una classe di pagina di base personalizzata (BasePage
) nell'esercitazione Specifica del titolo, dei meta tag e di altre intestazioni HTML nell'esercitazione sulla pagina master. Attualmente BasePage
esegue l'override del Page
metodo della OnLoadComplete
classe, in cui imposta la proprietà della Title
pagina in base ai dati della mappa del sito. Si aggiornerà BasePage
per eseguire anche l'override del OnPreInit
metodo per specificare la pagina master a livello di codice.
Protected Overrides Sub OnPreInit(ByVal e As System.EventArgs)
Me.MasterPageFile = "~/Site.master"
MyBase.OnPreInit(e)
End Sub
Poiché tutte le pagine di contenuto derivano da BasePage
, tutte hanno ora la relativa pagina master assegnata a livello di codice. A questo punto il PreInit
gestore eventi in Default.aspx.vb
è superfluo. È possibile rimuoverlo.
Che ne dici della@Page
direttiva?
Ciò che può essere poco chiaro è che le proprietà delle pagine del MasterPageFile
contenuto vengono ora specificate in due posizioni: a livello di codice nel BasePage
metodo della OnPreInit
classe e tramite l'attributo MasterPageFile
nella direttiva di ogni pagina del @Page
contenuto.
La prima fase del ciclo di vita della pagina è la fase di inizializzazione. Durante questa fase alla Page
proprietà dell'oggetto MasterPageFile
viene assegnato il valore dell'attributo MasterPageFile
nella @Page
direttiva (se specificato). La fase PreInit segue la fase di inizializzazione ed è qui che impostiamo a livello di codice la Page
proprietà dell'oggetto MasterPageFile
, sovrascrivendo così il valore assegnato dalla @Page
direttiva. Poiché si imposta la Page
proprietà dell'oggetto a livello di MasterPageFile
codice, è possibile rimuovere l'attributo MasterPageFile
dalla @Page
direttiva senza influire sull'esperienza dell'utente finale. Per convincersi di questo, procedere e rimuovere l'attributo MasterPageFile
dalla @Page
direttiva in Default.aspx
e quindi visitare la pagina tramite un browser. Come previsto, l'output è uguale a quello precedente alla rimozione dell'attributo.
Se la MasterPageFile
proprietà viene impostata tramite la @Page
direttiva o a livello di codice è inconsequential all'esperienza dell'utente finale. Tuttavia, l'attributo MasterPageFile
nella direttiva viene usato da Visual Studio durante la @Page
fase di progettazione per produrre la visualizzazione WYSIWYG nella finestra di progettazione. Se si torna a Default.aspx
in Visual Studio e si passa alla finestra di progettazione verrà visualizzato il messaggio "Errore pagina master: la pagina contiene controlli che richiedono un riferimento alla pagina master, ma non è specificato nessuno" (vedere la figura 2).
In breve, è necessario lasciare l'attributo MasterPageFile
nella @Page
direttiva per godere di un'esperienza di progettazione avanzata in Visual Studio.
Figura 02: Visual Studio usa l'attributo @Page
della MasterPageFile
direttiva per eseguire il rendering della visualizzazione struttura (fare clic per visualizzare l'immagine a dimensione intera)
Passaggio 3: Creazione di una pagina master alternativa
Poiché la pagina master di una pagina del contenuto può essere impostata a livello di codice in fase di esecuzione, è possibile caricare dinamicamente una determinata pagina master in base ad alcuni criteri esterni. Questa funzionalità può essere utile nelle situazioni in cui il layout del sito deve variare in base all'utente. Ad esempio, un'applicazione Web del motore di blog può consentire agli utenti di scegliere un layout per il blog, in cui ogni layout è associato a una pagina master diversa. In fase di esecuzione, quando un visitatore visualizza il blog di un utente, l'applicazione Web dovrà determinare il layout del blog e associare dinamicamente la pagina master corrispondente alla pagina del contenuto.
Si esaminerà ora come caricare dinamicamente una pagina master in fase di esecuzione in base ad alcuni criteri esterni. Il nostro sito web contiene attualmente solo una pagina master (Site.master
). È necessaria un'altra pagina master per illustrare la scelta di una pagina master in fase di esecuzione. Questo passaggio è incentrato sulla creazione e la configurazione della nuova pagina master. Il passaggio 4 esamina la determinazione della pagina master da usare in fase di esecuzione.
Creare una nuova pagina master nella cartella radice denominata Alternate.master
. Aggiungere anche un nuovo foglio di stile al sito Web denominato AlternateStyles.css
.
Figura 03: Aggiungere un'altra pagina master e un altro file CSS al sito Web (fare clic per visualizzare l'immagine a dimensione intera)
Ho progettato la Alternate.master
pagina master per visualizzare il titolo nella parte superiore della pagina, centrato e su uno sfondo navy. Ho erogato la colonna sinistra e spostato il contenuto sotto il MainContent
controllo ContentPlaceHolder, che ora si estende sull'intera larghezza della pagina. Inoltre, ho nixed nixed Lessons list e sostituito con un elenco orizzontale sopra MainContent
. Ho anche aggiornato i tipi di carattere e i colori usati dalla pagina master (e, per estensione, le relative pagine di contenuto). La figura 4 mostra quando Default.aspx
si usa la Alternate.master
pagina master.
Nota
ASP.NET include la possibilità di definire i temi. Un tema è una raccolta di immagini, file CSS e impostazioni delle proprietà del controllo Web correlate allo stile che possono essere applicate a una pagina in fase di esecuzione. I temi sono il modo per procedere se i layout del sito differiscono solo nelle immagini visualizzate e nelle relative regole CSS. Se i layout differiscono in modo più sostanziale, ad esempio usando controlli Web diversi o con un layout radicalmente diverso, sarà necessario usare pagine master separate. Per altre informazioni sui temi, vedere la sezione Altre informazioni sulla lettura alla fine di questa esercitazione.
Figura 04: Le pagine di contenuto possono ora usare un nuovo aspetto (fare clic per visualizzare un'immagine a dimensione intera)
Quando il markup delle pagine master e del contenuto viene fuso, la MasterPage
classe verifica che ogni controllo Contenuto nella pagina del contenuto faccia riferimento a contentPlaceHolder nella pagina master. Viene generata un'eccezione se viene trovato un controllo Content che fa riferimento a un ContentPlaceHolder inesistente. In altre parole, è fondamentale che la pagina master assegnata alla pagina del contenuto abbia un ContentPlaceHolder per ogni controllo Contenuto nella pagina contenuto.
La Site.master
pagina master include quattro controlli ContentPlaceHolder:
head
MainContent
QuickLoginUI
LeftColumnContent
Alcune delle pagine di contenuto nel nostro sito web includono solo uno o due controlli Contenuto; altri includono un controllo Contenuto per ognuno dei ContentPlaceHolders disponibili. Se la nuova pagina master (Alternate.master
) può essere assegnata a tali pagine di contenuto con controlli Contenuto per tutti i ContentPlaceHolders in Site.master
, è essenziale includere Alternate.master
anche gli stessi controlli ContentPlaceHolder di Site.master
.
Per ottenere l'aspetto Alternate.master
della pagina master simile al mio (vedere la figura 4), iniziare definendo gli stili della pagina master nel AlternateStyles.css
foglio di stile. Aggiungere le regole seguenti in AlternateStyles.css
:
body
{
font-family: Comic Sans MS, Arial;
font-size: medium;
margin: 0px;
}
#topContent
{
text-align: center;
background-color: Navy;
color: White;
font-size: x-large;
text-decoration: none;
font-weight: bold;
padding: 10px;
height: 50px;
}
#topContent a
{
text-decoration: none;
color: White;
}
#navContent
{
font-size: small;
text-align: center;
}
#footerContent
{
padding: 10px;
font-size: 90%;
text-align: center;
border-top: solid 1px black;
}
#mainContent
{
text-align: left;
padding: 10px;
}
Aggiungere quindi il markup dichiarativo seguente a Alternate.master
. Come si può notare, Alternate.master
contiene quattro controlli ContentPlaceHolder con gli stessi ID
valori dei controlli ContentPlaceHolder in Site.master
. Inoltre, include un controllo ScriptManager, che è necessario per tali pagine nel nostro sito Web che usano il framework ASP.NET AJAX.
<!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 id="Head1" runat="server">
<title>Untitled Page</title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
<link href="AlternateStyles.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="MyManager" runat="server">
</asp:ScriptManager>
<div id="topContent">
<asp:HyperLink ID="lnkHome" runat="server" NavigateUrl="~/Default.aspx"
Text="Master Pages Tutorials" />
</div>
<div id="navContent">
<asp:ListView ID="LessonsList" runat="server"
DataSourceID="LessonsDataSource">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</LayoutTemplate>
<ItemTemplate>
<asp:HyperLink runat="server" ID="lnkLesson"
NavigateUrl='<%# Eval("Url") %>'
Text='<%# Eval("Title") %>' />
</ItemTemplate>
<ItemSeparatorTemplate> | </ItemSeparatorTemplate>
</asp:ListView>
<asp:SiteMapDataSource ID="LessonsDataSource" runat="server"
ShowStartingNode="false" />
</div>
<div id="mainContent">
<asp:ContentPlaceHolder id="MainContent" runat="server">
</asp:ContentPlaceHolder>
</div>
<div id="footerContent">
<p>
<asp:Label ID="DateDisplay" runat="server"></asp:Label>
</p>
<asp:ContentPlaceHolder ID="QuickLoginUI" runat="server">
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="LeftColumnContent" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
Test della nuova pagina master
Per testare questa nuova pagina master, aggiornare il BasePage
metodo della OnPreInit
classe in modo che alla MasterPageFile
proprietà venga assegnato il valore "~/Alternate.maser"
e quindi visitare il sito Web. Ogni pagina deve funzionare senza errori, ad eccezione di due: ~/Admin/AddProduct.aspx
e ~/Admin/Products.aspx
. L'aggiunta di un prodotto a DetailsView in ~/Admin/AddProduct.aspx
restituisce un NullReferenceException
oggetto dalla riga di codice che tenta di impostare la proprietà della GridMessageText
pagina master. Quando si visita ~/Admin/Products.aspx
un oggetto InvalidCastException
viene generato al caricamento della pagina con il messaggio : "Impossibile eseguire il cast dell'oggetto di tipo "ASP.alternate_master" per digitare "ASP.site_master".
Questi errori si verificano perché la Site.master
classe code-behind include eventi, proprietà e metodi pubblici non definiti in Alternate.master
. La parte di markup di queste due pagine ha una @MasterType
direttiva che fa riferimento alla Site.master
pagina master.
<%@ MasterType VirtualPath="~/Site.master" %>
Inoltre, il gestore eventi di ItemInserted
DetailsView in ~/Admin/AddProduct.aspx
include il codice che esegue il cast della proprietà di Page.Master
tipo libero a un oggetto di tipo Site
. La @MasterType
direttiva (usata in questo modo) e il cast nel ItemInserted
gestore eventi associa strettamente le ~/Admin/AddProduct.aspx
pagine e ~/Admin/Products.aspx
alla Site.master
pagina master.
Per interrompere questo accoppiamento stretto, è possibile avere Site.master
e Alternate.master
derivare da una classe base comune che contiene definizioni per i membri pubblici. In seguito, è possibile aggiornare la @MasterType
direttiva per fare riferimento a questo tipo di base comune.
Creazione di una classe di pagina master di base personalizzata
Aggiungere un nuovo file di classe alla App_Code
cartella denominata BaseMasterPage.vb
e derivarlo da System.Web.UI.MasterPage
. È necessario definire il RefreshRecentProductsGrid
metodo e la GridMessageText
proprietà in BaseMasterPage
, ma non è possibile spostarli da Site.master
perché questi membri funzionano con i controlli Web specifici della Site.master
pagina master ( RecentProducts
GridView e GridMessage
Label).
Ciò che è necessario fare è configurare BaseMasterPage
in modo che questi membri siano definiti in tale posizione, ma vengono effettivamente implementati dalle BaseMasterPage
classi derivate (Site.master
e Alternate.master
). Questo tipo di ereditarietà è possibile contrassegnando la classe come MustInherit
e i relativi membri come MustOverride
. In breve, l'aggiunta di queste parole chiave alla classe e i suoi due membri annuncia che BaseMasterPage
non ha implementato RefreshRecentProductsGrid
e GridMessageText
, ma che le classi derivate lo faranno.
È anche necessario definire l'evento PricesDoubled
in BaseMasterPage
e fornire un mezzo dalle classi derivate per generare l'evento. Il modello usato in .NET Framework per facilitare questo comportamento consiste nel creare un evento pubblico nella classe di base e aggiungere un metodo protetto e sottoponibile a override denominato OnEventName
. Le classi derivate possono quindi chiamare questo metodo per generare l'evento o eseguirne l'override per eseguire il codice immediatamente prima o dopo la generazione dell'evento.
Aggiornare la BaseMasterPage
classe in modo che contenga il codice seguente:
Public MustInherit Class BaseMasterPage
Inherits System.Web.UI.MasterPage
Public Event PricesDoubled As EventHandler
Protected Overridable Sub OnPricesDoubled(ByVal e As EventArgs)
RaiseEvent PricesDoubled(Me, e)
End Sub
Public MustOverride Sub RefreshRecentProductsGrid()
Public MustOverride Property GridMessageText() As String
End Class
Passare quindi alla Site.master
classe code-behind e fare in modo che derivi da BaseMasterPage
. Poiché BaseMasterPage
contiene membri contrassegnati MustOverride
come è necessario eseguire l'override di tali membri qui in Site.master
. Aggiungere la Overrides
parola chiave alle definizioni di metodo e proprietà. Aggiornare anche il codice che genera l'evento PricesDoubled
nel DoublePrice
gestore eventi del Click
pulsante con una chiamata al metodo della classe di OnPricesDoubled
base.
Dopo queste modifiche, la Site.master
classe code-behind deve contenere il codice seguente:
Partial Class Site
Inherits BaseMasterPage
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
DateDisplay.Text = DateTime.Now.ToString("dddd, MMMM dd")
End Sub
Public Overrides Sub RefreshRecentProductsGrid()
RecentProducts.DataBind()
End Sub
Public Overrides Property GridMessageText() As String
Get
Return GridMessage.Text
End Get
Set(ByVal Value As String)
GridMessage.Text = Value
End Set
End Property
Protected Sub DoublePrice_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DoublePrice.Click
' Double the prices
DoublePricesDataSource.Update()
' Refresh RecentProducts
RecentProducts.DataBind()
' Raise the PricesDoubled event
MyBase.OnPricesDoubled(EventArgs.Empty)
End Sub
End Class
È anche necessario aggiornare Alternate.master
la classe code-behind per derivare ed BaseMasterPage
eseguire l'override dei due MustOverride
membri. Tuttavia, poiché Alternate.master
non contiene un controllo GridView che elenca i prodotti più recenti né un'etichetta che visualizza un messaggio dopo l'aggiunta di un nuovo prodotto al database, questi metodi non devono eseguire alcuna operazione.
Partial Class Alternate
Inherits BaseMasterPage
Public Overrides Property GridMessageText() As String
Get
Return String.Empty
End Get
Set(ByVal value As String)
' Do nothing
End Set
End Property
Public Overrides Sub RefreshRecentProductsGrid()
' Do nothing
End Sub
End Class
Riferimento alla classe di pagina master di base
Dopo aver completato la BaseMasterPage
classe e aver esteso le due pagine master, il passaggio finale consiste nell'aggiornare le ~/Admin/AddProduct.aspx
pagine e ~/Admin/Products.aspx
per fare riferimento a questo tipo comune. Iniziare modificando la direttiva in entrambe le @MasterType
pagine da:
<%@ MasterType VirtualPath="~/Site.master" %>
Con:
<%@ MasterType TypeName="BaseMasterPage" %>
Anziché fare riferimento a un percorso di file, la @MasterType
proprietà fa ora riferimento al tipo di base (BaseMasterPage
). Di conseguenza, la proprietà fortemente tipizzata Master
usata nelle classi code-behind di entrambe le pagine è ora di tipo (anziché di tipo Site
BaseMasterPage
). Con questa modifica sul posto rivedere ~/Admin/Products.aspx
. In precedenza, si è verificato un errore di cast perché la pagina è configurata per l'uso della Alternate.master
pagina master, ma la @MasterType
direttiva ha fatto riferimento al Site.master
file. Ma ora viene eseguito il rendering della pagina senza errori. Ciò è dovuto al fatto che è possibile eseguire il cast della Alternate.master
pagina master a un oggetto di tipo BaseMasterPage
(dal momento che lo estende).
C'è una piccola modifica che deve essere apportata in ~/Admin/AddProduct.aspx
. Il gestore eventi del ItemInserted
controllo DetailsView usa sia la proprietà fortemente tipizzata Master
che la proprietà di tipo Page.Master
libero. È stato corretto il riferimento fortemente tipizzato quando è stata aggiornata la @MasterType
direttiva, ma è comunque necessario aggiornare il riferimento con tipizzato libero. Sostituire la riga di codice seguente:
Dim myMasterPage As Site = CType(Page.Master, Site)
Con il comando seguente, che esegue il cast Page.Master
al tipo di base:
Dim myMasterPage As BaseMasterPage = CType(Page.Master, BaseMasterPage)
Passaggio 4: Determinazione della pagina master da associare alle pagine del contenuto
La BasePage
classe imposta attualmente tutte le proprietà delle pagine di MasterPageFile
contenuto su un valore hardcoded nella fase PreInit del ciclo di vita della pagina. È possibile aggiornare questo codice per basare la pagina master su un fattore esterno. La pagina master da caricare dipende forse dalle preferenze dell'utente attualmente connesso. In questo caso, è necessario scrivere codice nel OnPreInit
metodo in BasePage
che cerca le preferenze della pagina master dell'utente attualmente in visita.
Si creerà una pagina Web che consente all'utente di scegliere la pagina master da usare Site.master
oppure Alternate.master
e salvare questa scelta in una variabile di sessione. Per iniziare, creare una nuova pagina Web nella directory radice denominata ChooseMasterPage.aspx
. Quando si crea questa pagina (o qualsiasi altra pagina di contenuto) non è necessario associarla a una pagina master perché la pagina master è impostata a livello di codice in BasePage
. Tuttavia, se non si associa la nuova pagina a una pagina master, il markup dichiarativo predefinito della nuova pagina contiene un Web Form e altri contenuti forniti dalla pagina master. Dovrai sostituire manualmente questo markup con i controlli Contenuto appropriati. Per questo motivo, trovo più facile associare la nuova pagina ASP.NET a una pagina master.
Nota
Poiché Site.master
e Alternate.master
hanno lo stesso set di controlli ContentPlaceHolder, non è importante quale pagina master si sceglie durante la creazione della nuova pagina di contenuto. Per coerenza, è consigliabile usare Site.master
.
Figura 05: Aggiungere una nuova pagina contenuto al sito Web (fare clic per visualizzare l'immagine a dimensione intera)
Aggiornare il Web.sitemap
file in modo da includere una voce per questa lezione. Aggiungere il markup seguente sotto per <siteMapNode>
le pagine master e ASP.NET lezione AJAX:
<siteMapNode url="~/ChooseMasterPage.aspx" title="Choose a Master Page" />
Prima di aggiungere contenuto alla ChooseMasterPage.aspx
pagina, è necessario un attimo per aggiornare la classe code-behind della pagina in modo che derivi da (anziché System.Web.UI.Page
).BasePage
Aggiungere quindi un controllo DropDownList alla pagina, impostarne la ID
proprietà su MasterPageChoice
e aggiungere due elementi ListItem con i Text
valori di "~/Site.master" e "~/Alternate.master".
Aggiungere un controllo Web Button alla pagina e impostarne ID
le proprietà e Text
rispettivamente su SaveLayout
e "Save Layout Choice". A questo punto il markup dichiarativo della pagina dovrebbe essere simile al seguente:
<p>
Your layout choice:
<asp:DropDownList ID="MasterPageChoice" runat="server">
<asp:ListItem>~/Site.master</asp:ListItem>
<asp:ListItem>~/Alternate.master</asp:ListItem>
</asp:DropDownList>
</p>
<p>
<asp:Button ID="SaveLayout" runat="server" Text="Save Layout Choice" />
</p>
Quando la pagina viene visitata per la prima volta, è necessario visualizzare la scelta della pagina master attualmente selezionata dall'utente. Creare un Page_Load
gestore eventi e aggiungere il codice seguente:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
If Session("MyMasterPage") IsNot Nothing Then
Dim li As ListItem = MasterPageChoice.Items.FindByText(Session("MyMasterPage").ToString())
If li IsNot Nothing Then
li.Selected = True
End If
End If
End If
End Sub
Il codice precedente viene eseguito solo nella prima pagina visita (e non nei postback successivi). Controlla prima di tutto se la variabile MyMasterPage
Session esiste. In caso affermativo, tenta di trovare l'oggetto ListItem corrispondente nell'elenco MasterPageChoice
a discesa. Se viene trovato un oggetto ListItem corrispondente, la relativa Selected
proprietà viene impostata su True
.
È necessario anche il codice che salva la scelta dell'utente nella MyMasterPage
variabile Session. Creare un gestore eventi per l'evento SaveLayout
button Click
e aggiungere il codice seguente:
Protected Sub SaveLayout_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SaveLayout.Click
Session("MyMasterPage") = MasterPageChoice.SelectedValue
Response.Redirect("ChooseMasterPage.aspx")
End Sub
Nota
Al momento dell'esecuzione del Click
gestore eventi al postback, la pagina master è già stata selezionata. Pertanto, la selezione dell'elenco a discesa dell'utente non sarà attiva fino alla visita della pagina successiva. Forza Response.Redirect
il browser a richiedere ChooseMasterPage.aspx
nuovamente .
Al termine della pagina, l'attività ChooseMasterPage.aspx
finale consiste nell'assegnare BasePage
la MasterPageFile
proprietà in base al valore della MyMasterPage
variabile Session. Se la variabile Session non è impostata per BasePage
impostazione predefinita su Site.master
.
Protected Overrides Sub OnPreInit(ByVal e As System.EventArgs)
SetMasterPageFile()
MyBase.OnPreInit(e)
End Sub
Protected Overridable Sub SetMasterPageFile()
Me.MasterPageFile = GetMasterPageFileFromSession()
End Sub
Protected Function GetMasterPageFileFromSession() As String
If Session("MyMasterPage") Is Nothing Then
Return "~/Site.master"
Else
Return Session("MyMasterPage").ToString()
End If
End Function
Nota
Il codice che assegna la Page
proprietà dell'oggetto MasterPageFile
al gestore eventi OnPreInit
è stato spostato in due metodi separati. Questo primo metodo, SetMasterPageFile
, assegna la MasterPageFile
proprietà al valore restituito dal secondo metodo, GetMasterPageFileFromSession
. Il metodo Overridable
è stato contrassegnato SetMasterPageFile
in modo che le classi future che si estendono BasePage
possano eseguire facoltativamente l'override per implementare la logica personalizzata, se necessario. Nell'esercitazione successiva verrà illustrato un esempio di override BasePage
della proprietà di SetMasterPageFile
.
Con questo codice sul posto, visitare la ChooseMasterPage.aspx
pagina. Inizialmente, la Site.master
pagina master è selezionata (vedere la figura 6), ma l'utente può selezionare una pagina master diversa dall'elenco a discesa.
Figura 06: Le pagine del contenuto vengono visualizzate utilizzando la pagina master (fare clic per visualizzare l'immagine Site.master
a dimensione intera)
Figura 07: Le pagine del contenuto sono ora visualizzate usando la pagina master (fare clic per visualizzare l'immagine Alternate.master
a dimensione intera)
Riepilogo
Quando viene visitata una pagina di contenuto, i controlli Contenuto vengono fusi con i controlli ContentPlaceHolder della pagina master. La pagina master della pagina del contenuto è indicata dalla Page
proprietà della MasterPageFile
classe, assegnata all'attributo della direttiva durante la @Page
fase di MasterPageFile
inizializzazione. Come illustrato in questa esercitazione, è possibile assegnare un valore alla proprietà purché MasterPageFile
lo si verifichi prima della fine della fase PreInit. La possibilità di specificare a livello di codice la pagina master apre la porta per scenari più avanzati, ad esempio l'associazione dinamica di una pagina di contenuto a una pagina master in base a fattori esterni.
Buon programmatori!
Altre informazioni
Per altre informazioni sugli argomenti illustrati in questa esercitazione, vedere le risorse seguenti:
- Panoramica del ciclo di vita della pagina ASP.NET
- Panoramica dei temi e delle interfacce di ASP.NET
- Pagine master: suggerimenti, trucchi e trappole
- Temi in ASP.NET
Informazioni sull'autore
Scott Mitchell, autore di più libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Web Microsoft dal 1998. Scott lavora come consulente indipendente, formatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 3.5 in 24 ore. Scott può essere raggiunto all'indirizzo mitchell@4GuysFromRolla.com o tramite il suo blog all'indirizzo http://ScottOnWriting.NET.
Grazie speciale a
Questa serie di esercitazioni è stata esaminata da molti revisori utili. Il revisore principale per questa esercitazione era Suchi Banerjee. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, lasciami una riga in mitchell@4GuysFromRolla.com