Compartilhar via


Adicionar e responder a botões em um GridView (C#)

por Scott Mitchell

Baixar PDF

Neste tutorial, veremos como adicionar botões personalizados, tanto a um modelo quanto aos campos de um controle GridView ou DetailsView. Em particular, criaremos uma interface que possui um FormView que permite ao usuário percorrer as páginas dos fornecedores.

Introdução

Embora muitos cenários de relatório envolvam acesso somente leitura aos dados do relatório, não é incomum que os relatórios incluam a capacidade de executar ações com base nos dados exibidos. Normalmente, isso envolvia a adição de um controle Web Button, LinkButton ou ImageButton com cada registro exibido no relatório que, quando clicado, causa um postback e invoca algum código do lado do servidor. Editar e excluir os dados registro por registro é o exemplo mais comum. Na verdade, como vimos a partir do tutorial Visão geral da inserção, atualização e exclusão de dados , a edição e a exclusão são tão comuns que os controles GridView, DetailsView e FormView podem dar suporte a essa funcionalidade sem a necessidade de escrever uma única linha de código.

Além dos botões Editar e Excluir, os controles GridView, DetailsView e FormView também podem incluir Buttons, LinkButtons ou ImageButtons que, quando clicados, executam alguma lógica personalizada do lado do servidor. Neste tutorial, veremos como adicionar botões personalizados, tanto a um modelo quanto aos campos de um controle GridView ou DetailsView. Em particular, criaremos uma interface que possui um FormView que permite ao usuário percorrer as páginas dos fornecedores. Para um determinado fornecedor, o FormView mostrará informações sobre o fornecedor junto com um controle Web de botão que, se clicado, marcará todos os produtos associados como descontinuados. Além disso, um GridView lista os produtos fornecidos pelo fornecedor selecionado, com cada linha contendo botões de aumento de preço e preço com desconto que, se clicados, aumentam ou reduzem o produto UnitPrice em 10% (consulte a Figura 1).

Tanto o FormView quanto o GridView contêm botões que executam ações personalizadas

Figura 1: O FormView e o GridView contêm botões que executam ações personalizadas (clique para exibir a imagem em tamanho real)

Etapa 1: Adicionando as páginas da Web do tutorial do botão

Antes de vermos como adicionar botões personalizados, vamos primeiro criar as páginas ASP.NET em nosso projeto de site que precisaremos para este tutorial. Comece adicionando uma nova pasta chamada CustomButtons. Em seguida, adicione as duas páginas ASP.NET a seguir a essa pasta, certificando-se de associar cada página à Site.master página mestra:

  • Default.aspx
  • CustomButtons.aspx

Adicione as páginas ASP.NET para os tutoriais relacionados a botões personalizados

Figura 2: Adicionar as páginas ASP.NET para os tutoriais relacionados a botões personalizados

Como nas outras pastas, Default.aspx na CustomButtons pasta listará os tutoriais em sua seção. Lembre-se de que o SectionLevelTutorialListing.ascx Controle de Usuário fornece essa funcionalidade. Portanto, adicione esse Controle de Usuário arrastando-o Default.aspx do Gerenciador de Soluções para o modo de exibição Design da página.

Adicione o controle de usuário SectionLevelTutorialListing.ascx a Default.aspx

Figura 3: Adicionar o controle de usuário a Default.aspx (clique para exibir a SectionLevelTutorialListing.ascx imagem em tamanho real)

Por fim, adicione as páginas como entradas ao Web.sitemap arquivo. Especificamente, adicione a seguinte marcação após a Paginação <siteMapNode>e Classificação:

<siteMapNode
    title="Adding Custom Buttons"
    description="Samples of Reports that Include Buttons for Performing
                  Server-Side Actions"
    url="~/CustomButtons/Default.aspx">
    <siteMapNode
        title="Using ButtonFields and Buttons in Templates"
        description="Examines how to add custom Buttons, LinkButtons,
                      or ImageButtons as ButtonFields or within templates."
        url="~/CustomButtons/CustomButtons.aspx" />
</siteMapNode>

Após a atualização Web.sitemap, reserve um momento para visualizar o site de tutoriais por meio de um navegador. O menu à esquerda agora inclui itens para os tutoriais de edição, inserção e exclusão.

O mapa do site agora inclui a entrada para o tutorial Botões personalizados

Figura 4: O mapa do site agora inclui a entrada para o tutorial de botões personalizados

Etapa 2: Adicionando um FormView que lista os fornecedores

Vamos começar com este tutorial adicionando o FormView que lista os fornecedores. Conforme discutido na Introdução, este FormView permitirá que o usuário percorra as páginas dos fornecedores, mostrando os produtos fornecidos pelo fornecedor em um GridView. Além disso, este FormView incluirá um botão que, quando clicado, marcará todos os produtos do fornecedor como descontinuados. Antes de nos preocuparmos em adicionar o botão personalizado ao FormView, vamos primeiro criar o FormView para que ele exiba as informações do fornecedor.

Comece abrindo a CustomButtons.aspx CustomButtons página na pasta. Adicione um FormView à página arrastando-o da Caixa de Ferramentas para o Designer e defina sua ID propriedade como Suppliers. Na marca inteligente do FormView, opte por criar um novo ObjectDataSource chamado SuppliersDataSource.

Criar um novo ObjectDataSource chamado SuppliersDataSource

Figura 5: Criar um novo ObjectDataSource nomeado SuppliersDataSource (clique para exibir a imagem em tamanho completo)

Configure esse novo ObjectDataSource de modo que ele consulte o método da GetSuppliers() classe (consulte a SuppliersBLL Figura 6). Como esse FormView não fornece uma interface para atualizar as informações do fornecedor, selecione a opção (Nenhum) na lista suspensa na guia ATUALIZAR.

Configurar a fonte de dados para usar o método GetSuppliers() da classe SuppliersBLL

Figura 6: Configurar a fonte de dados para usar o método da GetSuppliers() classe (clique para exibir a SuppliersBLL imagem em tamanho real)

Depois de configurar o ObjectDataSource, o Visual Studio gerará um InsertItemTemplate, EditItemTemplatee para ItemTemplate o FormView. Remova o InsertItemTemplate e EditItemTemplate modifique o ItemTemplate para que ele exiba apenas o nome da empresa e o número de telefone do fornecedor. Por fim, ative o suporte à paginação para o FormView marcando a caixa de seleção Habilitar paginação em sua marca inteligente (ou definindo sua AllowPaging propriedade como True). Após essas alterações, a marcação declarativa da página deve ser semelhante à seguinte:

<asp:FormView ID="Suppliers" runat="server" DataKeyNames="SupplierID"
    DataSourceID="SuppliersDataSource" EnableViewState="False" AllowPaging="True">
    <ItemTemplate>
        <h3>
            <asp:Label ID="CompanyName" runat="server"
                Text='<%# Bind("CompanyName") %>' />
        </h3>
        <b>Phone:</b>
        <asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>' />
    </ItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliers" TypeName="SuppliersBLL">
</asp:ObjectDataSource>

A Figura 7 mostra a página CustomButtons.aspx quando visualizada por meio de um navegador.

O FormView lista os campos CompanyName e Phone do fornecedor selecionado no momento

Figura 7: O FormView lista os CompanyName campos e Phone do fornecedor selecionado no momento (clique para exibir a imagem em tamanho real)

Etapa 3: Adicionando um GridView que lista os produtos do fornecedor selecionado

Antes de adicionarmos o botão Descontinuar todos os produtos ao modelo do FormView, vamos primeiro adicionar um GridView abaixo do FormView que lista os produtos fornecidos pelo fornecedor selecionado. Para fazer isso, adicione um GridView à página, defina sua ID propriedade como SuppliersProductse adicione um novo ObjectDataSource chamado SuppliersProductsDataSource.

Criar um novo ObjectDataSource chamado SuppliersProductsDataSource

Figura 8: Criar um novo ObjectDataSource nomeado SuppliersProductsDataSource (clique para exibir a imagem em tamanho completo)

Configure esse ObjectDataSource para usar o método da GetProductsBySupplierID(supplierID) classe ProductsBLL (consulte a Figura 9). Embora esse GridView permita que o preço de um produto seja ajustado, ele não usará os recursos internos de edição ou exclusão do GridView. Portanto, podemos definir a lista suspensa como (Nenhum) para as guias UPDATE, INSERT e DELETE do ObjectDataSource.

Configurar a fonte de dados para usar o método ProductsBLL GetProductsBySupplierID(supplierID) da classe

Figura 9: Configurar a fonte de dados para usar o método da GetProductsBySupplierID(supplierID) classe (clique para exibir a ProductsBLL imagem em tamanho real)

Como o GetProductsBySupplierID(supplierID) método aceita um parâmetro de entrada, o assistente ObjectDataSource nos solicita a origem desse valor de parâmetro. Para passar o SupplierID valor do FormView, defina a lista suspensa Origem do parâmetro como Control e a lista suspensa ControlID como Suppliers (a ID do FormView criado na Etapa 2).

Indique que o parâmetro supplierID deve vir do controle FormView de fornecedores

Figura 10: Indicar que o supplierID parâmetro deve vir do controle FormView (clique para exibir a Suppliers imagem em tamanho real)

Depois de concluir o assistente ObjectDataSource, o GridView conterá um BoundField ou CheckBoxField para cada um dos campos de dados do produto. Vamos cortar isso para mostrar apenas o ProductName e UnitPrice BoundFields junto com o Discontinued CheckBoxField; além disso, vamos formatar o UnitPrice BoundField de forma que seu texto seja formatado como uma moeda. A marcação declarativa de GridView e SuppliersProductsDataSource ObjectDataSource deve ser semelhante à seguinte marcação:

<asp:GridView ID="SuppliersProducts" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="SuppliersProductsDataSource"
    EnableViewState="False" runat="server">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersProductsDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProductsBySupplierID" TypeName="ProductsBLL">
    <SelectParameters>
        <asp:ControlParameter ControlID="Suppliers" Name="supplierID"
            PropertyName="SelectedValue" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

Neste ponto, nosso tutorial exibe um relatório mestre/detalhes, permitindo que o usuário escolha um fornecedor no FormView na parte superior e exiba os produtos fornecidos por esse fornecedor por meio do GridView na parte inferior. A Figura 11 mostra uma captura de tela dessa página ao selecionar o fornecedor Tokyo Traders no FormView.

Os produtos do fornecedor selecionado são exibidos no GridView

Figura 11: Os produtos do fornecedor selecionado são exibidos no GridView (clique para exibir a imagem em tamanho real)

Etapa 4: Criando métodos DAL e BLL para descontinuar todos os produtos de um fornecedor

Antes de podermos adicionar um Button ao FormView que, quando clicado, descontinua todos os produtos do fornecedor, primeiro precisamos adicionar um método ao DAL e à BLL que executa essa ação. Em particular, este método será denominado DiscontinueAllProductsForSupplier(supplierID). Quando o botão do FormView for clicado, invocaremos esse método na camada lógica de negócios, passando o do fornecedor SupplierIDselecionado; a BLL chamará o método da camada de acesso a dados correspondente, que emitirá uma UPDATE instrução para o banco de dados que descontinua os produtos do fornecedor especificado.

Como fizemos em nossos tutoriais anteriores, usaremos uma abordagem de baixo para cima, começando com a criação do método DAL, depois o método BLL e, finalmente, implementando a funcionalidade na página ASP.NET. Abra o Northwind.xsd Conjunto de Dados Digitado App_Code/DAL na pasta e adicione um novo método ao (clique com o ProductsTableAdapter botão direito do ProductsTableAdapter mouse e escolha Adicionar Consulta). Isso abrirá o assistente de Configuração de Consulta TableAdapter, que nos orienta no processo de adição do novo método. Comece indicando que nosso método DAL usará uma instrução SQL ad-hoc.

Criar o método DAL usando uma instrução SQL ad hoc

Figura 12: Criar o método DAL usando uma instrução SQL ad hoc (clique para exibir a imagem em tamanho real)

Em seguida, o assistente nos pergunta sobre o tipo de consulta a ser criada. Como o DiscontinueAllProductsForSupplier(supplierID) método precisará atualizar a tabela do Products banco de dados, definindo o Discontinued campo como 1 para todos os produtos fornecidos pelo especificado supplierID, precisamos criar uma consulta que atualize os dados.

Escolha o tipo de consulta UPDATE

Figura 13: Escolha o tipo de consulta UPDATE (clique para exibir a imagem em tamanho real)

A próxima tela do assistente fornece a instrução existente UPDATE do TableAdapter, que atualiza cada um dos campos definidos no Products DataTable. Substitua esse texto de consulta pela seguinte instrução:

UPDATE [Products] SET
   Discontinued = 1
WHERE SupplierID = @SupplierID

Depois de inserir essa consulta e clicar em Avançar, a última tela do assistente solicita o nome do novo método use DiscontinueAllProductsForSupplier. Conclua o assistente clicando no botão Concluir. Ao retornar ao DataSet Designer, você deverá ver um novo método no ProductsTableAdapter .DiscontinueAllProductsForSupplier(@SupplierID)

Nomeie o novo método DAL DiscontinueAllProductsForSupplier

Figura 14: Nomeie o novo método DiscontinueAllProductsForSupplier DAL (clique para exibir a imagem em tamanho real)

Com o DiscontinueAllProductsForSupplier(supplierID) método criado na Camada de Acesso a Dados, nossa próxima tarefa é criar o DiscontinueAllProductsForSupplier(supplierID) método na Camada Lógica de Negócios. Para fazer isso, abra o arquivo de ProductsBLL classe e adicione o seguinte:

public int DiscontinueAllProductsForSupplier(int supplierID)
{
    return Adapter.DiscontinueAllProductsForSupplier(supplierID);
}

Esse método simplesmente chama o DiscontinueAllProductsForSupplier(supplierID) método no DAL, passando o valor do parâmetro fornecido supplierID . Se houvesse alguma regra de negócios que permitisse que os produtos de um fornecedor fossem descontinuados apenas em determinadas circunstâncias, essas regras deveriam ser implementadas aqui, na BLL.

Observação

Ao contrário das UpdateProduct sobrecargas na ProductsBLL classe, a assinatura do DiscontinueAllProductsForSupplier(supplierID) método não inclui o DataObjectMethodAttribute atributo (<System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, Boolean)>). Isso impede o DiscontinueAllProductsForSupplier(supplierID) método da lista suspensa do assistente Configurar Fonte de Dados do ObjectDataSource na guia UPDATE. Omiti esse atributo porque chamaremos o DiscontinueAllProductsForSupplier(supplierID) método diretamente de um manipulador de eventos em nossa página ASP.NET.

