Partilhar via


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

por Scott Mitchell

Descarregar PDF

Neste tutorial, veremos como adicionar botões personalizados, tanto a um modelo quanto aos campos de um controle GridView ou DetailsView. Em particular, vamos construir uma interface que tem um FormView que permite ao utilizador navegar pelos fornecedores.

Introdução

Não é raro que relatórios, embora muitos cenários envolvam acesso apenas de leitura aos dados, incluam funcionalidades para realizar ações com base nos dados exibidos. Normalmente, isso envolvia adicionar um controlo da Web Button, LinkButton ou ImageButton a cada registo exibido no relatório que, quando clicado, provoca um postback e executa algum código no lado do servidor. A edição e eliminação dos dados numa base registo a registo é 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 , editar e excluir é tão comum que os controles GridView, DetailsView e FormView podem oferecer suporte a essa funcionalidade sem a necessidade de escrever uma única linha de código.

Além dos botões Edit e Delete, 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, vamos construir uma interface que tem um FormView que permite ao utilizador navegar pelos fornecedores. Para um determinado fornecedor, o FormView mostrará informações sobre o fornecedor juntamente com um controle da 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 os botões Aumentar Preço e Preço de Desconto que, se clicados, aumentam ou reduzem o valor do UnitPrice produto em 10% (veja a Figura 1).

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

Figura 1: 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 Web do tutorial sobre o botão

Antes de analisarmos como adicionar botões personalizados, vamos primeiro reservar um momento 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 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

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

Figura 2: Adicionar as Páginas ASP.NET para os Tutoriais Personalizados Buttons-Related

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

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

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

Por fim, adicione as páginas como entradas ao Web.sitemap arquivo. Especificamente, adicione a seguinte marcação após "Paging and Sorting" <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>

Após a atualização Web.sitemap, reserve um momento para visualizar o site de tutoriais através 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: 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 os 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 por abrir a página CustomButtons.aspx na pasta CustomButtons. Adicione um FormView à página arrastando-o da Caixa de Ferramentas para o Designer e defina sua ID propriedade como Suppliers. Na tag inteligente do FormView, escolha criar um novo ObjectDataSource chamado SuppliersDataSource.

Criar um novo ObjectDataSource chamado SuppliersDataSource

Figura 5: Criar um novo ObjectDataSource nomeado SuppliersDataSource (Clique para visualizar a imagem em tamanho real)

