Interagir com a página de conteúdo através da página mestra (VB)

por Scott Mitchell

Examina como chamar métodos, definir propriedades etc. da Página de Conteúdo 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 de master. Lembre-se de que atualizamos a página master para incluir um controle GridView que listou os cinco produtos adicionados mais recentemente. Em seguida, criamos uma página de conteúdo 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 master 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 master 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 conteúdo e master interação de página se origina da página de conteúdo. No entanto, é possível que a página master desperte a página de conteúdo atual em ação, e essa funcionalidade poderá ser necessária se a página master contiver elementos de interface do usuário que permitem que os usuários modifiquem 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 master que inclui um controle Button que, quando clicado, dobra os preços de todos os produtos. Assim como o exemplo no tutorial anterior, o GridView precisa ser atualizado depois que o botão de preço duplo é clicado para que ele exiba os novos preços, mas nesse cenário é a página master que precisa despertar a página de conteúdo em ação.

Este tutorial explora como definir a funcionalidade de invocação de página master 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 de master é mais desafiador do que o contrário. Como uma página de conteúdo tem uma única página master, ao instigar a interação programática da página de conteúdo, sabemos quais métodos e propriedades públicos estão à nossa disposição. Uma página master, 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 master para executar alguma ação em sua página de conteúdo quando não soubermos qual página de conteúdo será invocada até o runtime?

Considere um controle web ASP.NET, 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 ela foi clicada. Isso é feito usando eventos. Em particular, o controle Button aciona seu Click evento quando é clicado; a página ASP.NET que contém o Botão 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 master em suas páginas de conteúdo:

  1. Adicione um evento à página master.
  2. Gere o evento sempre que a página master precisar se comunicar com sua página de conteúdo. Por exemplo, se a página master precisar alertar sua página de conteúdo de que o usuário dobrou os preços, seu evento será aumentado imediatamente após os preços terem sido dobrados.
  3. Crie um manipulador de eventos nessas 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 de master que inclui um controle Button para dobrar os preços.

Etapa 1: Exibindo produtos em uma página de conteúdo

Nossa primeira ordem de negócios é criar uma página de conteúdo que lista os produtos do banco de dados Northwind. (Adicionamos o banco de dados Northwind ao projeto no tutorial anterior, Interagindo com a página mestra da página de conteúdo.) Comece adicionando uma nova página ASP.NET à ~/Admin pasta chamada Products.aspx, associando-a Site.master à página master. A Figura 1 mostra o Gerenciador de Soluções depois que essa página é adicionada ao site.

Adicionar uma nova página de ASP.NET à pasta Administração

Figura 01: Adicionar uma nova página de ASP.NET à Admin pasta (clique para exibir a imagem em tamanho real)

Lembre-se de que, no tutorial Especificando o título, metamaras 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 ).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 de <siteMapNode> para a lição de Interação de Conteúdo à 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).

Retorne para Products.aspx. No controle Conteúdo de MainContent, adicione um controle GridView e nomeie-o ProductsGridcomo . Associe o GridView a um novo controle SqlDataSource chamado ProductsDataSource.

Associar GridView a um novo controle SqlDataSource

Figura 02: Associar o GridView a um novo controle SqlDataSource (clique para exibir a imagem em tamanho real)

Configure o assistente para que ele use o banco de dados Northwind. Se você trabalhou no tutorial anterior, já deve ter um cadeia de conexão nomeado NorthwindConnectionString em Web.config. Escolha esta cadeia de conexão na lista suspensa, conforme mostrado na Figura 3.

Configurar o SqlDataSource para usar o banco de dados Northwind

Figura 03: Configurar o SqlDataSource para usar o banco de dados Northwind (clique para exibir a imagem em tamanho real)

Em seguida, especifique a instrução do controle da SELECT fonte de dados escolhendo a tabela Products na lista suspensa e retornando as ProductName colunas e UnitPrice (consulte a Figura 4). Clique em Avançar e em Concluir para concluir o assistente Configurar Fonte de Dados.

Retornar os campos ProductName e UnitPrice da tabela Products

Figura 04: Retornar os ProductName campos e UnitPrice da Products tabela (clique para exibir a imagem em tamanho real)