Etapa 5: Adicionando um botão Descontinuar todos os produtos ao FormView

Com o DiscontinueAllProductsForSupplier(supplierID) método na BLL e DAL concluído, a etapa final para adicionar a capacidade de descontinuar todos os produtos para o fornecedor selecionado é adicionar um controle Web Button ao arquivo .ItemTemplate Vamos adicionar esse botão abaixo do número de telefone do fornecedor com o texto do botão Descontinuar todos os produtos e um ID valor de propriedade de DiscontinueAllProductsForSupplier. Você pode adicionar esse controle Web de botão por meio do Designer clicando no link Editar modelos na marca inteligente do FormView (consulte a Figura 15) ou diretamente por meio da sintaxe declarativa.

Adicionar um controle Web de botão Descontinuar todos os produtos ao FormView ItemTemplate

Figura 15: Adicionar um controle Web do botão Descontinuar todos os produtos ao FormView ItemTemplate (clique para exibir a imagem em tamanho completo)

Quando o Button é clicado por um usuário que visita a página, ocorre um postback e o evento do ItemCommand FormView é acionado. Para executar código personalizado em resposta a esse botão que está sendo clicado, podemos criar um manipulador de eventos para esse evento. Compreenda, porém, que o ItemCommand evento é acionado sempre que qualquer controle Web Button, LinkButton ou ImageButton é clicado no FormView. Isso significa que, quando o usuário se move de uma página para outra no FormView, o evento é acionado; a ItemCommand mesma coisa quando o usuário clica em Novo, Editar ou Excluir em um FormView que oferece suporte à inserção, atualização ou exclusão.

