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 tem um FormView que permite que o usuário percorra a página por meio 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 adicionar 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 com base em registro por registro é o exemplo mais comum. Na verdade, como vimos começando com o tutorial Visão geral de 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 Botões, 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 tem um FormView que permite que o usuário percorra a página por meio dos fornecedores. Para um determinado fornecedor, o FormView mostrará informações sobre o fornecedor juntamente com um controle Web button que, se clicado, marcará todos os seus produtos associados como descontinuados. Além disso, um GridView lista os produtos fornecidos pelo fornecedor selecionado, com cada linha contendo botões Aumentar Preço e Preço de Desconto que, se clicados, aumentam ou reduzem os produtos UnitPrice em 10% (consulte a Figura 1).

O FormView e o GridView contêm botões que executam ações personalizadas

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

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

Antes de examinarmos como adicionar botões personalizados, primeiro vamos dar um tempo para 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 ASP.NET páginas a seguir a essa pasta, certificando-se de associar cada página à Site.master página master:

  • Default.aspx
  • CustomButtons.aspx

Adicionar as páginas de ASP.NET para os tutoriais de Buttons-Related personalizados

Figura 2: Adicionar as páginas de ASP.NET para os tutoriais de Buttons-Related personalizados

Assim 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 a Default.aspx arrastando-o do Gerenciador de Soluções para o modo design da página.

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

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

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

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

Depois de atualizar Web.sitemap, reserve um momento para exibir 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 de botões personalizados

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

Etapa 2: Adicionar um FormView que Listas 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 a página pelos 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, primeiro vamos criar o FormView para que ele exiba as informações do fornecedor.

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

Criar um novo objectDataSource chamado SuppliersDataSource

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

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

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

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

Depois de configurar o ObjectDataSource, o Visual Studio gerará um InsertItemTemplate, EditItemTemplatee ItemTemplate para o FormView. Remova o InsertItemTemplate e EditItemTemplate e 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 de sua marca inteligente (ou definindo sua AllowPaging propriedade Truecomo ). Depois que essas alterações forem alteradas, a marcação declarativa da página deverá 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 exibida por meio de um navegador.

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

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

Etapa 3: Adicionar um GridView que Listas produtos do fornecedor selecionado

Antes de adicionarmos o Botão Descontinuar Todos os Produtos ao modelo do FormView, primeiro vamos 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 objetoDataSource nomeado SuppliersProductsDataSource (clique para exibir a imagem em tamanho real)

Configure este 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 GetProductsBySupplierID(supplierID) da classe ProductsBLL