Isso é tudo! Depois de concluir o assistente, o Visual Studio adiciona dois BoundFields ao GridView para espelho os dois campos retornados pelo controle SqlDataSource. A marcação dos controles GridView e SqlDataSource segue. A Figura 5 mostra os resultados quando exibidos 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>

Cada produto e seu preço são listados no GridView

Figura 05: Cada produto e seu preço são listados no GridView (clique para exibir a imagem em tamanho real)

Observação

Fique à vontade para limpo a aparência do GridView. Algumas sugestões incluem a formatação do valor UnitPrice exibido como uma moeda e o uso de cores e fontes de plano de fundo para melhorar a aparência da grade. Para obter mais informações sobre como exibir e formatar dados em ASP.NET, consulte minha série de tutoriais Trabalhando com Dados.

Etapa 2: adicionar um botão De preços duplos à página mestra

Nossa próxima tarefa é adicionar um controle Web button à página master que, quando clicado, dobrará o preço de todos os produtos no banco de dados. Abra a Site.master página master e arraste um Botão 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 e sua Text propriedade como "Preços duplos do produtoDoublePrice".

Em seguida, adicione um controle SqlDataSource à página master, nomeando-o DoublePricesDataSourcecomo . Esse SqlDataSource será usado para executar a instrução UPDATE para dobrar todos os preços. Especificamente, precisamos definir suas ConnectionString propriedades e UpdateCommand para a cadeia de conexão e UPDATE instrução apropriadas. Em seguida, precisamos chamar o método do Update controle SqlDataSource quando o DoublePrice botão é clicado. Para definir as ConnectionString propriedades e UpdateCommand , selecione o controle SqlDataSource e vá para o janela Propriedades. A ConnectionString propriedade lista as cadeias de conexão já armazenadas em Web.config uma lista suspensa; escolha a opção NorthwindConnectionString conforme mostrado na Figura 6.

Configurar o SqlDataSource para usar NorthwindConnectionString

Figura 06: Configurar o SqlDataSource para usar o NorthwindConnectionString (Clique para exibir a imagem em tamanho real)

Para definir a UpdateCommand propriedade, localize a opção UpdateQuery no janela Propriedades. Essa propriedade, quando selecionada, exibe um botão com reticências; clique neste botão para exibir a caixa de diálogo Comando e Parâmetro Editor 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.

Definir a propriedade UpdateCommand do SqlDataSource

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 deverá 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 Click manipulador de eventos para o DoublePrice Botão e adicione o seguinte código:

Protected Sub DoublePrice_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DoublePrice.Click
 ' Double the prices
 DoublePricesDataSource.Update()
End Sub

Para testar essa funcionalidade, visite a ~/Admin/Products.aspx página que criamos na Etapa 1 e clique no botão "Preços duplos do produto". Clicar no botão causa um postback e executa o DoublePrice manipulador de eventos do Click Botão, dobrando os preços de todos os produtos. Em seguida, a página é 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 do clique do botão "Preços duplos do produto". Isso ocorre porque os dados inicialmente carregados no GridView tinham seu estado armazenado no estado de exibição, portanto, 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 à ~/Admin/Products.aspx página, verá os preços atualizados.

Etapa 3: Gerando um evento quando os preços são duplicados

Como o GridView na ~/Admin/Products.aspx página não reflete imediatamente a duplicação do preço, um usuário pode pensar compreensivelmente 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 várias vezes. 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 master sempre que o usuário clicar no DoublePrice Botão. Um evento é uma maneira de uma classe (um editor de eventos) notificar outro de um conjunto de outras classes (os assinantes do evento) de que algo interessante ocorreu. Neste exemplo, a página master é o editor de eventos; as páginas de conteúdo que se preocupam 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 gerados pela definição de um delegado de eventos. O delegado de eventos especifica quais parâmetros de entrada o manipulador de eventos deve aceitar. No .NET Framework, os delegados de eventos 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 transmita 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 ao Command 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 eventName As eventDelegate