Como o ItemCommand é acionado independentemente de qual botão é clicado, no manipulador de eventos, precisamos de uma maneira de determinar se o botão Descontinuar todos os produtos foi clicado ou se foi algum outro botão. Para fazer isso, podemos definir a propriedade do CommandName controle Web Button como algum valor de identificação. Quando o botão é clicado, esse CommandName valor é passado para o manipulador de ItemCommand eventos, permitindo determinar se o botão Descontinuar todos os produtos foi clicado. Defina a propriedade do botão Descontinuar todos os CommandName produtos como DiscontinueProducts .

Por fim, vamos usar uma caixa de diálogo de confirmação do lado do cliente para garantir que o usuário realmente queira descontinuar os produtos do fornecedor selecionado. Como vimos no tutorial Adicionando confirmação do lado do cliente ao excluir , isso pode ser feito com um pouco de JavaScript. Em particular, defina a propriedade OnClientClick do controle Web Button como return confirm('This will mark _all_ of this supplier\'s products as discontinued. Are you certain you want to do this?');

Depois de fazer essas alterações, a sintaxe declarativa do FormView deve ser semelhante à seguinte:

<asp:FormView ID="Suppliers" runat="server" DataKeyNames="SupplierID"
    DataSourceID="SuppliersDataSource" EnableViewState="False"
    AllowPaging="True">
    <ItemTemplate>
        <h3><asp:Label ID="CompanyName" runat="server"
            Text='<%# Bind("CompanyName") %>'></asp:Label></h3>
        <b>Phone:</b>
        <asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>' />
        <br />
        <asp:Button ID="DiscontinueAllProductsForSupplier" runat="server"
            CommandName="DiscontinueProducts" Text="Discontinue All Products"
            OnClientClick="return confirm('This will mark _all_ of this supplier\'s
                products as discontinued. Are you certain you want to do this?');" />
    </ItemTemplate>
