Compartilhar via


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:

  1. Adicione um evento à página mestra.
  2. 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.
  3. 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.

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

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.

Associar o GridView a um novo controle SqlDataSource

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.

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 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.

Retorne os campos ProductName e UnitPrice da tabela Products

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>

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

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.

Configurar o SqlDataSource para usar o NorthwindConnectionString

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.

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 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 EventHandlerde 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 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 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.

Os valores de preço iniciais

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

Os preços recém-dobrados são exibidos no GridViews

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:

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