Páginas mestras aninhadas (C#)
por Scott Mitchell
Mostra como aninhar uma página mestra em outra.
Introdução
Ao longo dos últimos nove tutoriais, vimos como implementar um layout em todo o site com páginas mestras. Em poucas palavras, as páginas mestras permitem que nós, o desenvolvedor da página, defina a marcação comum na página mestra junto com regiões específicas que podem ser personalizadas em uma base de página de conteúdo por página de conteúdo. Os controles ContentPlaceHolder em uma página mestra indicam as regiões personalizáveis; a marcação personalizada para os controles ContentPlaceHolder é definida na página de conteúdo por meio de controles de conteúdo.
As técnicas de página mestra que exploramos até agora são ótimas se você tiver um único layout usado em todo o site. No entanto, muitos sites grandes têm um layout de site personalizado em várias seções. Por exemplo, considere um aplicativo de assistência médica usado pela equipe do hospital para gerenciar informações, atividades e faturamento do paciente. Pode haver três tipos de páginas da web neste aplicativo:
- Páginas específicas de membros da equipe onde os membros da equipe podem atualizar a disponibilidade, exibir agendas ou solicitar férias.
- Páginas específicas do paciente onde os membros da equipe visualizam ou editam informações de um paciente específico.
- Páginas específicas de faturamento em que os contadores analisam os status atuais dos sinistros e os relatórios financeiros.
Cada página pode compartilhar um layout comum, como um menu na parte superior e uma série de links usados com frequência na parte inferior. Mas as páginas específicas da equipe, do paciente e da cobrança podem precisar personalizar esse layout genérico. Por exemplo, talvez todas as páginas específicas da equipe devam incluir um calendário e uma lista de tarefas mostrando a disponibilidade e a programação diária do usuário conectado no momento. Talvez todas as páginas específicas do paciente precisem mostrar o nome, endereço e informações de seguro do paciente cujas informações estão sendo editadas.
É possível criar esses layouts personalizados usando páginas mestras aninhadas. Para implementar o cenário acima, começaríamos criando uma página mestra que definisse o layout de todo o site, o menu e o conteúdo do rodapé, com ContentPlaceHolders definindo as regiões personalizáveis. Em seguida, criaríamos três páginas mestras aninhadas, uma para cada tipo de página da Web. Cada página mestra aninhada definiria o conteúdo entre o tipo de páginas de conteúdo que usam a página mestra. Em outras palavras, a página mestra aninhada para páginas de conteúdo específicas do paciente incluiria marcação e lógica programática para exibir informações sobre o paciente que está sendo editado. Ao criar uma nova página específica do paciente, nós a vincularíamos a essa página mestra aninhada.
Este tutorial começa destacando os benefícios das páginas mestras aninhadas. Em seguida, mostra como criar e usar páginas mestras aninhadas.
Observação
As páginas mestras aninhadas são possíveis desde a versão 2.0 do .NET Framework. No entanto, o Visual Studio 2005 não incluiu suporte em tempo de design para páginas mestras aninhadas. A boa notícia é que o Visual Studio 2008 oferece uma experiência avançada de tempo de design para páginas mestras aninhadas. Se você estiver interessado em usar páginas mestras aninhadas, mas ainda estiver usando o Visual Studio 2005, confira a entrada de blog de Scott Guthrie, Dicas para páginas mestras aninhadas no VS 2005 Design-Time.
Os benefícios das páginas mestras aninhadas
Muitos sites têm um design de site abrangente, bem como designs mais personalizados específicos para determinados tipos de páginas. Por exemplo, em nosso aplicativo da web de demonstração, criamos uma seção de administração rudimentar (as páginas na ~/Admin
pasta). Atualmente, as páginas da Web na ~/Admin
pasta usam a mesma página mestra que as páginas que não estão na seção de administração (ou seja, Site.master
ou Alternate.master
, dependendo da seleção do usuário).
Observação
Por enquanto, finja que nosso site tem apenas uma página mestra, Site.master
. Abordaremos o uso de páginas mestras aninhadas com duas (ou mais) páginas mestras, começando com "Usando uma página mestra aninhada para a seção Administração" mais adiante neste tutorial.
Imagine que nos foi pedido para personalizar o layout das páginas de Administração para incluir informações adicionais ou links que, de outra forma, não estariam presentes em outras páginas do site. Há quatro técnicas para implementar esse requisito:
- Adicione manualmente as informações e os links específicos da Administração a todas as páginas de conteúdo da
~/Admin
pasta. - Atualize a
Site.master
página mestra para incluir as informações e os links específicos da seção Administração e, em seguida, adicione código à página mestra para mostrar ou ocultar essas seções com base no fato de uma das páginas de Administração estar sendo visitada. - Crie uma nova página mestra especificamente para a seção Administração, copie a marcação de
Site.master
, adicione as informações e os links específicos da seção Administração e atualize as~/Admin
páginas de conteúdo na pasta para usar essa nova página mestra. - Crie uma página mestra aninhada que seja associada e
Site.master
faça com que as páginas de conteúdo na~/Admin
pasta usem essa nova página mestra aninhada. Essa página mestra aninhada incluiria apenas as informações adicionais e os links específicos das páginas de Administração e não precisaria repetir a marcação já definida noSite.master
.
A primeira opção é a menos palatável. O objetivo de usar páginas mestras é deixar de ter que copiar e colar manualmente a marcação comum em novas páginas ASP.NET. A segunda opção é aceitável, mas torna o aplicativo menos sustentável, pois aumenta as páginas mestras com marcação que é exibida apenas ocasionalmente e exige que os desenvolvedores que editam a página mestra contornem essa marcação e tenham que lembrar quando, exatamente, determinada marcação é exibida versus quando ela está oculta. Essa abordagem seria menos sustentável, pois as personalizações de mais e mais tipos de páginas da Web precisavam ser acomodadas por essa única página mestra.
A terceira opção remove os problemas de desordem e complexidade que surgiram com a segunda opção. No entanto, a principal desvantagem da opção três é que ela exige que copiemos e colemos o layout comum da nova página mestra específica da Site.master
seção Administração. Se mais tarde decidirmos alterar o layout de todo o site, temos que nos lembrar de alterá-lo em dois lugares.
A quarta opção, páginas mestras aninhadas, nos dá o melhor da segunda e terceira opções. As informações de layout de todo o site são mantidas em um arquivo - a página mestra de nível superior - enquanto o conteúdo específico de regiões específicas é separado em arquivos diferentes.
Este tutorial começa com uma olhada na criação e no uso de uma página mestra aninhada simples. Criamos uma nova página mestra de nível superior, duas páginas mestras aninhadas e duas páginas de conteúdo. Começando com "Usando uma página mestra aninhada para a seção de administração", examinamos a atualização de nossa arquitetura de página mestra existente para incluir o uso de páginas mestras aninhadas. Especificamente, criamos uma página mestra aninhada e a usamos para incluir conteúdo personalizado adicional para as páginas de conteúdo na ~/Admin
pasta.
Etapa 1: Criando uma página mestra simples de nível superior
Criar um mestre aninhado com base em uma das páginas mestras existentes e, em seguida, atualizar uma página de conteúdo existente para usar essa nova página mestra aninhada em vez da página mestra de nível superior envolve alguma complexidade porque as páginas de conteúdo existentes já esperam determinados controles ContentPlaceHolder definidos na página mestra de nível superior. Portanto, a página mestra aninhada também deve incluir os mesmos controles ContentPlaceHolder com os mesmos nomes. Além disso, nosso aplicativo de demonstração específico tem duas páginas mestras (Site.master
e Alternate.master
) que são atribuídas dinamicamente a uma página de conteúdo com base nas preferências do usuário, o que aumenta ainda mais essa complexidade. Veremos como atualizar o aplicativo existente para usar páginas mestras aninhadas posteriormente neste tutorial, mas vamos primeiro nos concentrar em um exemplo simples de páginas mestras aninhadas.
Crie uma nova pasta chamada NestedMasterPages
e adicione um novo arquivo de página mestra a essa pasta chamada Simple.master
. (Consulte a Figura 1 para obter uma captura de tela do Gerenciador de Soluções depois que essa pasta e arquivo forem adicionados.) Arraste o AlternateStyles.css
arquivo de folha de estilos do Gerenciador de Soluções para o Designer. Isso adiciona um <link>
elemento ao arquivo de folha de estilo no elemento, após o <head>
qual a marcação do <head>
elemento da página mestra deve ser semelhante a:
<head runat="server">
<title>Untitled Page</title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
<link href="../AlternateStyles.css" rel="stylesheet" type="text/css" />
</head>
Em seguida, adicione a seguinte marcação no formulário da Web de Simple.master
:
<div id="topContent">
<asp:HyperLink ID="lnkHome" runat="server"
NavigateUrl="~/NestedMasterPages/Default.aspx"
Text="Nested Master Pages Tutorial (Simple)" />
</div>
<div id="mainContent">
<asp:ContentPlaceHolder id="MainContent" runat="server">
</asp:ContentPlaceHolder>
</div>
Essa marcação exibe um link intitulado "Páginas mestras aninhadas (simples)" na parte superior da página em uma fonte branca grande em um plano de fundo azul-marinho. Abaixo disso está o MainContent
ContentPlaceHolder. A Figura 1 mostra a Simple.master
página mestra quando carregada no Visual Studio Designer.
Figura 01: A página mestra aninhada define o conteúdo específico das páginas na seção Administração (clique para exibir a imagem em tamanho real)
Etapa 2: Criando uma página mestra aninhada simples
Simple.master
contém dois controles ContentPlaceHolder: o MainContent
ContentPlaceHolder que adicionamos no formulário da Web junto com o head
ContentPlaceHolder no <head>
elemento. Se fôssemos criar uma página de conteúdo e associá-la à Simple.master
página de conteúdo, teríamos dois controles de conteúdo referenciando os dois ContentPlaceHolders. Da mesma forma, se criarmos uma página mestra aninhada e a associarmos a Simple.master
ela, a página mestra aninhada terá dois controles de conteúdo.
Vamos adicionar uma nova página mestra aninhada NestedMasterPages
à pasta chamada SimpleNested.master
. Clique com o botão direito do NestedMasterPages
mouse na pasta e escolha Adicionar novo item. Isso abre a caixa de diálogo Adicionar novo item mostrada na Figura 2. Selecione o tipo de modelo de Página Mestra e digite o nome da nova página mestra. Para indicar que a nova página mestra deve ser uma página mestra aninhada, marque a caixa de seleção "Selecionar página mestra".
Em seguida, clique no botão Adicionar. Isso exibirá a mesma caixa de diálogo Selecionar uma página mestra que você vê ao vincular uma página de conteúdo a uma página mestra (consulte a Figura 3). Escolha a Simple.master
página mestra na pasta e clique em NestedMasterPages
OK.
Observação
Se você criou seu site ASP.NET usando o modelo de Projeto de Aplicativo Web em vez do modelo de Projeto de Site, não verá a caixa de seleção "Selecionar página mestra" na caixa de diálogo Adicionar Novo Item mostrada na Figura 2. Para criar uma página mestra aninhada ao usar o modelo de Projeto de Aplicação Web, você deve escolher o modelo de Página Mestra Aninhada (em vez do modelo de Página Mestra). Depois de selecionar o modelo de Página Mestra Aninhada e clicar em Adicionar, a mesma caixa de diálogo Selecionar uma Página Mestre mostrada na Figura 3 será exibida.
Figura 02: Marque a caixa de seleção "Selecionar página mestra" para adicionar uma página mestra aninhada (clique para exibir a imagem em tamanho real)
Figura 03: Associar a página mestra aninhada à página mestra (clique para exibir a Simple.master
imagem em tamanho real)
A marcação declarativa da página mestra aninhada, mostrada abaixo, contém dois controles Content que fazem referência aos dois controles ContentPlaceHolder da página mestra de nível superior.
<%@ Master Language="C#" MasterPageFile="~/NestedMasterPages/Simple.master" AutoEventWireup="false" CodeFile="SimpleNested.master.cs" Inherits="NestedMasterPages_SimpleNested" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
</asp:Content>
Exceto pela <%@ Master %>
diretiva, a marcação declarativa inicial da página mestra aninhada é idêntica à marcação gerada inicialmente ao associar uma página de conteúdo à mesma página mestra de nível superior. Como a diretiva de uma página de <%@ Page %>
conteúdo, a <%@ Master %>
diretiva aqui inclui um MasterPageFile
atributo que especifica a página mestra pai da página mestra aninhada. A principal diferença entre a página mestra aninhada e uma página de conteúdo associada à mesma página mestra de nível superior é que a página mestra aninhada pode incluir controles ContentPlaceHolder. Os controles ContentPlaceHolder da página mestra aninhada definem as regiões em que as páginas de conteúdo podem personalizar a marcação.
Atualize essa página mestra aninhada para que ela exiba o texto "Olá, de SimpleNested!" no controle Content que corresponde ao MainContent
controle ContentPlaceHolder.
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
<p>Hello, from SimpleNested!</p>
</asp:Content>
Depois de fazer essa adição, salve a página mestra aninhada e adicione uma nova página de conteúdo à NestedMasterPages
pasta chamada Default.aspx
, e vincule-a SimpleNested.master
à página mestra. Ao adicionar esta página, você pode se surpreender ao ver que ela não contém controles de conteúdo (consulte a Figura 4)! Uma página de conteúdo só pode acessar os ContentPlaceHolders da página mestra pai . SimpleNested.master
não contém nenhum controle ContentPlaceHolder; portanto, qualquer página de conteúdo associada a essa página mestra não pode conter nenhum controle de conteúdo.
Figura 04: A nova página de conteúdo não contém controles de conteúdo (clique para exibir a imagem em tamanho real)
O que precisamos fazer é atualizar a página mestra aninhada (SimpleNested.master
) para incluir controles ContentPlaceHolder. Normalmente, você desejará que suas páginas mestras aninhadas incluam um ContentPlaceHolder para cada ContentPlaceHolder definido por sua página mestra pai, permitindo assim que sua página mestra filho ou página de conteúdo funcione com qualquer um dos controles ContentPlaceHolder da página mestra de nível superior.
Atualize a SimpleNested.master
página mestra para incluir um ContentPlaceHolder em seus dois controles de conteúdo. Dê aos controles ContentPlaceHolder o mesmo nome que o controle ContentPlaceHolder ao qual seu controle Content se refere. Ou seja, adicione um controle ContentPlaceHolder nomeado MainContent
ao controle Content em SimpleNested.master
que faz referência ao MainContent
ContentPlaceHolder em Simple.master
. Faça a mesma coisa no controle Content que faz referência ao head
ContentPlaceHolder.
Observação
Embora eu recomende nomear os controles ContentPlaceHolder na página mestra aninhada da mesma forma que os ContentPlaceHolders na página mestra de nível superior, essa simetria de nomenclatura não é necessária. Você pode dar aos controles ContentPlaceHolder em sua página mestra aninhada qualquer nome que desejar. No entanto, acho mais fácil lembrar quais ContentPlaceHolders correspondem a quais regiões da página se minha página mestra de nível superior e páginas mestras aninhadas usarem os mesmos nomes.
Depois de fazer essas adições, a marcação declarativa da página SimpleNested.master
mestra deve ser semelhante à seguinte:
<%@ Master Language="C#" MasterPageFile="~/NestedMasterPages/Simple.master"AutoEventWireup="false" CodeFile="SimpleNested.master.cs" Inherits="NestedMasterPages_SimpleNested" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
<p>Hello, from SimpleNested!</p>
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
Exclua a Default.aspx
página de conteúdo que acabamos de criar e adicione-a novamente, vinculando-a SimpleNested.master
à página mestra. Desta vez, o Default.aspx
Visual Studio adiciona dois controles de conteúdo ao , referenciando os ContentPlaceHolders agora definidos em SimpleNested.master
(consulte a Figura 6). Adicione o texto "Olá, do Default.aspx!" no controle de conteúdo que fez referência MainContent
a .
A Figura 5 mostra as três entidades envolvidas aqui - Simple.master
, , SimpleNested.master
e Default.aspx
- e como elas se relacionam entre si. Como mostra o diagrama, a página mestra aninhada implementa controles de conteúdo para o ContentPlaceHolder de seu pai. Se essas regiões precisarem ser acessíveis à página de conteúdo, a página mestra aninhada deverá adicionar seus próprios ContentPlaceHolders aos controles de conteúdo.
Figura 05: As páginas mestras de nível superior e aninhadas ditam o layout da página de conteúdo (clique para exibir a imagem em tamanho real)
Esse comportamento ilustra como uma página de conteúdo ou página mestra só reconhece sua página mestra pai. Esse comportamento também é indicado pelo Visual Studio Designer. A Figura 6 mostra o Designer para Default.aspx
. Embora o Designer mostre claramente quais regiões são editáveis na página de conteúdo e quais partes não são, ele não elimina a ambiguidade de quais regiões não editáveis são da página mestra aninhada e quais regiões são da página mestra de nível superior.
Figura 06: A página de conteúdo agora inclui controles de conteúdo para os ContentPlaceHolders da página mestra aninhada (clique para exibir a imagem em tamanho real)
Etapa 3: Adicionando uma segunda página mestra aninhada simples
O benefício das páginas mestras aninhadas é mais evidente quando há várias páginas mestras aninhadas. Para ilustrar esse benefício, crie outra página mestra aninhada NestedMasterPages
na pasta; nomeie essa nova página SimpleNestedAlternate.master
mestra aninhada e vincule-a Simple.master
à página mestra. Adicione controles ContentPlaceHolder nos dois controles Content da página mestra aninhada, como fizemos na Etapa 2. Adicione também o texto "Olá, de SimpleNestedAlternate!" no controle Content que corresponde ao ContentPlaceHolder da MainContent
página mestra de nível superior. Depois de fazer essas alterações, a marcação declarativa da nova página mestra aninhada deve ser semelhante à seguinte:
<%@ Master Language="C#" MasterPageFile="~/NestedMasterPages/Simple.master" AutoEventWireup="false" CodeFile="SimpleNestedAlternate.master.cs" Inherits="NestedMasterPages_SimpleNestedAlternate" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
<p>Hello, from SimpleNestedAlternate!</p>
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
Crie uma página de conteúdo nomeada Alternate.aspx
na NestedMasterPages
pasta e associe-a SimpleNestedAlternate.master
à página mestra aninhada. Adicione o texto "Olá, da alternativa!" no controle de conteúdo que corresponde a MainContent
. A Figura 7 mostra Alternate.aspx
quando exibida por meio do Visual Studio Designer.
Figura 07: Alternate.aspx
está acoplado à página mestra (clique para exibir a SimpleNestedAlternate.master
imagem em tamanho real)
Compare o designer na Figura 7 com o designer na Figura 6. Ambas as páginas de conteúdo compartilham o mesmo layout definido na página mestra de nível superior (Simple.master
), ou seja, o título "Tutorial de Páginas Mestras Aninhadas (Simples)". No entanto, ambos têm conteúdo distinto definido em suas páginas mestras pai - o texto "Olá, de SimpleNested!" na Figura 6 e "Olá, de SimpleNestedAlternate!" na Figura 7. É verdade que essas diferenças aqui são triviais, mas você pode estender este exemplo para incluir diferenças mais significativas. Por exemplo, a SimpleNested.master
página pode incluir um menu com opções específicas para suas páginas de conteúdo, enquanto SimpleNestedAlternate.master
pode ter informações pertinentes às páginas de conteúdo que se vinculam a ela.
Agora, imagine que precisássemos fazer uma alteração no layout geral do site. Por exemplo, imagine que quiséssemos adicionar uma lista de links comuns a todas as páginas de conteúdo. Para fazer isso, atualizamos a página mestra de nível superior, Simple.master
. Todas as alterações são refletidas imediatamente em suas páginas mestras aninhadas e, por extensão, em suas páginas de conteúdo.
Para demonstrar a facilidade com que podemos alterar o layout do site abrangente, abra a Simple.master
página mestra e adicione a seguinte marcação entre os topContent
elementos and mainContent
<div>
:
<div id="navContent">
<asp:HyperLink ID="lnkDefault" runat="server"
NavigateUrl="~/NestedMasterPages/Default.aspx"
Text="Nested Master Page Example 1" />
|
<asp:HyperLink ID="lnkAlternate" runat="server"
NavigateUrl="~/NestedMasterPages/Alternate.aspx"
Text="Nested Master Page Example 2" />
</div>
Isso adiciona dois links à parte superior de cada página que se vincula a Simple.master
, SimpleNested.master
, ou SimpleNestedAlternate.master
; essas alterações se aplicam a todas as páginas mestras aninhadas e suas páginas de conteúdo imediatamente. A Figura 8 mostra Alternate.aspx
quando visualizada por meio de um navegador. Observe a adição dos links na parte superior da página (em comparação com a Figura 7).
Figura 08: Alteradas para a página mestra de nível superior são refletidas imediatamente em suas páginas mestras aninhadas e suas páginas de conteúdo (clique para exibir a imagem em tamanho real)
Usando uma página mestra aninhada para a seção Administração
Neste ponto, examinamos as vantagens das páginas mestras aninhadas e vimos como criá-las e usá-las em um aplicativo ASP.NET. Os exemplos nas Etapas 1, 2 e 3, no entanto, envolveram a criação de uma nova página mestra de nível superior, novas páginas mestras aninhadas e novas páginas de conteúdo. Que tal adicionar uma nova página mestra aninhada a um site com uma página mestra de nível superior e páginas de conteúdo existentes?
Integrar uma página mestra aninhada a um site existente e associá-la a páginas de conteúdo existentes requer um pouco mais de esforço do que começar do zero. As etapas 4, 5, 6 e 7 exploram esses desafios à medida que aumentamos nosso aplicativo de demonstração para incluir uma nova página mestra aninhada chamada AdminNested.master
que contém instruções para o administrador e é usada pelas páginas ASP.NET na ~/Admin
pasta.
A integração de uma página mestra aninhada em nosso aplicativo de demonstração apresenta os seguintes obstáculos:
- As páginas de conteúdo existentes na
~/Admin
pasta têm certas expectativas de sua página mestra. Para começar, eles esperam que determinados controles ContentPlaceHolder estejam presentes. Além disso, as~/Admin/AddProduct.aspx
páginas e~/Admin/Products.aspx
chamam o método públicoRefreshRecentProductsGrid
da página mestra, definem suaGridMessageText
propriedade ou têm um manipulador de eventos para seuPricesDoubled
evento. Consequentemente, nossa página mestra aninhada deve fornecer os mesmos ContentPlaceHolders e membros públicos. - No tutorial anterior, aprimoramos a
BasePage
classe para definir dinamicamente aPage
propriedade doMasterPageFile
objeto com base em uma variável Session. Como podemos oferecer suporte a páginas mestras dinâmicas ao usar páginas mestras aninhadas?
Esses dois desafios surgirão à medida que criarmos a página mestra aninhada e a usarmos em nossas páginas de conteúdo existentes. Investigaremos e superaremos esses problemas à medida que surgirem.
Etapa 4: Criando a página mestra aninhada
Nossa primeira tarefa é criar a página mestra aninhada a ser usada pelas páginas na seção Administração. Como vimos na Etapa 2, ao adicionar uma nova página mestra aninhada, precisamos especificar a página mestra pai da página mestra aninhada. Mas temos duas páginas mestras de nível superior: Site.master
e Alternate.master
. Lembre-se de que criamos Alternate.master
no tutorial anterior e escrevemos código BasePage
na classe que define a propriedade do MasterPageFile
objeto Page em runtime como ou Site.master
Alternate.master
dependendo do valor da MyMasterPage
variável Session.
Como configuramos nossa página mestra aninhada para que ela use a página mestra de nível superior apropriada? Nós temos duas opções:
- Crie duas páginas
AdminNestedSite.master
mestras aninhadas eAdminNestedAlternate.master
, e vincule-as às páginasSite.master
mestras de nível superior eAlternate.master
, respectivamente. EmBasePage
, então, definiríamos oPage
objetoMasterPageFile
para a página mestra aninhada apropriada. - Crie uma única página mestra aninhada e faça com que as páginas de conteúdo usem essa página mestra específica. Em seguida, em tempo de execução, precisaríamos definir a propriedade da
MasterPageFile
página mestra aninhada como a página mestra de nível superior apropriada em tempo de execução. (Como você já deve ter percebido, as páginas mestras também têm umaMasterPageFile
propriedade.)
Vamos usar a segunda opção. Crie um único arquivo de página mestra aninhado ~/Admin
na pasta chamada AdminNested.master
. Como ambos Site.master
Alternate.master
têm o mesmo conjunto de controles ContentPlaceHolder, não importa a qual página mestra você o vincule, embora eu o encoraje a associá-lo Site.master
por uma questão de consistência.
Figura 09: Adicionar uma página mestra aninhada à ~/Admin
pasta. (Clique para ver a imagem em tamanho real)
Como a página mestra aninhada está associada a uma página mestra com quatro controles ContentPlaceHolder, o Visual Studio adiciona quatro controles Content à marcação inicial do novo arquivo de página mestra aninhada. Como fizemos nas Etapas 2 e 3, adicione um controle ContentPlaceHolder em cada controle Content, dando a ele o mesmo nome que o controle ContentPlaceHolder da página mestra de nível superior. Adicione também a seguinte marcação ao controle Content que corresponde ao MainContent
ContentPlaceHolder:
<div class="instructions">
<b>Administration Instructions:</b>
<br />
The pages in the Administration section allow you, the Administrator, to
add new products and view existing products.
</div>
Em seguida, defina a instructions
classe CSS nos Styles.css
arquivos e AlternateStyles.css
CSS. As seguintes regras CSS fazem com que os elementos HTML estilizados com a instructions
classe sejam exibidos com uma cor de fundo amarela clara e uma borda preta sólida:
.instructions
{
padding: 6px;
border: dashed 1px black;
background-color: #ffb;
margin-bottom: 10px;
}
Como essa marcação foi adicionada à página mestra aninhada, ela só aparecerá nas páginas que usam essa página mestra aninhada (ou seja, as páginas na seção Administração).
Depois de fazer essas adições à sua página mestra aninhada, sua marcação declarativa deve ser semelhante à seguinte:
<%@ Master Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="AdminNested.master.cs" Inherits="Admin_AdminNested" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
<asp:ContentPlaceHolder ID="head" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" Runat="Server">
<div class="instructions">
<b>Administration Instructions:</b>
<br />
The pages in the Administration section allow you, the Administrator, to
add new products and view existing products.
</div>
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="QuickLoginUI" Runat="Server">
<asp:ContentPlaceHolder ID="QuickLoginUI" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="LeftColumnContent" Runat="Server">
<asp:ContentPlaceHolder ID="LeftColumnContent" runat="server">
</asp:ContentPlaceHolder>
</asp:Content>
Observe que cada controle Content tem um controle ContentPlaceHolder e que as propriedades dos ID
controles ContentPlaceHolder recebem os mesmos valores que os controles ContentPlaceHolder correspondentes na página mestra de nível superior. Além disso, a marcação específica da seção Administração aparece no MainContent
ContentPlaceHolder.
A Figura 10 mostra a AdminNested.master
página mestra aninhada quando exibida por meio do Designer do Visual Studio. Você pode ver as instruções na caixa amarela na parte superior do MainContent
controle Conteúdo.
Figura 10: A página mestra aninhada estende a página mestra de nível superior para incluir instruções para o administrador. (Clique para ver a imagem em tamanho real)
Etapa 5: Atualizando as páginas de conteúdo existentes para usar a nova página mestra aninhada
Sempre que adicionamos uma nova página de conteúdo à seção Administração, precisamos vinculá-la à AdminNested.master
página mestra que acabamos de criar. Mas e as páginas de conteúdo existentes? Atualmente, todas as páginas de conteúdo no site derivam da BasePage
classe, que define programaticamente a página mestra da página de conteúdo em runtime. Esse não é o comportamento que queremos para as páginas de conteúdo na seção Administração. Em vez disso, queremos que essas páginas de conteúdo sempre usem a AdminNested.master
página. Será responsabilidade da página mestra aninhada escolher a página de conteúdo de nível superior correta em runtime.
A melhor maneira de obter esse comportamento desejado é criar uma nova classe de página base personalizada chamada AdminBasePage
que estende a BasePage
classe. AdminBasePage
pode então substituir e SetMasterPageFile
definir o Page
objeto MasterPageFile
como o valor codificado "~/Admin/AdminNested.master". Dessa forma, qualquer página derivada de AdminBasePage
usará AdminNested.master
, enquanto qualquer página derivada de BasePage
terá sua MasterPageFile
propriedade definida dinamicamente como "~/Site.master" ou "~/Alternate.master" com base no valor da MyMasterPage
variável Session.
Comece adicionando um novo arquivo de classe à App_Code
pasta chamada AdminBasePage.cs
. Ter AdminBasePage
extend BasePage
e, em seguida, substituir o SetMasterPageFile
método. Nesse método, atribua o MasterPageFile
valor "~/Admin/AdminNested.master". Depois de fazer essas alterações, seu arquivo de classe deve ser semelhante ao seguinte:
public class AdminBasePage : BasePage
{
protected override void SetMasterPageFile()
{
this.MasterPageFile = "~/Admin/AdminNested.master";
}
}
Agora precisamos que as páginas de conteúdo existentes na seção Administração derivem de em vez de AdminBasePage
BasePage
. Vá para o arquivo de classe code-behind para cada página de conteúdo na ~/Admin
pasta e faça essa alteração. Por exemplo, você ~/Admin/Default.aspx
alteraria a declaração de classe code-behind de:
public partial class Admin_Default : BasePage
Para:
public partial class Admin_Default : AdminBasePage
A Figura 11 mostra como a página mestra de nível superior (Site.master
ou Alternate.master
), a página mestra aninhada (AdminNested.master
) e as páginas de conteúdo da seção Administração se relacionam entre si.
Figura 11: A página mestra aninhada define o conteúdo específico das páginas na seção Administração (clique para exibir a imagem em tamanho real)
Etapa 6: Espelhando os métodos e propriedades públicas da página mestra
Lembre-se de que as ~/Admin/AddProduct.aspx
páginas e ~/Admin/Products.aspx
interagem programaticamente com a página mestra: ~/Admin/AddProduct.aspx
chama o método public RefreshRecentProductsGrid
da página mestra e define sua GridMessageText
propriedade; ~/Admin/Products.aspx
tem um manipulador de eventos para o PricesDoubled
evento. No tutorial anterior, criamos uma classe abstrata BaseMasterPage
que definiu esses membros públicos.
As ~/Admin/AddProduct.aspx
páginas e ~/Admin/Products.aspx
pressupõem que sua página mestra deriva da BaseMasterPage
classe. A AdminNested.master
página, no entanto, atualmente estende a System.Web.UI.MasterPage
classe. Como resultado, ao visitar ~/Admin/Products.aspx
um InvalidCastException
é lançado com a mensagem: "Não é possível converter o objeto do tipo 'ASP.admin_adminnested_master' para o tipo 'BaseMasterPage'".
Para corrigir isso, precisamos fazer com que a AdminNested.master
classe code-behind estenda BaseMasterPage
. Atualize a declaração de classe code-behind da página mestra aninhada de:
public partial class Admin_AdminNested : System.Web.UI.MasterPage
Para:
public partial class Admin_AdminNested : BaseMasterPage
Ainda não terminamos. Como a BaseMasterPage
classe é abstrata, precisamos substituir os abstract
membros RefreshRecentProductsGrid
e GridMessageText
. Esses membros são usados pelas páginas mestras de nível superior para atualizar suas interfaces do usuário. (Na verdade, apenas a página mestra usa esses métodos, embora ambas as Site.master
páginas mestras de nível superior implementem esses métodos, já que ambas se estendem BaseMasterPage
.)
Embora precisemos implementar esses membros no AdminNested.master
, tudo o que essas implementações precisam fazer é simplesmente chamar o mesmo membro na página mestra de nível superior usada pela página mestra aninhada. Por exemplo, quando uma página de conteúdo na seção Administração chama o método da RefreshRecentProductsGrid
página mestra aninhada, tudo o que a página mestra aninhada precisa fazer é, por sua vez, chamar Site.master
o Alternate.master
método ou RefreshRecentProductsGrid
.
Para conseguir isso, comece adicionando a seguinte @MasterType
diretiva ao topo de AdminNested.master
:
<%@ MasterType TypeName="BaseMasterPage" %>
Lembre-se de que a @MasterType
diretiva adiciona uma propriedade fortemente tipada à classe code-behind chamada Master
. Em seguida, substitua os RefreshRecentProductsGrid
membros and GridMessageText
e simplesmente delegue a chamada ao Master
método correspondente do :
public partial class Admin_AdminNested : BaseMasterPage
{
public override void RefreshRecentProductsGrid()
{
Master.RefreshRecentProductsGrid();
}
public override string GridMessageText
{
get
{
return Master.GridMessageText;
}
set
{
Master.GridMessageText = value;
}
}
}
Com esse código em vigor, você poderá visitar e usar as páginas de conteúdo na seção Administração. A Figura 12 mostra a página quando visualizada ~/Admin/Products.aspx
por meio de um navegador. Como você pode ver, a página inclui a caixa Instruções de Administração, que é definida na página mestra aninhada.
Figura 12: As páginas de conteúdo na seção Administração incluem instruções na parte superior de cada página (clique para exibir a imagem em tamanho real)
Etapa 7: Usando a página mestra de nível superior apropriada em tempo de execução
Embora todas as páginas de conteúdo na seção Administração sejam totalmente funcionais, todas elas usam a mesma página mestra de nível superior e ignoram a página mestra selecionada pelo usuário em ChooseMasterPage.aspx
. Esse comportamento se deve ao fato de que a página mestra aninhada tem sua MasterPageFile
propriedade definida estaticamente como Site.master
em sua <%@ Master %>
diretiva.
Para usar a página mestra de nível superior selecionada pelo usuário final, precisamos definir a AdminNested.master
propriedade do MasterPageFile
como o valor na MyMasterPage
variável Session. Como definimos as propriedades das MasterPageFile
páginas de conteúdo em BasePage
, você pode pensar que definiríamos a propriedade da MasterPageFile
página mestra aninhada na BaseMasterPage
classe code-behind da AdminNested.master
. Isso não funcionará, no entanto, porque precisamos definir a MasterPageFile
propriedade até o final do estágio PreInit. A primeira vez que podemos tocar programaticamente no ciclo de vida da página a partir de uma página mestra é o estágio Init (que ocorre após o estágio PreInit).
Portanto, precisamos definir a propriedade da MasterPageFile
página mestra aninhada nas páginas de conteúdo. As únicas páginas de conteúdo que usam a AdminNested.master
página mestra derivam de AdminBasePage
. Portanto, podemos colocar essa lógica lá. Na Etapa 5, substituímos o SetMasterPageFile
método, definindo a Page
propriedade do MasterPageFile
objeto como "~/Admin/AdminNested.master". Atualize SetMasterPageFile
para definir também a propriedade da MasterPageFile
página mestra como o resultado armazenado em Sessão:
public class AdminBasePage : BasePage
{
protected override void SetMasterPageFile()
{
this.MasterPageFile = "~/Admin/AdminNested.master";
Page.Master.MasterPageFile = base.GetMasterPageFileFromSession();
}
}
O GetMasterPageFileFromSession
método, que adicionamos à BasePage
classe no tutorial anterior, retorna o caminho apropriado do arquivo de paginação mestra com base no valor da variável Session.
Com essa alteração em vigor, a seleção da página mestra do usuário é transferida para a seção Administração. A Figura 13 mostra a mesma página que a Figura 12, mas depois que o usuário alterou sua seleção de página mestra para Alternate.master
.
Figura 13: A página de administração aninhada usa a página mestra de nível superior selecionada pelo usuário (clique para exibir a imagem em tamanho real)
Resumo
Assim como as páginas de conteúdo podem ser associadas a uma página mestra, é possível criar páginas mestras aninhadas fazendo com que uma página mestra filho seja associada a uma página mestra pai. A página mestra filho pode definir controles de conteúdo para cada um dos ContentPlaceHolders de seu pai; em seguida, ele pode adicionar seus próprios controles ContentPlaceHolder (bem como outras marcações) a esses controles de conteúdo. As páginas mestras aninhadas são bastante úteis em grandes aplicativos da Web em que todas as páginas compartilham uma aparência abrangente, mas certas seções do site exigem personalizações exclusivas.
Boa programação!
Leitura Adicional
Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos:
- Páginas mestras ASP.NET aninhadas
- Dicas para páginas mestras aninhadas e tempo de design do VS 2005
- Suporte à página mestra aninhada do VS 2008
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. Interessado em revisar meus próximos artigos do MSDN? Se sim, me mande uma mensagem em mitchell@4GuysFromRolla.com