</asp:FormView>

Em seguida, crie um manipulador de eventos para o evento do ItemCommand FormView. Neste manipulador de eventos, precisamos primeiro determinar se o botão Descontinuar todos os produtos foi clicado. Em caso afirmativo, queremos criar uma instância da ProductsBLL classe e invocar seu DiscontinueAllProductsForSupplier(supplierID) método, passando o SupplierID FormView selecionado:

protected void Suppliers_ItemCommand(object sender, FormViewCommandEventArgs e)
{
    if (e.CommandName.CompareTo("DiscontinueProducts") == 0)
    {
        // The "Discontinue All Products" Button was clicked.
        // Invoke the ProductsBLL.DiscontinueAllProductsForSupplier(supplierID) method
        // First, get the SupplierID selected in the FormView
        int supplierID = (int)Suppliers.SelectedValue;
        // Next, create an instance of the ProductsBLL class
        ProductsBLL productInfo = new ProductsBLL();
        // Finally, invoke the DiscontinueAllProductsForSupplier(supplierID) method
        productInfo.DiscontinueAllProductsForSupplier(supplierID);
    }
}

Observe que o SupplierID fornecedor selecionado atual no FormView pode ser acessado usando a propriedade do SelectedValue FormView. A SelectedValue propriedade retorna o primeiro valor de chave de dados para o registro que está sendo exibido no FormView. A propriedade do DataKeyNames FormView, que indica os campos de dados dos quais os valores de chave de dados são extraídos, foi definida automaticamente pelo SupplierID Visual Studio ao associar o ObjectDataSource ao FormView na Etapa 2.

