Especificar a página mestra programaticamente (VB)
por Scott Mitchell
Examina a configuração da página mestra da página de conteúdo programaticamente por meio do manipulador de eventos PreInit.
Introdução
Desde o exemplo inaugural em Criando um layout em todo o site usando páginas mestras, todas as páginas de conteúdo referenciaram sua página mestra declarativamente por meio do MasterPageFile
atributo na @Page
diretiva. Por exemplo, a seguinte @Page
diretiva vincula a página de conteúdo à página Site.master
mestra:
<%@ Page Language="C#" MasterPageFile="~/Site.master"... %>
A classe no namespace inclui umaMasterPageFile
propriedade que retorna o caminho para a página mestra da página de conteúdo; é essa propriedade que é definida pela @Page
diretiva.System.Web.UI
Page
Essa propriedade também pode ser usada para especificar programaticamente a página mestra da página de conteúdo. Essa abordagem é útil se você quiser atribuir dinamicamente a página mestra com base em fatores externos, como o usuário que visita a página.
Neste tutorial, adicionamos uma segunda página mestra ao nosso site e decidimos dinamicamente qual página mestra usar no tempo de execução.
Etapa 1: uma olhada no ciclo de vida da página
Sempre que uma solicitação chega ao servidor Web para uma página ASP.NET que é uma página de conteúdo, o mecanismo de ASP.NET deve fundir os controles de conteúdo da página nos controles ContentPlaceHolder correspondentes da página mestra. Essa fusão cria uma única hierarquia de controle que pode prosseguir pelo ciclo de vida típico da página.
A Figura 1 ilustra essa fusão. A etapa 1 na Figura 1 mostra o conteúdo inicial e as hierarquias de controle de página mestra. No final do estágio PreInit, os controles de conteúdo na página são adicionados aos ContentPlaceHolders correspondentes na página mestra (Etapa 2). Após essa fusão, a página mestra serve como a raiz da hierarquia de controle fundida. Essa hierarquia de controle fundida é então adicionada à página para produzir a hierarquia de controle finalizada (Etapa 3). O resultado líquido é que a hierarquia de controle da página inclui a hierarquia de controle fundida.
Figura 01: As hierarquias de controle da página mestra e da página de conteúdo são fundidas durante o estágio de pré-inicialização (clique para exibir a imagem em tamanho real)
Etapa 2: Definindo aMasterPageFile
propriedade do código
A página mestra que participa dessa fusão depende do valor da Page
propriedade do MasterPageFile
objeto. Definir o MasterPageFile
atributo na @Page
diretiva tem o efeito líquido de atribuir a Page
propriedade do durante MasterPageFile
o estágio de inicialização, que é o primeiro estágio do ciclo de vida da página. Como alternativa, podemos definir essa propriedade programaticamente. No entanto, é imperativo que essa propriedade seja definida antes que a fusão na Figura 1 ocorra.
No início do estágio PreInit, o Page
objeto gera seu PreInit
evento e chama seu OnPreInit
método. Para definir a página mestra programaticamente, podemos criar um manipulador de eventos para o PreInit
evento ou substituir o OnPreInit
método. Vamos examinar as duas abordagens.
Comece abrindo Default.aspx.vb
o , o arquivo de classe code-behind para a página inicial do nosso site. Adicione um manipulador de eventos para o evento da PreInit
página digitando o seguinte código:
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
End Sub
A partir daqui, podemos definir a MasterPageFile
propriedade. Atualize o código para que ele atribua o valor "~/Site.master" à MasterPageFile
propriedade.
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
Me.MasterPageFile = "~/Site.master"
End Sub
Se você definir um ponto de interrupção e começar com a depuração, verá que sempre que a página for visitada Default.aspx
ou sempre que houver um postback para essa página, o Page_PreInit
manipulador de eventos será executado e a MasterPageFile
propriedade será atribuída a "~/Site.master".
Como alternativa, você pode substituir o Page
método da OnPreInit
classe e definir a MasterPageFile
propriedade lá. Para este exemplo, não vamos definir a página mestra em uma página específica, mas sim a partir de BasePage
. Lembre-se de que criamos uma classe de página base personalizada (BasePage
) no tutorial Especificando o título, as metatags e outros cabeçalhos HTML na página mestra. Atualmente BasePage
, substitui o Page
método da OnLoadComplete
classe, em que define a propriedade da Title
página com base nos dados do mapa do site. Vamos atualizar BasePage
para substituir também o OnPreInit
método para especificar programaticamente a página mestra.
Protected Overrides Sub OnPreInit(ByVal e As System.EventArgs)
Me.MasterPageFile = "~/Site.master"
MyBase.OnPreInit(e)
End Sub
Como todas as nossas páginas de conteúdo derivam de BasePage
, todas elas agora têm sua página mestra atribuída programaticamente. Neste ponto, o PreInit
manipulador de eventos é Default.aspx.vb
supérfluo; sinta-se à vontade para removê-lo.
E quanto à@Page
diretiva?
O que pode ser um pouco confuso é que as propriedades das MasterPageFile
páginas de conteúdo agora estão sendo especificadas em dois lugares: programaticamente no BasePage
método da OnPreInit
classe, bem como por meio do MasterPageFile
atributo na diretiva de cada página de @Page
conteúdo.
O primeiro estágio no ciclo de vida da página é o estágio de inicialização. Durante esse estágio, a Page
propriedade do MasterPageFile
objeto recebe o valor do MasterPageFile
atributo na @Page
diretiva (se for fornecido). O estágio PreInit segue o estágio Initialization e é aqui que definimos programaticamente a propriedade do Page
MasterPageFile
objeto, substituindo assim o valor atribuído pela @Page
diretiva. Como estamos definindo a Page
propriedade do MasterPageFile
objeto programaticamente, podemos remover o MasterPageFile
atributo da @Page
diretiva sem afetar a experiência do usuário final. Para se convencer disso, vá em frente e remova o MasterPageFile
@Page
atributo da diretiva e Default.aspx
visite a página por meio de um navegador. Como seria de esperar, a saída é a mesma de antes da remoção do atributo.
Se a MasterPageFile
propriedade é definida por meio da @Page
diretiva ou programaticamente, não é irrelevante para a experiência do usuário final. No entanto, o MasterPageFile
atributo na diretiva é usado pelo Visual Studio durante o @Page
tempo de design para produzir o modo de exibição WYSIWYG no Designer. Se você retornar ao Default.aspx
Visual Studio e navegar até o Designer, verá a mensagem "Erro de Página Mestra: a página tem controles que exigem uma referência de Página Mestra, mas nenhuma é especificada" (consulte a Figura 2).
Em resumo, você precisa deixar o MasterPageFile
atributo na @Page
diretiva para desfrutar de uma experiência avançada de tempo de design no Visual Studio.
@Page atributo MasterPageFile da diretiva para renderizar o modo de exibição de design" />
Figura 02: O Visual Studio usa o @Page
atributo da MasterPageFile
diretiva para renderizar o modo de exibição de design (clique para exibir a imagem em tamanho real)
Etapa 3: Criando uma página mestra alternativa
Como a página mestra de uma página de conteúdo pode ser definida programaticamente em runtime, é possível carregar dinamicamente uma página mestra específica com base em alguns critérios externos. Essa funcionalidade pode ser útil em situações em que o layout do site precisa variar de acordo com o usuário. Por exemplo, um aplicativo da Web do mecanismo de blog pode permitir que seus usuários escolham um layout para seu blog, onde cada layout está associado a uma página mestra diferente. Em tempo de execução, quando um visitante está exibindo o blog de um usuário, o aplicativo Web precisaria determinar o layout do blog e associar dinamicamente a página mestra correspondente à página de conteúdo.
Vamos examinar como carregar dinamicamente uma página mestra em tempo de execução com base em alguns critérios externos. Nosso site atualmente contém apenas uma página mestra (Site.master
). Precisamos de outra página mestra para ilustrar a escolha de uma página mestra em tempo de execução. Esta etapa se concentra na criação e configuração da nova página mestra. A etapa 4 examina como determinar qual página mestra usar em runtime.
Crie uma nova página mestra na pasta raiz chamada Alternate.master
. Adicione também uma nova folha de estilo ao site chamada AlternateStyles.css
.
Figura 03: Adicionar outra página mestra e arquivo CSS ao site (clique para exibir a imagem em tamanho real)
Eu projetei a Alternate.master
página mestra para que o título seja exibido na parte superior da página, centralizado e em um plano de fundo azul-marinho. Dispensei a coluna da esquerda e movi esse conteúdo para baixo do MainContent
controle ContentPlaceHolder, que agora abrange toda a largura da página. Além disso, eliminei a lista de lições não ordenada e a substituí por uma lista horizontal acima MainContent
. Também atualizei as fontes e cores usadas pela página mestra (e, por extensão, suas páginas de conteúdo). A Figura 4 mostra Default.aspx
ao usar a Alternate.master
página mestra.
Observação
ASP.NET inclui a capacidade de definir temas. Um Tema é uma coleção de imagens, arquivos CSS e configurações de propriedade de controle da Web relacionadas ao estilo que podem ser aplicadas a uma página em tempo de execução. Os temas são o caminho a percorrer se os layouts do seu site diferirem apenas nas imagens exibidas e por suas regras CSS. Se os layouts forem mais substancialmente diferentes, como usar controles Web diferentes ou ter um layout radicalmente diferente, você precisará usar páginas mestras separadas. Consulte a seção Leitura Adicional no final deste tutorial para obter mais informações sobre Temas.
Figura 04: Nossas páginas de conteúdo agora podem usar uma nova aparência (clique para exibir a imagem em tamanho real)
Quando a marcação das páginas mestra e de conteúdo é fundida, a MasterPage
classe verifica se cada controle de conteúdo na página de conteúdo faz referência a um ContentPlaceHolder na página mestra. Uma exceção será gerada se um controle de conteúdo que faz referência a um ContentPlaceHolder inexistente for encontrado. Em outras palavras, é imperativo que a página mestra que está sendo atribuída à página de conteúdo tenha um ContentPlaceHolder para cada controle de conteúdo na página de conteúdo.
A Site.master
página mestra inclui quatro controles ContentPlaceHolder:
head
MainContent
QuickLoginUI
LeftColumnContent
Algumas das páginas de conteúdo em nosso site incluem apenas um ou dois controles de conteúdo; outros incluem um controle de conteúdo para cada um dos ContentPlaceHolders disponíveis. Se nossa nova página mestra (Alternate.master
) puder ser atribuída às páginas de conteúdo que têm controles de conteúdo para todos os ContentPlaceHolders Site.master
, é essencial que Alternate.master
também inclua os mesmos controles Site.master
ContentPlaceHolder que .
Para que sua Alternate.master
página mestra seja semelhante à minha (consulte a AlternateStyles.css
Figura 4), comece definindo os estilos da página mestra na folha de estilos. Adicione as seguintes regras em 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;
}
Em seguida, adicione a seguinte marcação declarativa a Alternate.master
. Como você pode ver, Alternate.master
contém quatro controles ContentPlaceHolder com os mesmos ID
valores que os controles ContentPlaceHolder no Site.master
. Além disso, inclui um controle ScriptManager, que é necessário para as páginas do nosso site que usam a estrutura 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>
Testando a nova página mestra
Para testar essa nova página mestra, atualize o BasePage
método da OnPreInit
classe para que a MasterPageFile
propriedade receba o valor "~/Alternate.maser"
e, em seguida, visite o site. Todas as páginas devem funcionar sem erros, exceto duas: ~/Admin/AddProduct.aspx
e ~/Admin/Products.aspx
. Adicionar um produto ao DetailsView em resulta em ~/Admin/AddProduct.aspx
uma NullReferenceException
linha de código que tenta definir a propriedade da GridMessageText
página mestra. Ao visitar ~/Admin/Products.aspx
um InvalidCastException
é lançado no carregamento da página com a mensagem: "Não é possível converter o objeto do tipo 'ASP.alternate_master' para o tipo 'ASP.site_master'."
Esses erros ocorrem porque a Site.master
classe code-behind inclui eventos públicos, propriedades e métodos que não estão definidos no Alternate.master
. A parte de marcação dessas duas páginas tem uma @MasterType
diretiva que faz referência à Site.master
página mestra.
<%@ MasterType VirtualPath="~/Site.master" %>
Além disso, o manipulador de ItemInserted
eventos do DetailsView inclui ~/Admin/AddProduct.aspx
código que converte a propriedade de tipo Page.Master
flexível em um objeto do tipo Site
. A @MasterType
diretiva (usada dessa forma) e a conversão no ItemInserted
manipulador de eventos acoplam firmemente as ~/Admin/AddProduct.aspx
páginas e ~/Admin/Products.aspx
à Site.master
página mestra.
Para quebrar esse acoplamento rígido, podemos ter Site.master
e Alternate.master
derivar de uma classe base comum que contém definições para os membros públicos. Em seguida, podemos atualizar a @MasterType
diretiva para fazer referência a esse tipo de base comum.
Criando uma classe de página mestra base personalizada
Adicione um novo arquivo de classe à App_Code
pasta nomeada BaseMasterPage.vb
e faça com que ele derive de System.Web.UI.MasterPage
. Precisamos definir o RefreshRecentProductsGrid
método e a GridMessageText
propriedade em BaseMasterPage
, mas não podemos simplesmente movê-los para lá porque Site.master
esses membros trabalham com controles Web específicos da Site.master
página mestra (o GridView e GridMessage
o RecentProducts
Label).
O que precisamos fazer é configurar BaseMasterPage
de tal forma que esses membros sejam definidos lá, mas na verdade sejam implementados pelas BaseMasterPage
classesSite.master
derivadas de ( e Alternate.master
). Esse tipo de herança é possível marcando a classe como MustInherit
e seus membros como MustOverride
. Resumindo, adicionar essas palavras-chave à classe e seus dois membros anuncia que BaseMasterPage
não implementou RefreshRecentProductsGrid
e GridMessageText
, mas que suas classes derivadas o farão.
Também precisamos definir o PricesDoubled
evento e BaseMasterPage
fornecer um meio pelas classes derivadas para gerar o evento. O padrão usado no .NET Framework para facilitar esse comportamento é criar um evento público na classe base e adicionar um método protegido e substituível chamado OnEventName
. As classes derivadas podem chamar esse método para gerar o evento ou substituí-lo para executar o código imediatamente antes ou depois que o evento for gerado.
Atualize sua BaseMasterPage
classe para que ela contenha o seguinte código:
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
Em seguida, vá para a Site.master
classe code-behind e faça com que ela derive de BaseMasterPage
. Como BaseMasterPage
contém membros marcados MustOverride
, precisamos substituir esses membros aqui no Site.master
. Adicione a Overrides
palavra-chave às definições de método e propriedade. Atualize também o código que gera o PricesDoubled
evento no DoublePrice
manipulador de Click
eventos do Button com uma chamada para o método da OnPricesDoubled
classe base.
Após essas modificações, a Site.master
classe code-behind deve conter o seguinte código:
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
Também precisamos atualizar Alternate.master
a classe code-behind de para derivar BaseMasterPage
e substituir os dois MustOverride
membros. Mas como Alternate.master
não contém um GridView que lista os produtos mais recentes nem um Label que exibe uma mensagem depois que um novo produto é adicionado ao banco de dados, esses métodos não precisam fazer nada.
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
Referenciando a classe de página mestra base
Agora que concluímos a BaseMasterPage
aula e temos nossas duas páginas mestras estendendo-a, nossa etapa final é atualizar as ~/Admin/AddProduct.aspx
páginas e ~/Admin/Products.aspx
para se referir a esse tipo comum. Comece alterando a @MasterType
diretiva em ambas as páginas de:
<%@ MasterType VirtualPath="~/Site.master" %>
Para:
<%@ MasterType TypeName="BaseMasterPage" %>
Em vez de fazer referência a um caminho de arquivo, a @MasterType
propriedade agora faz referência ao tipo base (BaseMasterPage
). Conseqüentemente, a propriedade fortemente tipada Master
usada nas classes code-behind de ambas as páginas agora é do tipo BaseMasterPage
(em vez de tipo Site
). Com essa mudança de lugar, revisite ~/Admin/Products.aspx
. Anteriormente, isso resultava em um erro de conversão porque a página está configurada para usar a Alternate.master
página mestra, mas a @MasterType
diretiva fazia referência ao Site.master
arquivo. Mas agora a página é renderizada sem erros. Isso ocorre porque a Alternate.master
página mestra pode ser convertida em um objeto do tipo BaseMasterPage
(já que ela a estende).
Há uma pequena mudança que precisa ser feita no ~/Admin/AddProduct.aspx
. O manipulador de ItemInserted
eventos do controle DetailsView usa a propriedade fortemente tipada Master
e a propriedade de tipo Page.Master
flexível. Corrigimos a referência fortemente tipada quando atualizamos a @MasterType
diretiva, mas ainda precisamos atualizar a referência vagamente tipada. Substitua a seguinte linha de código:
Dim myMasterPage As Site = CType(Page.Master, Site)
Com o seguinte, que converte Page.Master
para o tipo base:
Dim myMasterPage As BaseMasterPage = CType(Page.Master, BaseMasterPage)
Etapa 4: Determinando qual página mestra vincular às páginas de conteúdo
Atualmente, nossa BasePage
classe define todas as propriedades das MasterPageFile
páginas de conteúdo como um valor embutido em código no estágio PreInit do ciclo de vida da página. Podemos atualizar esse código para basear a página mestra em algum fator externo. Talvez a página mestra a ser carregada dependa das preferências do usuário conectado no momento. Nesse caso, precisaríamos escrever código no OnPreInit
método BasePage
que pesquisa as preferências da página mestra do usuário que está visitando no momento.
Vamos criar uma página da Web que permita ao usuário escolher qual página mestra usar - Site.master
ou Alternate.master
- e salvar essa opção em uma variável Session. Comece criando uma nova página da Web no diretório raiz chamada ChooseMasterPage.aspx
. Ao criar esta página (ou qualquer outra página de conteúdo a partir de agora), você não precisa vinculá-la a uma página mestra porque a página mestra é definida programaticamente em BasePage
. No entanto, se você não vincular a nova página a uma página mestra, a marcação declarativa padrão da nova página conterá um formulário da Web e outros conteúdos fornecidos pela página mestra. Você precisará substituir manualmente essa marcação pelos controles de conteúdo apropriados. Por esse motivo, acho mais fácil vincular a nova página ASP.NET a uma página mestra.
Observação
Porque Site.master
e Alternate.master
ter o mesmo conjunto de controles ContentPlaceHolder, não importa qual página mestra você escolher ao criar a nova página de conteúdo. Para consistência, sugiro usar Site.master
.
Figura 05: Adicionar uma nova página de conteúdo ao site (clique para exibir a imagem em tamanho real)
Atualize o Web.sitemap
arquivo para incluir uma entrada para esta lição. Adicione a seguinte marcação abaixo da <siteMapNode>
lição para as Páginas Mestras e ASP.NET AJAX:
<siteMapNode url="~/ChooseMasterPage.aspx" title="Choose a Master Page" />
Antes de adicionar qualquer conteúdo à página, ChooseMasterPage.aspx
reserve um momento para atualizar a classe code-behind da página para que ela derive de (em vez de BasePage
System.Web.UI.Page
). Em seguida, adicione um controle DropDownList à página, defina sua ID
propriedade como MasterPageChoice
e adicione dois ListItems com os Text
valores de "~/Site.master" e "~/Alternate.master".
Adicione um controle Web de botão à página e defina suas ID
propriedades e Text
como SaveLayout
"Salvar opção de layout", respectivamente. Neste ponto, a marcação declarativa da sua página deve ser semelhante à seguinte:
<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 a página é visitada pela primeira vez, precisamos exibir a opção de página mestra selecionada pelo usuário no momento. Crie um manipulador de Page_Load
eventos e adicione o seguinte código:
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
O código acima é executado apenas na primeira visita à página (e não em postbacks subsequentes). Primeiro, ele verifica se a variável MyMasterPage
Session existe. Em caso afirmativo, ele tentará localizar o ListItem correspondente no MasterPageChoice
DropDownList. Se um ListItem correspondente for encontrado, sua Selected
propriedade será definida como True
.
Também precisamos de código que salve a escolha do usuário na MyMasterPage
variável Session. Crie um manipulador de Click
eventos para o SaveLayout
evento do Button e adicione o seguinte código:
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
Observação
No momento em que o Click
manipulador de eventos é executado no postback, a página mestra já foi selecionada. Portanto, a seleção da lista suspensa do usuário não estará em vigor até a próxima visita à página. Isso Response.Redirect
força o navegador a solicitar ChooseMasterPage.aspx
novamente .
Com a ChooseMasterPage.aspx
página concluída, nossa tarefa final é BasePage
atribuir a MasterPageFile
propriedade com base no valor da MyMasterPage
variável Session. Se a variável Session não estiver definida, o padrão Site.master
será BasePage
.
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
Observação
Mudei o código que atribui a Page
propriedade do MasterPageFile
objeto para fora do OnPreInit
manipulador de eventos e para dois métodos separados. Este primeiro método, SetMasterPageFile
, atribui a MasterPageFile
propriedade ao valor retornado pelo segundo método, GetMasterPageFileFromSession
. Marquei o método Overridable
para que as SetMasterPageFile
classes futuras que se estendem BasePage
possam opcionalmente substituí-lo para implementar a lógica personalizada, se necessário. Veremos um exemplo de substituição BasePage
da propriedade de no SetMasterPageFile
próximo tutorial.
Com esse código em vigor, visite a ChooseMasterPage.aspx
página. Inicialmente, a Site.master
página mestra é selecionada (consulte a Figura 6), mas o usuário pode escolher uma página mestra diferente na lista suspensa.
Figura 06: As páginas de conteúdo são exibidas usando a página mestra (clique para exibir a Site.master
imagem em tamanho real)
Figura 07: As páginas de conteúdo agora são exibidas usando a página mestra (clique para exibir a Alternate.master
imagem em tamanho real)
Resumo
Quando uma página de conteúdo é visitada, seus controles de conteúdo são fundidos com os controles ContentPlaceHolder da página mestra. A página mestra da página de conteúdo é indicada pela Page
propriedade da MasterPageFile
classe, que é atribuída ao @Page
atributo da MasterPageFile
diretiva durante o estágio de inicialização. Como este tutorial mostrou, podemos atribuir um valor à MasterPageFile
propriedade, desde que o façamos antes do final do estágio PreInit. Ser capaz de especificar programaticamente a página mestra abre a porta para cenários mais avançados, como associar dinamicamente uma página de conteúdo a uma página mestra com base em fatores externos.
Boa programação!
Leitura Adicional
Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos:
- Visão geral do ciclo de vida da página ASP.NET
- Visão geral dos temas e skins do ASP.NET
- Páginas mestras: dicas, truques e armadilhas
- Temas em ASP.NET
Sobre o autor
Scott Mitchell, autor de vários livros ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Web da Microsoft desde 1998. Scott trabalha como consultor, instrutor e escritor independente. Seu último livro é Sams Teach Yourself ASP.NET 3.5 em 24 horas. Scott pode ser contatado em mitchell@4GuysFromRolla.com ou através de seu blog em http://ScottOnWriting.NET.
Agradecimentos especiais a
Esta série de tutoriais foi revisada por muitos revisores úteis. O revisor principal deste tutorial foi Suchi Banerjee. Interessado em revisar meus próximos artigos do MSDN? Se sim, me mande uma mensagem em mitchell@4GuysFromRolla.com