Configure esta nova ObjectDataSource para que ele consulte o método SuppliersBLL da classe GetSuppliers() (consulte a 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 SuppliersBLL classe (GetSuppliers() imagem em tamanho real)

Depois de configurar o ObjectDataSource, o Visual Studio gerará um InsertItemTemplate, EditItemTemplatee ItemTemplate para o FormView. Remova os InsertItemTemplate e EditItemTemplate, e modifique o ItemTemplate para que exiba apenas o nome da empresa e o número de telefone do fornecedor. Por fim, ative o suporte de paginação para o FormView marcando a caixa de seleção Ativar paginação a partir do seu tag inteligente (ou definindo a sua propriedade AllowPaging como True). Após essas alterações, a marcação declarativa da sua 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 através 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 atualmente selecionado (Clique para visualizar 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 SuppliersProducts, e adicione um novo ObjectDataSource chamado SuppliersProductsDataSource.

Criar um novo ObjectDataSource chamado FornecedoresProdutosDataSource

Figura 8: Criar um novo ObjectDataSource nomeado SuppliersProductsDataSource (Clique para visualizar 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 método da ProductsBLL classe (GetProductsBySupplierID(supplierID) 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 valor SupplierID do FormView, defina como Control a lista suspensa da fonte do Parâmetro e como Suppliers a lista suspensa do ControlID (a ID do FormView criado na Etapa 2).

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

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

Após concluir o assistente ObjectDataSource, o GridView conterá um campo 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 do seu GridView e SuppliersProductsDataSource ObjectDataSource deverá 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 do FormView na parte superior e visualize os produtos fornecidos por esse fornecedor através do GridView na parte inferior. A Figura 11 mostra uma captura de tela desta 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 visualizar 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 Button ao FormView que, quando clicado, descontinua todos os produtos do fornecedor, primeiro precisamos adicionar um método ao DAL e ao 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 de lógica de negócios, passando o do fornecedor SupplierIDselecionado, a BLL chamará para o método correspondente da camada de acesso a dados, 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 DataSet Tipado localizado na pasta App_Code/DAL e adicione um novo método (clique com o botão direito do ProductsTableAdapter mouse no ProductsTableAdapter e escolha Adicionar consulta). Isso abrirá o assistente de Configuração de Consulta TableAdapter, que nos orientará 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 visualizar a imagem em tamanho real)

Em seguida, o assistente questiona-nos sobre o tipo de consulta que queremos criar. 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 visualizar a imagem em tamanho real)

A próxima tela do assistente fornece a instrução UPDATE existente do TableAdapter, que atualiza os campos definidos na Products DataTable. Substitua este 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 uso DiscontinueAllProductsForSupplierdo nome do novo método. Conclua o assistente de instalação clicando no botão Concluir. Ao retornar ao DataSet Designer, você verá um novo método no ProductsTableAdapter nome DiscontinueAllProductsForSupplier(@SupplierID).

Nomeie o novo método DAL chamado DiscontinueAllProductsForSupplier

Figura 14: Nomeie o novo método DiscontinueAllProductsForSupplier DAL (Clique para visualizar 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);
}

Este método simplesmente invoca o método DiscontinueAllProductsForSupplier(supplierID) no DAL, passando o valor do parâmetro fornecido supplierID. Se existissem regras comerciais que só permitissem a descontinuação dos produtos de um fornecedor em determinadas circunstâncias, essas regras deveriam ser aplicadas 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 que o método DiscontinueAllProductsForSupplier(supplierID) apareça na lista suspensa do assistente de configuração de fonte de dados do ObjectDataSource na secção UPDATE. Omiti este atributo porque chamaremos o método DiscontinueAllProductsForSupplier(supplierID) diretamente a partir de um manipulador de eventos na nossa página ASP.NET.

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

Com o DiscontinueAllProductsForSupplier(supplierID) método no 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 FormView's 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 este controlo Button Web através do Designer clicando no link Edit Templates no tag inteligente do FormView (consulte a Figura 15) ou diretamente através da sintaxe declarativa.

Adicionar um botão Descontinuar Todos os Produtos como Controle Web ao ItemTemplate do FormView

Figura 15: Adicionar um controle da Web do botão Descontinuar todos os produtos ao 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 código personalizado em resposta a esse botão que está sendo clicado, podemos criar um manipulador de eventos para esse evento. Entenda, no entanto, que o ItemCommand evento é acionado sempre que qualquer controle da Web Button, LinkButton ou ImageButton é clicado dentro do FormView. Isso significa que quando o usuário se move de uma página para outra no FormView, o ItemCommand evento é acionado, a mesma coisa quando o usuário clica em Novo, Editar ou Excluir em um FormView que suporta inserção, atualização ou exclusão.

Como o ItemCommand botão é acionado independentemente do 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 manipulador de ItemCommand eventos, permitindo-nos determinar se o botão Descontinuar todos os produtos foi clicado. Defina a propriedade CommandName do botão Descontinuar Todos os Produtos como DescontinuarProdutos.

Finalmente, 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 Adicionar confirmação Client-Side ao eliminar, isso pode ser feito com um pouco de JavaScript. Em particular, defina a propriedade OnClientClick do controle Button Web 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 ter a seguinte aparência:

<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 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 atualmente selecionado no FormView pode ser acedido utilizando a propriedade SelectedValue do FormView. A SelectedValue propriedade retorna o primeiro valor de chave de dados para o registro que está sendo exibido no FormView. A propriedade do DataKeyNamesFormView, 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 vincular 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 da 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-se que a Cooperativa de Quesos 'Las Cabras' encerrou as suas atividades e, por conseguinte, os seus produtos vão ser 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 real)

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á então 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 está sendo recuperado para o 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, será necessário revincular 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 visualizar 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

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 Data Access Layer e Business Logic Layer. 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 esta sobrecarga, variaremos ligeiramente deste padrão e, em vez disso, passaremos no produto ProductID e na porcentagem pela qual ajustar o UnitPrice (em vez de passar no novo, ajustado UnitPrice em si). 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 UnitPrice do produto atual.

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 do produto especificado por meio do método DAL GetProductByProductID(productID). Em seguida, ele verifica se o valor do banco de dados UnitPrice é atribuído ao produtoNULL. Se for, o preço é deixado inalterado. Se, no entanto, houver um valor não-NULLUnitPrice, o método atualiza o UnitPrice do produto em pela porcentagem especificada (unitPriceAdjustmentPercent).

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