Com o manipulador de ItemCommand eventos criado, reserve um momento para testar a página. Navegue até o fornecedor Cooperativa de Quesos 'Las Cabras' (é o quinto fornecedor no FormView para mim). Este fornecedor fornece dois produtos, Queso Cabrales e Queso Manchego La Pastora, ambos sem continuação.

Imagine que a Cooperativa de Quesos 'Las Cabras' faliu e, portanto, seus produtos serão descontinuados. Clique no botão Descontinuar todos os produtos. Isso exibirá a caixa de diálogo de confirmação do lado do cliente (consulte a Figura 16).

Cooperativa de Quesos Las Cabras fornece dois produtos ativos

Figura 16: Cooperativa de Quesos Las Cabras fornece dois produtos ativos (Clique para ver a imagem em tamanho maior)

Se você clicar em OK na caixa de diálogo de confirmação do lado do cliente, o envio do formulário continuará, causando um postback no qual o evento do ItemCommand FormView será acionado. O manipulador de eventos que criamos será executado, invocando o DiscontinueAllProductsForSupplier(supplierID) método e descontinuando os produtos Queso Cabrales e Queso Manchego La Pastora.

Se você tiver desabilitado o estado de exibição do GridView, o GridView estará sendo reassociado ao armazenamento de dados subjacente em cada postback e, portanto, será atualizado imediatamente para refletir que esses dois produtos foram descontinuados (consulte a Figura 17). Se, no entanto, você não tiver desabilitado o estado de exibição no GridView, precisará reassociar manualmente os dados ao GridView depois de fazer essa alteração. Para fazer isso, basta fazer uma chamada para o método do DataBind() GridView imediatamente após invocar o DiscontinueAllProductsForSupplier(supplierID) método.