Figura 9: Configurar a fonte de dados para usar o ProductsBLL método da GetProductsBySupplierID(supplierID) classe (clique para exibir a 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 Suppliers FormView

Figura 10: Indique que o supplierID parâmetro deve vir do Suppliers controle FormView (clique para exibir a 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 modo 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 de master/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 desta página ao selecionar o fornecedor da 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 para um fornecedor

Antes de podermos adicionar um Botão 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, esse método será chamado DiscontinueAllProductsForSupplier(supplierID)de . Quando o Botão do FormView for clicado, invocaremos esse método na Camada de Lógica de Negócios, passando o do SupplierIDfornecedor selecionado; a BLL será chamada para o método 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 na App_Code/DAL pasta e adicione um novo método ao ProductsTableAdapter (clique com o botão direito do ProductsTableAdapter mouse no e escolha Adicionar Consulta). Isso abrirá o assistente de Configuração de Consulta tableAdapter, que nos orienta pelo 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 solicita qual tipo de consulta criar. Como o DiscontinueAllProductsForSupplier(supplierID) método precisará atualizar a tabela de 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.

Escolher o tipo de consulta UPDATE

Figura 13: Escolher 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 na 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 solicitará que 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 chamado DiscontinueAllProductsForSupplier(@SupplierID).

Nomear o novo método DAL DiscontinueAllProductsForSupplier

Figura 14: nomear 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 de Lógica de Negócios. Para fazer isso, abra o ProductsBLL arquivo de 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 apenas os produtos de um fornecedor fossem descontinuados 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: Adicionar um botão Descontinuar Todos os Produtos ao FormView

Com o DiscontinueAllProductsForSupplier(supplierID) método na BLL e na DAL concluídos, a etapa final para adicionar a capacidade de descontinuar todos os produtos para o fornecedor selecionado é adicionar um controle Web Button ao FormView.ItemTemplate Vamos adicionar um 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 ItemTemplate do FormView

Figura 15: Adicionar um controle Web de botão Descontinuar Todos os Produtos ao do FormView ItemTemplate (Clique para exibir a imagem em tamanho real)

Quando o Botão é clicado por um usuário que visita a página, um postback ocorre e o evento do ItemCommand FormView é acionado. Para executar o código personalizado em resposta a este Botão que está sendo clicado, podemos criar um manipulador de eventos para esse evento. No entanto, entenda que o ItemCommand evento é acionado sempre que qualquer controle Web Button, LinkButton ou ImageButton é clicado no FormView. Isso significa que, quando o usuário passa 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 dá suporte à inserção, atualização ou exclusão.

Como o aciona ItemCommand 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 para algum valor de identificação. Quando o Botão é clicado, esse CommandName valor é passado para o ItemCommand manipulador de eventos, permitindo-nos determinar se o botão Descontinuar Todos os Produtos foi clicado. Defina a propriedade do CommandName Botão Descontinuar Todos os Produtos como DescontinuarProdutos.

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 Client-Side confirmação 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. Nesse manipulador de eventos, precisamos primeiro determinar se o botão Descontinuar Todos os Produtos foi clicado. Nesse caso, queremos criar uma instância da ProductsBLL classe e invocar seu DiscontinueAllProductsForSupplier(supplierID) método, passando o SupplierID do 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 do fornecedor selecionado atual no FormView pode ser acessado usando a propriedade do SelectedValueFormView. A SelectedValue propriedade retorna o primeiro valor de chave de dados para o registro que está sendo exibido no FormView. A propriedade formViewDataKeyNames, que indica os campos de dados dos quais os valores da chave de dados são extraídos, foi definida automaticamente como SupplierID pelo Visual Studio ao associar ObjectDataSource ao FormView novamente na Etapa 2.

Com o ItemCommand manipulador de eventos criado, tire 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 não descontinuados.

Imagine que a Cooperativa de Quesos 'Las Cabras' saiu do negócio e, portanto, seus produtos devem ser descontinuados. Clique no botão Descontinuar Todos os Produtos. Isso exibirá a caixa de diálogo confirmar do lado do cliente (consulte Figura 16).

Cooperativa de Quesos Las Cabras fornece dois produtos ativos

Figura 16: Cooperativa de Quesos Las Cabras fornece dois produtos ativos (clique para exibir imagem em tamanho real)

Se você clicar em OK na caixa de diálogo confirmar 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 executará, invocando o DiscontinueAllProductsForSupplier(supplierID) método e descontinuando os produtos Queso Cabrales e Queso Manchego La Pastora.

Se você desabilitou o estado de exibição do GridView, o GridView está sendo recuperado para o armazenamento de dados subjacente em cada postback e, portanto, será imediatamente atualizado para refletir que esses dois produtos estão 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 de lógica de negócios para ajustar o preço de um produto

Assim como com o 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 de Camada de Acesso a Dados e 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 passadas UpdateProduct tomaram 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, variaremos ligeiramente desse padrão e, em vez disso, passaremos o produto ProductID e o percentual pelo qual ajustar o UnitPrice (em vez de passar o novo, ajustado UnitPrice em si). Essa abordagem simplificará o código que precisamos escrever na classe code-behind da página ASP.NET, pois não precisamos nos preocupar em determinar o produto UnitPriceatual.

A UpdateProduct sobrecarga deste 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 método da GetProductByProductID(productID) DAL. Em seguida, ele verifica se o do produto recebe um valor de UnitPrice banco de dados NULL . Se for, o preço será deixado sem alterações. Se, no entanto, houver um valor diferenteNULLUnitPrice , o método atualizará o do UnitPrice produto 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 nome indica, renderiza como uma coluna com um Button, LinkButton ou ImageButton para cada linha. Semelhante ao FormView, clicar em qualquer botão dentro dos botões de paginação GridView, editar ou excluir botões, classificar botões e assim por diante causa um postback e aciona o evento do RowCommandGridView.

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 RowCommand manipulador de eventos para determinar qual botão foi clicado.

Vamos adicionar dois novos ButtonFields ao GridView, um com um texto de botão Preço +10% e outro com o texto Preço -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 Campos de Botão ao GridView

Figura 18: Adicionar dois campos de botão 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. No entanto, isso pode ser alterado por meio da propriedade ButtonFieldButtonType. Vamos renderizar esses dois ButtonFields como botões de push regulares; portanto, defina a ButtonType propriedade como Button. A Figura 19 mostra a caixa de diálogo Campos após essas alterações terem sido feitas; a seguir está a marcação declarativa do GridView.

Configurar as propriedades ButtonFields Text, CommandName e ButtonType

Figura 19: configurar as propriedades ButtonFields Text, CommandNamee ButtonType

<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 gridView RowCommand . Esse manipulador de eventos, se disparado porque os botões Preço +10% ou Preço -10% foram clicados, precisa determinar o para a ProductID 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 o ProductID para a 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 gridView DataKeyNames foi definida como ProductID pelo Visual Studio ao associar ObjectDataSource ao GridView, DataKeys(rowIndex).Value fornece o ProductID para a rowIndex especificada.

O ButtonField passa automaticamente na rowIndex da linha cujo botão foi clicado por meio do e.CommandArgument parâmetro . Portanto, para determinar o para 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 está sendo recuperado para o armazenamento de dados subjacente em cada postback e, portanto, será imediatamente atualizado 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 exibir os produtos fornecidos pela Página Inicial da Vovó Kelly. A Figura 21 mostra os resultados depois que o botão Preço +10% foi clicado duas vezes para o Boysenberry Spread da Vovó e o botão Preço -10% uma vez para o Molho de Cranberry northwoods.

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 por meio dos botões Preço +10% e Preço -10%

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

Observação

O GridView (e o DetailsView) também podem ter Botões, LinkButtons ou ImageButtons adicionados a seus TemplateFields. Assim como acontece com o BoundField, esses Botões, quando clicados, induzem um postback, elevando o evento do RowCommand GridView. No entanto, ao adicionar botões em um TemplateField, o botão CommandArgument não é definido automaticamente para o índice da linha como é ao usar ButtonFields. Se você precisar determinar o índice de linha do botão que foi clicado dentro do RowCommand manipulador de eventos, precisará definir manualmente a propriedade de CommandArgument Button 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 Botões, LinkButtons ou ImageButtons. Esses botões, quando clicados, causam um postback e acionam o ItemCommand evento nos controles FormView e DetailsView e no RowCommand evento no GridView. Esses controles da 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 ou RowCommand . Nesse manipulador de eventos, primeiro marcar o valor de entrada CommandName para determinar qual botão foi clicado e, em seguida, tomar a ação personalizada apropriada. Neste tutorial, vimos como usar botões e ButtonFields para descontinuar todos os produtos de um fornecedor especificado ou aumentar ou diminuir o preço de um produto específico em 10%.

Programação feliz!

Sobre o autor

Scott Mitchell, autor de sete 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 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.