O GridView (e o DetailsView) são ambos constituídos 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 Apagar, nos botões de classificação e assim por diante causa um postback e gera o evento do RowCommand GridView.

O ButtonField tem uma propriedade CommandName que atribui o valor especificado a cada uma das suas propriedades Buttons CommandName. Como com o 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 Preço +10% e outro com o texto Preço -10%. Para adicionar estes ButtonFields, clique no link Editar Colunas da etiqueta 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 destes dois ButtonFields como Preço +10% e Preço -10% e as CommandName propriedades como AumentarPreço e DiminuirPreço, respectivamente. Por padrão, um ButtonField renderiza a sua coluna de botões como LinkButtons. Isso pode ser alterado, no entanto, através da propriedade ButtonType ButtonField. Vamos ter estes dois ButtonFields renderizados como botões normais; 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 Text, CommandName e ButtonType dos ButtonFields

Figura 19: Configurar as propriedades de ButtonFields Text, CommandName e 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 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 essas 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 na linha em que o botão Price +10% ou Price -10% foi clicado, precisamos consultar a coleção do DataKeys do GridView. Esta coleção contém os valores dos campos especificados na DataKeyNames propriedade para cada linha GridView. Como a propriedade do DataKeyNames GridView 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 transmite automaticamente o rowIndex da linha cujo botão foi clicado através do parâmetro e.CommandArgument. Portanto, para determinar o ProductID da 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 no botão Descontinuar todos os produtos, se você tiver desabilitado o estado de exibição do GridView, o GridView está sendo redirecionado para o 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, será necessário revincular 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 após o botão Price +10% ter sido clicado duas vezes para o Boysenberry Spread da vovó e o botão Price -10% uma vez para Northwoods Cranberry Sauce.

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

Figura 20: O GridView inclui os botões Price +10% e Price -10% (Clique para visualizar 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 terceiro produto foram atualizados através dos botões Preço +10% e Preço -10% (Clique para ver a imagem em tamanho real)

Observação

O GridView (e o DetailsView) também podem ter Buttons, LinkButtons ou ImageButtons adicionados aos seus TemplateFields. Tal como acontece com o BoundField, estes botões, quando clicados, provocarão um postback, acionando o evento RowCommand do GridView. Ao adicionar botões num TemplateField, no entanto, o CommandArgument do botão não é definido automaticamente para o índice da linha como acontece quando se utiliza ButtonFields. Caso precises determinar o índice de linha do botão que foi clicado no evento RowCommand, deverás definir manualmente a propriedade do Button CommandArgument na 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 disparam o evento ItemCommand nos controlos FormView e DetailsView e o evento RowCommand no comando 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 executando nosso próprio código personalizado.

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

Feliz Programação!

Sobre o Autor

Scott Mitchell, autor de sete livros sobre ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias Web da Microsoft desde 1998. Scott trabalha como consultor, formador e escritor independente. Seu último livro é Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Ele pode ser contatado em mitchell@4GuysFromRolla.com.