Depois de clicar no botão Descontinuar todos os produtos, os produtos do fornecedor são atualizados de acordo

Figura 17: Depois de clicar no botão Descontinuar todos os produtos, os produtos do fornecedor são atualizados de acordo (clique para exibir a imagem em tamanho real)

Etapa 6: Criando uma sobrecarga UpdateProduct na camada lógica de negócios para ajustar o preço de um produto

Assim como no botão Descontinuar todos os produtos no FormView, para adicionar botões para aumentar e diminuir o preço de um produto no GridView, precisamos primeiro adicionar os métodos apropriados da Camada de Acesso a Dados e da Camada de Lógica de Negócios. Como já temos um método que atualiza uma única linha de produto no DAL, podemos fornecer essa funcionalidade criando uma nova sobrecarga para o UpdateProduct método na BLL.

Nossas sobrecargas anteriores UpdateProduct incluíram alguma combinação de campos de produto como valores de entrada escalares e, em seguida, atualizaram apenas esses campos para o produto especificado. Para essa sobrecarga, vamos variar um pouco desse padrão e, em vez disso, passar o produto ProductID e a porcentagem pela qual ajustar o UnitPrice (em vez de passar o novo, ajustado UnitPrice ). Essa abordagem simplificará o código que precisamos escrever na classe code-behind da página ASP.NET, já que não precisamos nos preocupar em determinar o arquivo UnitPrice.

A UpdateProduct sobrecarga para este tutorial é mostrada abaixo:

public bool UpdateProduct(decimal unitPriceAdjustmentPercentage, int productID)
{
    Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
    if (products.Count == 0)
        // no matching record found, return false
        return false;
    Northwind.ProductsRow product = products[0];
    // Adjust the UnitPrice by the specified percentage (if it's not NULL)
    if (!product.IsUnitPriceNull())
        product.UnitPrice *= unitPriceAdjustmentPercentage;
    // Update the product record
    int rowsAffected = Adapter.Update(product);
    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}

Essa sobrecarga recupera informações sobre o produto especificado por meio do GetProductByProductID(productID) método do DAL. Em seguida, ele verifica se o produto está atribuído a um valor de banco de UnitPrice dados NULL . Se for, o preço permanece inalterado. Se, no entanto, houver um valor não-NULLUnitPrice, o método atualiza o produto UnitPrice pela porcentagem especificada (unitPriceAdjustmentPercent).

