Especificar a página mestra programaticamente (C#)
por Scott Mitchell
Analisa a configuração da página de master de conteúdo programaticamente por meio do manipulador de eventos PreInit.
Introdução
Desde o exemplo inaugural em Criando um layout de Site-Wide usando páginas mestras, todas as páginas de conteúdo referenciaram seus master página declarativamente por meio do MasterPageFile
atributo na @Page
diretiva . Por exemplo, a diretiva a seguir @Page
vincula a página de conteúdo à página Site.master
master :
<%@ Page Language="C#" MasterPageFile="~/Site.master" ... %>
A Page
classe no System.Web.UI
namespace inclui uma MasterPageFile
propriedade que retorna o caminho para a página master da página de conteúdo; é essa propriedade definida pela @Page
diretiva . Essa propriedade também pode ser usada para especificar programaticamente a página master da página de conteúdo. Essa abordagem será útil se você quiser atribuir dinamicamente a página master com base em fatores externos, como o usuário que visita a página.
Neste tutorial, adicionamos uma segunda página master ao nosso site e decidimos dinamicamente qual master página usar em runtime.
Etapa 1: Uma olhada no ciclo de vida da página
Sempre que uma solicitação chega ao servidor Web para uma página de 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 master. Essa fusão cria uma hierarquia de controle único 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 master hierarquias de controle de página. No final do estágio PreInit, os controles de conteúdo na página são adicionados ao ContentPlaceHolders correspondente na página master (Etapa 2). Após essa fusão, a página master 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 juntas durante o estágio PreInit (clique para exibir a imagem em tamanho real)
Etapa 2: Definindo a propriedade doMasterPageFile
código
O que master página 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 durante MasterPageFile
o estágio 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 da fusão na Figura 1 ocorrer.
No início do estágio PreInit, o Page
objeto aciona seu PreInit
evento e chama seu OnPreInit
método. Para definir a página master 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.cs
, o arquivo de classe code-behind para a home page do nosso site. Adicione um manipulador de eventos para o evento da PreInit
página digitando no seguinte código:
protected void Page_PreInit(object sender, EventArgs e)
{
}
A partir daqui, podemos definir a MasterPageFile
propriedade . Atualize o código para que ele atribua o valor "~/Site. master" para a MasterPageFile
propriedade .
protected void Page_PreInit(object sender, EventArgs e)
{
this.MasterPageFile = "~/Site.master";
}
Se você definir um ponto de interrupção e começar com a depuração, verá que sempre que a Default.aspx
página for visitada ou sempre que houver um postback nessa 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 master em uma página específica, mas sim de BasePage
. Lembre-se de que criamos uma classe de página base personalizada (BasePage
) novamente no tutorial Especificando o título, metamaras 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 também substituir o OnPreInit
método para especificar programaticamente a página master.
protected override void OnPreInit(EventArgs e)
{
this.MasterPageFile = "~/Site.master";
base.OnPreInit(e);
}
Como todas as nossas páginas de conteúdo derivam de BasePage
, todas elas agora têm sua página master atribuída programaticamente. Neste ponto, o PreInit
manipulador de eventos em Default.aspx.cs
é supérfluo; fique à vontade para removê-lo.
E a@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 locais: 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 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 inicialização e é aqui que definimos programaticamente a Page
propriedade do MasterPageFile
objeto, substituindo assim o valor atribuído da @Page
diretiva . Como estamos definindo a Page
propriedade do MasterPageFile
objeto programaticamente, poderíamos 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
atributo da @Page
diretiva em Default.aspx
e visite a página por meio de um navegador. Como era de se esperar, a saída é a mesma que antes de o atributo ser removido.
Se a MasterPageFile
propriedade é definida por meio da @Page
diretiva ou programaticamente é inconsequente à experiência do usuário final. No entanto, o MasterPageFile
atributo na @Page
diretiva é usado pelo Visual Studio durante o tempo de design para produzir a exibição WYSIWYG no Designer. Se você voltar para Default.aspx
o Visual Studio e navegar até o Designer verá a mensagem "Erro da 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 suma, você precisa deixar o MasterPageFile
atributo na @Page
diretiva para desfrutar de uma experiência rica em tempo de design no Visual Studio.
atributo MasterPageFile da Directive para renderizar a exibição de design" />
Figura 02: o Visual Studio usa o @Page
atributo da MasterPageFile
diretiva para renderizar a exibição de design (clique para exibir a imagem em tamanho real)
Etapa 3: Criando uma página mestra alternativa
Como a página master de uma página de conteúdo pode ser definida programaticamente em runtime, é possível carregar dinamicamente uma página de master 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 Web do mecanismo de blog pode permitir que seus usuários escolham um layout para seu blog, em que cada layout está associado a uma página de master diferente. Em runtime, 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 de master correspondente à página de conteúdo.
Vamos examinar como carregar dinamicamente uma página de master em runtime com base em alguns critérios externos. Atualmente, nosso site contém apenas uma página de master (Site.master
). Precisamos de outra página master para ilustrar a escolha de uma página de master no runtime. Esta etapa se concentra na criação e configuração da nova página de master. A etapa 4 analisa a determinação de qual página master usar no runtime.
Crie uma nova página master na pasta raiz chamada Alternate.master
. Adicione também uma nova folha de estilos ao site chamado 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 master para ter o título exibido na parte superior da página, centralizado e em um plano de fundo da marinha. Dispensei a coluna esquerda e movi esse conteúdo abaixo do MainContent
controle ContentPlaceHolder, que agora abrange toda a largura da página. Além disso, nixed the unordered Lessons list and replaced it with a horizontal list above MainContent
. Também atualizei as fontes e cores usadas pela página master (e, por extensão, suas páginas de conteúdo). A Figura 4 mostra Default.aspx
ao usar a Alternate.master
página master.
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 runtime. Os temas são o caminho a percorrer se os layouts do seu site diferem apenas nas imagens exibidas e pelas regras do CSS. Se os layouts forem mais substancialmente diferentes, como usar diferentes controles da Web ou ter um layout radicalmente diferente, você precisará usar páginas master 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 de master e conteúdo é fundida, a MasterPage
classe verifica se todos os controles de conteúdo na página de conteúdo fazem referência a um ContentPlaceHolder na página master. Uma exceção será gerada se um controle content que faz referência a um ContentPlaceHolder inexistente for encontrado. Em outras palavras, é imperativo que a página master 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 master 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 de master (Alternate.master
) puder ser atribuída a essas páginas de conteúdo que têm controles de conteúdo para todos os ContentPlaceHolders, Site.master
é essencial que Alternate.master
também incluam os mesmos controles ContentPlaceHolder que Site.master
.
Para que sua Alternate.master
página de master fique semelhante à minha (consulte Figura 4), comece definindo os estilos da página master na AlternateStyles.css
folha de estilos. Adicione as seguintes regras a 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 marcação declarativa a seguir a Alternate.master
. Como você pode ver, Alternate.master
contém quatro controles ContentPlaceHolder com os mesmos ID
valores que os controles ContentPlaceHolder em Site.master
. Além disso, ele inclui um controle ScriptManager, que é necessário para as páginas em nosso site que usam o ASP.NET estrutura 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 esse novo master página, atualize o BasePage
método da OnPreInit
classe para que a MasterPageFile
propriedade receba o valor "~/Alternate.master" e visite o site. Cada página deve funcionar sem erro, exceto por dois: ~/Admin/AddProduct.aspx
e ~/Admin/Products.aspx
. Adicionar um produto ao DetailsView resulta em ~/Admin/AddProduct.aspx
um NullReferenceException
da linha de código que tenta definir a propriedade da GridMessageText
página master. Ao visitar ~/Admin/Products.aspx
um InvalidCastException
é gerado no carregamento da página com a mensagem: "Não é possível converter o objeto do tipo 'ASP.alternate_master' para digitar 'ASP.site_master'."
Esses erros ocorrem porque a Site.master
classe code-behind inclui eventos públicos, propriedades e métodos que não são definidos em Alternate.master
. A parte de marcação dessas duas páginas tem uma @MasterType
diretiva que faz referência à Site.master
página master.
<%@ MasterType VirtualPath="~/Site.master" %>
Além disso, o manipulador de eventos do ItemInserted
DetailsView no ~/Admin/AddProduct.aspx
inclui o 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 associam firmemente as ~/Admin/AddProduct.aspx
páginas e ~/Admin/Products.aspx
à Site.master
página master.
Para interromper esse acoplamento apertado, podemos ter Site.master
e Alternate.master
derivar de uma classe base comum que contém definições para os membros públicos. Depois disso, podemos atualizar a @MasterType
diretiva para fazer referência a esse tipo base comum.
Criando uma classe de página mestra base personalizada
Adicione um novo arquivo de classe à App_Code
pasta chamada BaseMasterPage.cs
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 da Web específicos para a Site.master
página master (GridView RecentProducts
e GridMessage
Label).
O que precisamos fazer é configurar BaseMasterPage
de forma que esses membros sejam definidos lá, mas, na verdade, são implementados pelas BaseMasterPage
classes derivadas de (Site.master
e Alternate.master
). Esse tipo de herança é possível marcando a classe e seus membros como abstract
. Em suma, adicionar o abstract
palavra-chave a esses dois membros anuncia que BaseMasterPage
não implementou RefreshRecentProductsGrid
e GridMessageText
, mas que suas classes derivadas irão.
Também precisamos definir o PricesDoubled
evento em BaseMasterPage
e fornecer um meio pelas classes derivadas para acionar 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 virtual
chamado OnEventName
. As classes derivadas podem chamar esse método para acionar o evento ou podem substituí-lo para executar o código imediatamente antes ou depois que o evento é acionado.
Atualize sua BaseMasterPage
classe para que ela contenha o seguinte código:
using System; public abstract class BaseMasterPage : System.Web.UI.MasterPage
{
public event EventHandler PricesDoubled;
protected virtual void OnPricesDoubled(EventArgs e)
{
if (PricesDoubled != null)
PricesDoubled(this, e);
}
public abstract void RefreshRecentProductsGrid();
public abstract string GridMessageText
{
get;
set;
}
}
Em seguida, vá para a Site.master
classe code-behind e faça com que ela derive de BaseMasterPage
. Porque BaseMasterPage
precisamos abstract
substituir esses abstract
membros aqui no Site.master
. Adicione o override
palavra-chave às definições de método e propriedade. Atualize também o código que aciona o PricesDoubled
evento no DoublePrice
manipulador de eventos do Click
Botão 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:
public partial class Site : BaseMasterPage {
protected void Page_Load(object sender, EventArgs e)
{
DateDisplay.Text = DateTime.Now.ToString("dddd, MMMM dd");
}
public override void RefreshRecentProductsGrid()
{
RecentProducts.DataBind();
}
public override string GridMessageText
{
get
{
return GridMessage.Text;
}
set
{
GridMessage.Text = value;
}
}
protected void DoublePrice_Click(object sender, EventArgs e)
{
// Double the prices
DoublePricesDataSource.Update();
// Refresh RecentProducts
RecentProducts.DataBind();
// Raise the PricesDoubled event
base.OnPricesDoubled(EventArgs.Empty);
}
}
Também precisamos atualizar Alternate.master
a classe code-behind para derivar BaseMasterPage
e substituir os dois abstract
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.
public partial class Alternate : BaseMasterPage
{
public override void RefreshRecentProductsGrid()
{
// Do nothing
}
public override string GridMessageText
{
get
{
return string.Empty;
}
set
{
// Do nothing
}
}
}
Referenciando a classe de página mestra base
Agora que concluímos a BaseMasterPage
classe e temos nossas duas páginas master estendendo-a, nossa etapa final é atualizar as ~/Admin/AddProduct.aspx
páginas e ~/Admin/Products.aspx
para fazer referência 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 referenciar um caminho de arquivo, a @MasterType
propriedade agora faz referência ao tipo base (BaseMasterPage
). Consequentemente, a propriedade fortemente tipada Master
usada nas classes code-behind de ambas as páginas agora é do tipo BaseMasterPage
(em vez do tipo Site
). Com essa alteração em vigor, reveja ~/Admin/Products.aspx
. Anteriormente, isso resultava em um erro de conversão porque a página estava configurada para usar a Alternate.master
página master, 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 master pode ser convertida em um objeto do tipo BaseMasterPage
(já que a estende).
Há uma pequena alteração que precisa ser feita em ~/Admin/AddProduct.aspx
. O manipulador de eventos do ItemInserted
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 de tipo flexível. Substitua a seguinte linha de código:
Site myMasterPage = Page.Master as Site;
Com o seguinte, que é convertido Page.Master
no tipo base:
BaseMasterPage myMasterPage = Page.Master as BaseMasterPage;
Etapa 4: Determinando qual página mestra associar às páginas de conteúdo
Atualmente, nossa BasePage
classe define todas as propriedades de 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 master em algum fator externo. Talvez a página master a ser carregada dependa das preferências do usuário conectado no momento. Nesse caso, precisamos escrever código no OnPreInit
método em BasePage
que pesquisa as preferências de página de master do usuário que está visitando no momento.
Vamos criar uma página da Web que permita que o usuário escolha qual master página usar - Site.master
ou Alternate.master
- e salvar essa opção em uma variável de sessão. Comece criando uma nova página da Web no diretório raiz chamado ChooseMasterPage.aspx
. Ao criar essa página (ou outras páginas de conteúdo a partir de agora), você não precisa associá-la a uma página master porque a página master é definida programaticamente em BasePage
. No entanto, se você não associar a nova página a uma página master, a marcação declarativa padrão da nova página conterá um Web Form e outro conteúdo fornecido pela página master. Você precisará substituir manualmente essa marcação pelos controles de Conteúdo apropriados. Por esse motivo, acho mais fácil associar a nova página de ASP.NET a uma página master.
Observação
Como Site.master
e Alternate.master
têm o mesmo conjunto de controles ContentPlaceHolder, não importa qual master página 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 de <siteMapNode>
para a lição Páginas Mestras e ASP.NET AJAX:
<siteMapNode url="~/ChooseMasterPage.aspx" title="Choose a Master Page" />
Antes de adicionar qualquer conteúdo à ChooseMasterPage.aspx
página, reserve um momento para atualizar a classe code-behind da página para que ela seja derivada de (em vez System.Web.UI.Page
de BasePage
). Em seguida, adicione um controle DropDownList à página, defina sua ID
propriedade MasterPageChoice
como 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
e "Salvar Escolha de Layout", respectivamente. Neste ponto, a marcação declarativa da 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 master do usuário selecionada no momento. Crie um Page_Load
manipulador de eventos e adicione o seguinte código:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Session["MyMasterPage"] != null)
{
ListItem li = MasterPageChoice.Items.FindByText(Session["MyMasterPage"].ToString());
if (li != null)
li.Selected = true;
}
}
}
O código acima é executado somente na primeira visita à página (e não em postbacks subsequentes). Primeiro, ele verifica se a variável MyMasterPage
Session existe. Se isso acontecer, ele tentará encontrar o ListItem correspondente no MasterPageChoice
DropDownList. Se um ListItem correspondente for encontrado, sua Selected
propriedade será definida true
como .
Também precisamos de código que salve a escolha do usuário na MyMasterPage
variável De sessão. Crie um manipulador de eventos para o SaveLayout
evento do Click
Botão e adicione o seguinte código:
protected void SaveLayout_Click(object sender, EventArgs e)
{
Session["MyMasterPage"] = MasterPageChoice.SelectedValue;
Response.Redirect("ChooseMasterPage.aspx");
}
Observação
No momento em que o Click
manipulador de eventos é executado no postback, a página master já foi selecionada. Portanto, a seleção de lista suspensa do usuário não estará em vigor até a próxima visita à página. O Response.Redirect
força o navegador a solicitar ChooseMasterPage.aspx
novamente .
Com a ChooseMasterPage.aspx
página concluída, nossa tarefa final é atribuir BasePage
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 override void OnPreInit(EventArgs e)
{
SetMasterPageFile();
base.OnPreInit(e);
}
protected virtual void SetMasterPageFile()
{
this.MasterPageFile = GetMasterPageFileFromSession();
}
protected string GetMasterPageFileFromSession()
{
if (Session["MyMasterPage"] == null)
return "~/Site.master";
else
return Session["MyMasterPage"].ToString();
}
Observação
Movai o código que atribui a Page
propriedade do MasterPageFile
objeto para fora do OnPreInit
manipulador de eventos e para dois métodos separados. Esse primeiro método, SetMasterPageFile
, atribui a MasterPageFile
propriedade ao valor retornado pelo segundo método, GetMasterPageFileFromSession
. Fiz o SetMasterPageFile
método virtual
para que 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 SetMasterPageFile
no próximo tutorial.
Com esse código em vigor, visite a ChooseMasterPage.aspx
página. Inicialmente, a Site.master
página master está selecionada (consulte a Figura 6), mas o usuário pode escolher uma página de master diferente na lista suspensa.
Figura 06: As páginas de conteúdo são exibidas usando a Site.master
página mestra (clique para exibir a imagem em tamanho real)
Figura 07: As páginas de conteúdo agora são exibidas usando a Alternate.master
página mestra (clique para exibir a 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 master. A página master 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 inicialização. Como este tutorial mostrou, podemos atribuir um valor à MasterPageFile
propriedade desde que façamos isso antes do final do estágio PreInit. Ser capaz de especificar programaticamente a página master abre a porta para cenários mais avançados, como associar dinamicamente uma página de conteúdo a uma página master com base em fatores externos.
Programação feliz!
Leitura Adicional
Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos:
- Diagrama do ciclo de vida da página ASP.NET
- Visão geral do ciclo de vida da página ASP.NET
- Visão geral de temas e capas ASP.NET
- Páginas Mestras: Dicas, Truques e Armadilhas
- Temas em ASP.NET
Sobre o autor
Scott Mitchell, autor de vários livros do ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Microsoft Web desde 1998. Scott trabalha como consultor independente, treinador e escritor. 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
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? Nesse caso, deixe-me uma linha em mitchell@4GuysFromRolla.com