Interagir com a página de conteúdo através da página mestra (C#)
por Scott Mitchell
Examina como chamar métodos, definir propriedades, etc. da Página de Conteúdo a partir do código na Página Mestra.
Introdução
O tutorial anterior examinou como fazer com que a página de conteúdo interaja programaticamente com sua página mestra. Lembre-se de que atualizamos a página mestra para incluir um controle GridView que listava os cinco produtos adicionados mais recentemente. Em seguida, criamos uma página de conteúdo a partir da qual o usuário poderia adicionar um novo produto. Ao adicionar um novo produto, a página de conteúdo precisava instruir a página mestra a atualizar seu GridView para que ela incluísse o produto recém-adicionado. Essa funcionalidade foi realizada adicionando um método público à página mestra que atualizou os dados associados ao GridView e, em seguida, invocando esse método da página de conteúdo.
A forma mais comum de interação de conteúdo e página mestra se origina da página de conteúdo. No entanto, é possível que a página mestra desperte a página de conteúdo atual para a ação, e essa funcionalidade pode ser necessária se a página mestra contiver elementos de interface do usuário que permitam aos usuários modificar dados que também são exibidos na página de conteúdo. Considere uma página de conteúdo que exibe as informações de produtos em um controle GridView e uma página mestra que inclui um controle Button que, quando clicado, dobra os preços de todos os produtos. Assim como no exemplo do tutorial anterior, o GridView precisa ser atualizado depois que o botão de preço duplo é clicado para exibir os novos preços, mas, nesse cenário, é a página mestra que precisa ativar a página de conteúdo.
Este tutorial explora como fazer com que a página mestra invoque a funcionalidade definida na página de conteúdo.
Instigando a interação programática por meio de um evento e manipuladores de eventos
Invocar a funcionalidade da página de conteúdo de uma página mestra é mais desafiador do que o contrário. Como uma página de conteúdo tem uma única página mestra, ao instigar a interação programática a partir da página de conteúdo, sabemos quais métodos e propriedades públicas estão à nossa disposição. Uma página mestra, no entanto, pode ter muitas páginas de conteúdo diferentes, cada uma com seu próprio conjunto de propriedades e métodos. Como, então, podemos escrever código na página mestra para executar alguma ação em sua página de conteúdo quando não sabemos qual página de conteúdo será invocada até o tempo de execução?
Considere um ASP.NET controle Web, como o controle Button. Um controle Button pode aparecer em qualquer número de páginas ASP.NET e precisa de um mecanismo pelo qual ele possa alertar a página de que ele foi clicado. Isso é feito usando eventos. Em particular, o controle Button gera seu Click
evento quando é clicado; a página ASP.NET que contém o Button pode, opcionalmente, responder a essa notificação por meio de um manipulador de eventos.
Esse mesmo padrão pode ser usado para ter uma funcionalidade de gatilho de página mestra em suas páginas de conteúdo:
- Adicione um evento à página mestra.
- Gerar o evento sempre que a página mestra precisar se comunicar com sua página de conteúdo. Por exemplo, se a página mestra precisar alertar sua página de conteúdo de que o usuário dobrou os preços, seu evento será gerado imediatamente após os preços terem sido dobrados.
- Crie um manipulador de eventos nas páginas de conteúdo que precisam executar alguma ação.
Este restante deste tutorial implementa o exemplo descrito na Introdução; ou seja, uma página de conteúdo que lista os produtos no banco de dados e uma página mestra que inclui um controle Button para dobrar os preços.
Etapa 1: Exibir produtos em uma página de conteúdo
Nossa primeira ordem do dia é criar uma página de conteúdo que liste os produtos do banco de dados Northwind. (Adicionamos o banco de dados Northwind ao projeto no tutorial anterior, Interagindo com a Página Mestra a partir da Página de Conteúdo.) Comece adicionando uma nova página ASP.NET à ~/Admin
pasta chamada Products.aspx
, certificando-se de vinculá-la à Site.master
página mestra. A Figura 1 mostra o Gerenciador de Soluções depois que essa página foi adicionada ao site.
Figura 01: Adicionar uma nova página ASP.NET à pasta (clique para exibir a Admin
imagem em tamanho real)
Lembre-se de que, no tutorial Especificando o título, as metatags e outros cabeçalhos HTML na página mestra, criamos uma classe de página base personalizada chamada BasePage
que gera o título da página se ela não estiver definida explicitamente. Vá para a Products.aspx
classe code-behind da página e faça com que ela derive de BasePage
(em vez de de ).System.Web.UI.Page
Por fim, atualize o Web.sitemap
arquivo para incluir uma entrada para esta lição. Adicione a seguinte marcação abaixo da <siteMapNode>
lição Interação Conteúdo para Página Mestra:
<siteMapNode url="~/Admin/Products.aspx" title="Master to Content Page Interaction" />
A adição desse <siteMapNode>
elemento é refletida na lista Lições (consulte a Figura 5).
Voltar para Products.aspx
. No controle Content for MainContent
, adicione um controle GridView e nomeie-o ProductsGrid
. Associe o GridView a um novo controle SqlDataSource chamado ProductsDataSource
.
Figura 02: Associar o GridView a um novo controle SqlDataSource (clique para exibir a imagem em tamanho completo)
Configure o assistente para que ele use o banco de dados Northwind. Se você trabalhou no tutorial anterior, já deve ter uma cadeia de conexão chamada NorthwindConnectionString
.Web.config
Escolha essa cadeia de conexão na lista suspensa, conforme mostrado na Figura 3.
Figura 03: Configurar o SqlDataSource para usar o banco de dados Northwind (clique para exibir a imagem em tamanho completo)
Em seguida, especifique a instrução do controle da SELECT
fonte de dados escolhendo a tabela Products na lista suspensa e retornando as colunas e UnitPrice
(consulte a ProductName
Figura 4). Clique em Avançar e, em seguida, em Concluir para concluir o assistente Configurar Fonte de Dados.
Figura 04: Retornar os ProductName
campos e UnitPrice
da tabela (clique para exibir a Products
imagem em tamanho real)
Isso é tudo! Depois de concluir o assistente, o Visual Studio adiciona dois BoundFields ao GridView para espelhar os dois campos retornados pelo controle SqlDataSource. A marcação dos controles GridView e SqlDataSource é a seguir. A Figura 5 mostra os resultados quando visualizados por meio de um navegador.
<asp:GridView ID="ProductsGrid" runat="server" AutoGenerateColumns="False"
DataSourceID="ProductsDataSource">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="ProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [ProductName], [UnitPrice] FROM [Products]">
</asp:SqlDataSource>
Figura 05: Cada produto e seu preço são listados no GridView (clique para exibir a imagem em tamanho real)
Observação
Sinta-se à vontade para limpar a aparência do GridView. Algumas sugestões incluem formatar o valor UnitPrice exibido como uma moeda e usar cores de fundo e fontes para melhorar a aparência da grade. Para obter mais informações sobre como exibir e formatar dados no ASP.NET, consulte minha série de tutoriais Trabalhando com Dados.
Etapa 2: Adicionando um botão de preços duplos à página mestra
Nossa próxima tarefa é adicionar um controle Web de botão à página mestra que, quando clicado, dobrará o preço de todos os produtos no banco de dados. Abra a Site.master
página mestra e arraste um Button da Caixa de Ferramentas para o Designer, colocando-o abaixo do RecentProductsDataSource
controle SqlDataSource que adicionamos no tutorial anterior. Defina a propriedade do ID
Botão como DoublePrice
" Text
Dobrar Preços do Produto".
Em seguida, adicione um controle SqlDataSource à página mestra, nomeando-a DoublePricesDataSource
. Esse SqlDataSource será usado para executar a UPDATE
instrução para dobrar todos os preços. Especificamente, precisamos definir suas ConnectionString
propriedades e UpdateCommand
para a cadeia de conexão e UPDATE
a instrução apropriadas. Em seguida, precisamos chamar esse método do Update
controle SqlDataSource quando o DoublePrice
botão é clicado. Para definir as ConnectionString
propriedades and UpdateCommand
, selecione o controle SqlDataSource e vá para a janela Propriedades. A ConnectionString
propriedade lista as cadeias de conexão já armazenadas Web.config
em uma lista suspensa; escolha a NorthwindConnectionString
opção como mostrado na Figura 6.
Figura 06: Configurar o SqlDataSource para usar o (clique para exibir a NorthwindConnectionString
imagem em tamanho completo)
Para definir a UpdateCommand
propriedade, localize a opção UpdateQuery na janela Propriedades. Essa propriedade, quando selecionada, exibe um botão com reticências; clique nesse botão para exibir a caixa de diálogo Editor de comandos e parâmetros mostrada na Figura 7. Digite a seguinte UPDATE
instrução na caixa de texto da caixa de diálogo:
UPDATE Products SET UnitPrice = UnitPrice * 2
Essa instrução, quando executada, dobrará o UnitPrice
valor de cada registro na Products
tabela.
Figura 07: Definir a propriedade de UpdateCommand
SqlDataSource (clique para exibir a imagem em tamanho real)
Depois de definir essas propriedades, a marcação declarativa dos controles Button e SqlDataSource deve ser semelhante à seguinte:
<asp:Button ID="DoublePrice" runat="server"
Text="Double Product Prices" />
<asp:SqlDataSource ID="DoublePricesDataSource" runat="server"
UpdateCommand="UPDATE Products SET UnitPrice = UnitPrice * 2"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
ProviderName="<%$ ConnectionStrings:NorthwindConnectionString.ProviderName %>">
</asp:SqlDataSource>
Tudo o que resta é chamar seu Update
método quando o DoublePrice
botão é clicado. Crie um manipulador de Click
eventos para o DoublePrice
Button e adicione o seguinte código:
protected void DoublePrice_Click(object sender, EventArgs e)
{
// Double the prices
DoublePricesDataSource.Update();
}
Para testar essa funcionalidade, visite a ~/Admin/Products.aspx
página que criamos na Etapa 1 e clique no botão "Dobrar preços de produtos". Clicar no botão causa um postback e executa o DoublePrice
manipulador de Click
eventos do botão, dobrando os preços de todos os produtos. A página é então renderizada novamente e a marcação é retornada e exibida novamente no navegador. O GridView na página de conteúdo, no entanto, lista os mesmos preços de antes de clicar no botão "Preços Duplos do Produto". Isso ocorre porque os dados inicialmente carregados no GridView tiveram seu estado armazenado no estado de exibição, portanto, eles não são recarregados em postbacks, a menos que sejam instruídos de outra forma. Se você visitar uma página diferente e retornar à página, ~/Admin/Products.aspx
verá os preços atualizados.
Etapa 3: Aumentar um evento quando os preços dobram
Como o ~/Admin/Products.aspx
GridView na página não reflete imediatamente a duplicação do preço, um usuário pode, compreensivelmente, pensar que não clicou no botão "Preços Duplos do Produto" ou que não funcionou. Eles podem tentar clicar no botão mais algumas vezes, dobrando os preços repetidamente. Para corrigir isso, precisamos que a grade na página de conteúdo exiba os novos preços imediatamente após serem dobrados.
Conforme discutido anteriormente neste tutorial, precisamos gerar um evento na página mestra sempre que o usuário clicar no DoublePrice
Button. Um evento é uma maneira de uma classe (um editor de eventos) notificar outra um conjunto de outras classes (os assinantes do evento) de que algo interessante ocorreu. Neste exemplo, a página mestra é o editor do evento; as páginas de conteúdo que se preocupam com quando o DoublePrice
botão é clicado são os assinantes.
Uma classe assina um evento criando um manipulador de eventos, que é um método executado em resposta ao evento que está sendo gerado. O editor define os eventos que ele gera definindo um delegado de evento. O delegado de evento especifica quais parâmetros de entrada o manipulador de eventos deve aceitar. No .NET Framework, os delegados de evento não retornam nenhum valor e aceitam dois parâmetros de entrada:
- Um
Object
, que identifica a origem do evento e - Uma classe derivada de
System.EventArgs
O segundo parâmetro passado para um manipulador de eventos pode incluir informações adicionais sobre o evento. Embora a classe base EventArgs
não passe nenhuma informação, o .NET Framework inclui várias classes que estendem EventArgs
e abrangem propriedades adicionais. Por exemplo, uma CommandEventArgs
instância é passada para manipuladores de eventos que respondem Command
ao evento e inclui duas propriedades informativas: CommandArgument
e CommandName
.
Observação
Para obter mais informações sobre como criar, gerar e manipular eventos, consulte Eventos e delegados e Delegados de eventos em inglês simples.
Para definir um evento, use a seguinte sintaxe:
public event eventDelegate eventName;
Como só precisamos alertar a página de conteúdo quando o usuário clica no DoublePrice
Button e não precisamos passar nenhuma outra informação adicional, podemos usar o delegado EventHandler
de evento , que define um manipulador de eventos que aceita como segundo parâmetro um objeto do tipo System.EventArgs
. Para criar o evento na página mestra, adicione a seguinte linha de código à classe code-behind da página mestra:
public partial class Site : System.Web.UI.MasterPage
{
public event EventHandler PricesDoubled;
...
}
O código acima adiciona um evento público à página mestra chamado PricesDoubled
. Agora precisamos aumentar este evento depois que os preços dobraram. Para gerar um evento, use a seguinte sintaxe:
if (eventName != null)
eventName(sender, eventArgs);
Onde sender e eventArgs são os valores que você deseja passar para o manipulador de eventos do assinante.
Atualize o manipulador de DoublePrice
Click
eventos com o seguinte código:
protected void DoublePrice_Click(object sender, EventArgs e)
{
// Double the prices
DoublePricesDataSource.Update();
// Refresh RecentProducts
RecentProducts.DataBind();
// Raise the PricesDoubled event
if (PricesDoubled != null)
PricesDoubled(this, EventArgs.Empty);
}
Como antes, o Click
manipulador de eventos começa chamando o DoublePricesDataSource
método do Update
controle SqlDataSource para dobrar os preços de todos os produtos. Depois disso, há duas adições ao manipulador de eventos. Primeiro, os RecentProducts
dados do GridView são atualizados. Esse GridView foi adicionado à página mestra no tutorial anterior e exibe os cinco produtos adicionados mais recentemente. Precisamos atualizar essa grade para que ela mostre os preços recém-dobrados para esses cinco produtos. Em seguida, o PricesDoubled
evento é levantado. Uma referência à própria página mestra (this
) é enviada ao manipulador de eventos como a origem do evento e um objeto vazio EventArgs
é enviado como os argumentos do evento.
Etapa 4: Manipulando o evento na página de conteúdo
Neste ponto, a página mestra gera seu PricesDoubled
evento sempre que o DoublePrice
controle Button é clicado. No entanto, isso é apenas metade da batalha - ainda precisamos lidar com o evento no assinante. Isso envolve duas etapas: criar o manipulador de eventos e adicionar código de conexão de eventos para que, quando o evento for gerado, o manipulador de eventos seja executado.
Comece criando um manipulador de eventos chamado Master_PricesDoubled
. Devido à forma como definimos o PricesDoubled
evento na página mestra, os dois parâmetros de entrada do manipulador de eventos devem ser dos tipos Object
e EventArgs
, respectivamente. No manipulador de eventos, chame o ProductsGrid
método do DataBind
GridView para reassociar os dados à grade.
private void Master_PricesDoubled(object sender, EventArgs e)
{
// Rebind data to ProductsGrid
ProductsGrid.DataBind();
}
O código do manipulador de eventos está completo, mas ainda não conectamos o evento da PricesDoubled
página mestra a esse manipulador de eventos. O assinante conecta um evento a um manipulador de eventos por meio da seguinte sintaxe:
publisher.eventName += new eventDelegate(methodName);
publisher é uma referência ao objeto que oferece o eventName e methodName é o nome do manipulador de eventos definido no assinante que tem uma assinatura correspondente ao eventDelegate. Em outras palavras, se o delegado de evento for EventHandler
, então methodName deve ser o nome de um método no assinante que não retorna um valor e aceita dois parâmetros de entrada de tipos Object
e EventArgs
, respectivamente.
Esse código de conexão de evento deve ser executado na primeira visita à página e nos postbacks subsequentes e deve ocorrer em um ponto no ciclo de vida da página que precede quando o evento pode ser gerado. Um bom momento para adicionar o código de conexão de eventos é no estágio PreInit, que ocorre muito cedo no ciclo de vida da página.
Abra ~/Admin/Products.aspx
e crie um manipulador de Page_PreInit
eventos:
protected void Page_PreInit(object sender, EventArgs e)
{
// TODO: Put event wiring logic here
}
Para completar esse código de conexão, precisamos de uma referência programática à página mestra da página de conteúdo. Conforme observado no tutorial anterior, há duas maneiras de fazer isso:
- Convertendo a propriedade de tipo
Page.Master
flexível para o tipo de página mestra apropriado ou - Adicionando uma
@MasterType
diretiva na.aspx
página e, em seguida, usando a propriedade fortemente tipadaMaster
.
Vamos usar a última abordagem. Adicione a seguinte @MasterType
diretiva à parte superior da marcação declarativa da página:
<%@ MasterType VirtualPath="~/Site.master" %>
Em seguida, adicione o seguinte código de conexão de eventos no manipulador de Page_PreInit
eventos:
protected void Page_PreInit(object sender, EventArgs e)
{
// Create an event handler for the master page's PricesDoubled event
Master.PricesDoubled += new EventHandler(Master_PricesDoubled);
}
Com esse código em vigor, o GridView na página de conteúdo é atualizado sempre que o DoublePrice
Botão é clicado.
As Figuras 8 e 9 ilustram esse comportamento. A Figura 8 mostra a página quando visitada pela primeira vez. Observe que os RecentProducts
valores de preço no GridView (na coluna esquerda da página mestra) e no ProductsGrid
GridView (na página de conteúdo). A Figura 9 mostra a mesma tela imediatamente após o DoublePrice
botão ter sido clicado. Como você pode ver, os novos preços são refletidos instantaneamente em ambos os GridViews.
Figura 08: Os valores iniciais do preço (clique para exibir a imagem em tamanho real)
Figura 09: Os preços recém-dobrados são exibidos no GridViews (clique para exibir a imagem em tamanho real)
Resumo
Idealmente, uma página mestra e suas páginas de conteúdo são completamente separadas uma da outra e não requerem nenhum nível de interação. No entanto, se você tiver uma página mestra ou uma página de conteúdo que exiba dados que podem ser modificados da página mestra ou da página de conteúdo, talvez seja necessário que a página mestra alerte a página de conteúdo (ou vice-versa) quando os dados forem modificados para que a exibição possa ser atualizada. No tutorial anterior, vimos como fazer com que uma página de conteúdo interaja programaticamente com sua página mestra; Neste tutorial, vimos como fazer com que uma página mestra inicie a interação.
Embora a interação programática entre um conteúdo e uma página mestra possa se originar do conteúdo ou da página mestra, o padrão de interação usado depende da origem. As diferenças se devem ao fato de que uma página de conteúdo tem uma única página mestra, mas uma página mestra pode ter muitas páginas de conteúdo diferentes. Em vez de ter uma página mestra interagindo diretamente com uma página de conteúdo, uma abordagem melhor é fazer com que a página mestra gere um evento para sinalizar que alguma ação ocorreu. As páginas de conteúdo que se preocupam com a ação podem criar manipuladores de eventos.
Boa programação!
Leitura Adicional
Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos:
- Acessando e atualizando dados no ASP.NET
- Eventos e Delegados
- Passando informações entre conteúdo e páginas mestras
- Trabalhando com dados em tutoriais 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