Etapa 7: Adicionando os botões Aumentar e Diminuir ao GridView

O GridView (e o DetailsView) são compostos por uma coleção de campos. Além de BoundFields, CheckBoxFields e TemplateFields, ASP.NET inclui o ButtonField, que, como o próprio nome indica, é renderizado como uma coluna com um Button, LinkButton ou ImageButton para cada linha. Semelhante ao FormView, clicar em qualquer botão nos botões de paginação do GridView, nos botões Editar ou Excluir, nos botões de classificação e assim por diante causa um postback e gera o evento do RowCommand GridView.

O ButtonField tem uma CommandName propriedade que atribui o valor especificado a cada uma de suas propriedades Buttons CommandName . Assim como no FormView, o CommandName valor é usado pelo manipulador de RowCommand eventos para determinar qual botão foi clicado.

Vamos adicionar dois novos ButtonFields ao GridView, um com um texto de botão Price +10% e outro com o texto Price -10%. Para adicionar esses ButtonFields, clique no link Editar Colunas na marca inteligente do GridView, selecione o tipo de campo ButtonField na lista no canto superior esquerdo e clique no botão Adicionar.

Adicionar dois ButtonFields ao GridView

Figura 18: Adicionar dois ButtonFields ao GridView

Mova os dois ButtonFields para que eles apareçam como os dois primeiros campos GridView. Em seguida, defina as Text propriedades desses dois ButtonFields como Price +10% e Price -10% e as CommandName propriedades como IncreasePrice e DecreasePrice, respectivamente. Por padrão, um ButtonField renderiza sua coluna de botões como LinkButtons. Isso pode ser alterado, no entanto, por meio da ButtonType propriedade do ButtonField. Vamos renderizar esses dois ButtonFields como botões regulares; portanto, defina a ButtonType propriedade como Button. A Figura 19 mostra a caixa de diálogo Campos depois que essas alterações foram feitas; em seguida, está a marcação declarativa do GridView.

Configurar as propriedades ButtonFields Text, CommandName e ButtonType

Figura 19: Configurar as propriedades ButtonFields Text, CommandNameButtonType e

<asp:GridView ID="SuppliersProducts" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="SuppliersProductsDataSource"
    EnableViewState="False">
    <Columns>
        <asp:ButtonField ButtonType="Button" CommandName="IncreasePrice"
            Text="Price +10%" />
        <asp:ButtonField ButtonType="Button" CommandName="DecreasePrice"
            Text="Price -10%" />
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>

Com esses ButtonFields criados, a etapa final é criar um manipulador de eventos para o evento do RowCommand GridView. Esse manipulador de eventos, se acionado porque os botões Price +10% ou Price -10% foram clicados, precisa determinar o ProductID para a linha cujo botão foi clicado e, em seguida, invocar o ProductsBLL método da UpdateProduct classe, passando o ajuste percentual apropriado UnitPrice junto com o ProductID. O código a seguir executa estas tarefas:

protected void SuppliersProducts_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName.CompareTo("IncreasePrice") == 0 ||
        e.CommandName.CompareTo("DecreasePrice") == 0)
    {
        // The Increase Price or Decrease Price Button has been clicked
        // Determine the ID of the product whose price was adjusted
        int productID =
            (int)SuppliersProducts.DataKeys[Convert.ToInt32(e.CommandArgument)].Value;
        // Determine how much to adjust the price
        decimal percentageAdjust;
        if (e.CommandName.CompareTo("IncreasePrice") == 0)
            percentageAdjust = 1.1M;
        else
            percentageAdjust = 0.9M;

        // Adjust the price
        ProductsBLL productInfo = new ProductsBLL();
        productInfo.UpdateProduct(percentageAdjust, productID);
    }
}