Como só precisamos alertar a página de conteúdo quando o usuário clicar no DoublePrice Botão e não precisar passar outras informações adicionais, podemos usar o delegado EventHandlerde eventos , que define um manipulador de eventos que aceita como seu segundo parâmetro um objeto do tipo System.EventArgs. Para criar o evento na página master, adicione a seguinte linha de código à classe code-behind da página master:

Partial Class Site
 Inherits System.Web.UI.MasterPage

 Public Event PricesDoubled As EventHandler
 ...
End Class

O código acima adiciona um evento público à página master chamada PricesDoubled. Agora precisamos aumentar este evento depois que os preços forem dobrados. Para gerar um evento, use a seguinte sintaxe:

RaiseEvent eventName(sender, eventArgs)

Onde remetente e eventArgs são os valores que você deseja passar para o manipulador de eventos do assinante.

Atualize o DoublePriceClick manipulador de eventos com o seguinte código:

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
 RaiseEvent PricesDoubled(Me, EventArgs.Empty)
End Sub

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. Este GridView foi adicionado à página master no tutorial anterior e exibe os cinco produtos adicionados mais recentemente. Precisamos atualizar essa grade para que ela mostre os preços apenas duplicados desses cinco produtos. Depois disso, o PricesDoubled evento é gerado. Uma referência à própria página master (Me) é 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 master aciona 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 fiação de evento para que, quando o evento for acionado, 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 master, os dois parâmetros de entrada do manipulador de eventos devem ser de tipos Object e EventArgs, respectivamente. No manipulador de eventos, chame o ProductsGrid método gridview DataBind para reassociar os dados à grade.

Private Sub Master_PricesDoubled(ByVal sender As Object, ByVal e As EventArgs)
 ' Rebind data to ProductsGrid
 ProductsGrid.DataBind()
End Sub

O código do manipulador de eventos foi concluído, mas ainda não conectamos o evento da PricesDoubled página master a esse manipulador de eventos. O assinante conecta um evento a um manipulador de eventos por meio da seguinte sintaxe:

AddHandler publisher.eventName, AddressOf methodName

publisher é uma referência ao objeto que oferece o event eventName e methodName é o nome do manipulador de eventos definido no assinante.

Esse código de fiação de evento deve ser executado na primeira visita de página e 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 código de fiação de evento está 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 Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreInit
 ' TODO: Put event wiring logic here
End Sub

Para concluir esse código de fiação, precisamos de uma referência programática à página master 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 de master apropriado ou
  • Adicionando uma @MasterType diretiva na .aspx página e, em seguida, usando a propriedade fortemente tipada Master .

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 fiação de evento no Page_PreInit manipulador de eventos:

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreInit
 AddHandler Master.PricesDoubled, AddressOf Master_PricesDoubled
End Sub

Com esse código em vigor, o GridView na página de conteúdo é atualizado sempre que o DoublePrice Botão é clicado.

Os números 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 master) 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.

Os valores de preço iniciais

Figura 08: os valores de preço iniciais (clique para exibir a imagem em tamanho real)

Os preços Just-Doubled são exibidos em GridViews

Figura 09: os preços do Just-Doubled são exibidos no GridViews (Clique para exibir a imagem em tamanho real)

Resumo

O ideal é que uma página master e suas páginas de conteúdo sejam completamente separadas umas das outras e não exijam nenhum nível de interação. No entanto, se você tiver uma página master ou de conteúdo que exibe dados que podem ser modificados da página master ou do conteúdo, talvez seja necessário que a página master 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 master; neste tutorial, analisamos como fazer com que uma página master inicie a interação.

Embora a interação programática entre um conteúdo e master página possa se originar do conteúdo ou master página, o padrão de interação usado depende da origem. As diferenças ocorrem devido ao fato de que uma página de conteúdo tem uma única página master, mas uma página master pode ter muitas páginas de conteúdo diferentes. Em vez de ter uma página master interagir diretamente com uma página de conteúdo, uma abordagem melhor é fazer com que a página master gere um evento para sinalizar que alguma ação ocorreu. Essas páginas de conteúdo que se preocupam com a ação podem criar manipuladores de eventos.

Programação feliz!

Leitura Adicional

Para obter mais informações sobre os tópicos discutidos neste tutorial, consulte os seguintes recursos:

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, solte-me uma linha em mitchell@4GuysFromRolla.com