Para determinar a ProductID linha cujo botão Preço +10% ou Preço -10% foi clicado, precisamos consultar a coleção do DataKeys GridView. Essa coleção contém os valores dos campos especificados na DataKeyNames propriedade para cada linha GridView. Como a propriedade do GridView DataKeyNames foi definida como ProductID pelo Visual Studio ao associar o ObjectDataSource ao GridView, DataKeys(rowIndex).Value fornece o ProductID para o rowIndex especificado.

O ButtonField passa automaticamente o rowIndex da linha cujo botão foi clicado por meio do e.CommandArgument parâmetro. Portanto, para determinar a ProductID linha cujo botão Preço +10% ou Preço -10% foi clicado, usamos: Convert.ToInt32(SuppliersProducts.DataKeys(Convert.ToInt32(e.CommandArgument)).Value).

Assim como acontece com o botão Descontinuar todos os produtos, se você tiver desabilitado o estado de exibição do GridView, o GridView será reassociado ao armazenamento de dados subjacente em cada postback e, portanto, será atualizado imediatamente para refletir uma alteração de preço que ocorre ao clicar em qualquer um dos botões. Se, no entanto, você não tiver desabilitado o estado de exibição no GridView, precisará reassociar manualmente os dados ao GridView depois de fazer essa alteração. Para fazer isso, basta fazer uma chamada para o método do DataBind() GridView imediatamente após invocar o UpdateProduct método.

A Figura 20 mostra a página ao visualizar os produtos fornecidos pela Grandma Kelly's Homestead. A Figura 21 mostra os resultados depois que o botão Preço +10% foi clicado duas vezes para o Grandma's Boysenberry Spread e o botão Preço -10% uma vez para o Northwoods Cranberry Sauce.

O GridView inclui os botões Preço +10% e Preço -10%

Figura 20: O GridView inclui os botões Preço +10% e Preço -10% (Clique para exibir a imagem em tamanho real)

Os preços do primeiro e terceiro produto foram atualizados através dos botões Preço +10% e Preço -10%

Figura 21: Os preços do primeiro e do terceiro produto foram atualizados por meio dos botões Preço +10% e Preço -10% (clique para visualizar a imagem em tamanho real)

Observação

O GridView (e o DetailsView) também podem ter Buttons, LinkButtons ou ImageButtons adicionados aos seus TemplateFields. Assim como acontece com o BoundField, esses Buttons, quando clicados, induzirão um postback, gerando o evento do RowCommand GridView. Ao adicionar botões em um TemplateField, no entanto, o Button CommandArgument não é definido automaticamente como o índice da linha, como acontece ao usar ButtonFields. Se você precisar determinar o índice de linha do botão que foi clicado no RowCommand manipulador de eventos, precisará definir manualmente a propriedade do Button CommandArgument em sua sintaxe declarativa dentro do TemplateField, usando código como:
<asp:Button runat="server" ... CommandArgument='<%# ((GridViewRow) Container).RowIndex %>'.

Resumo

Os controles GridView, DetailsView e FormView podem incluir Buttons, LinkButtons ou ImageButtons. Esses botões, quando clicados, causam um postback e geram o ItemCommand evento nos controles FormView e DetailsView e o RowCommand evento no GridView. Esses controles Web de dados têm funcionalidade interna para lidar com ações comuns relacionadas a comandos, como excluir ou editar registros. No entanto, também podemos usar botões que, quando clicados, respondem com a execução de nosso próprio código personalizado.

Para fazer isso, precisamos criar um manipulador de eventos para o ItemCommand evento or RowCommand . Neste manipulador de eventos, primeiro verificamos o valor de entrada CommandName para determinar qual botão foi clicado e, em seguida, tomamos a ação personalizada apropriada. Neste tutorial, vimos como usar botões e ButtonFields para descontinuar todos os produtos de um fornecedor especificado ou para aumentar ou diminuir o preço de um determinado produto em 10%.

Boa programação!

Sobre o autor

Scott Mitchell, autor de sete 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 2.0 em 24 horas. Ele pode ser contatado em mitchell@4GuysFromRolla.com. ou através de seu blog, que pode ser encontrado em http://ScottOnWriting.NET.