none
GridView - Problema com índices RRS feed

  • Pergunta

  • Boa Tarde! Estou criando um sistema de orçamento...

    Tava funcionando perfeito! Crie as opções de Editar, Cancelar, Atualizar e Editar o GridView. Bem como mais 2 colunas
    (convertido em Templete Field)... 

    E agora está dando erro na hora de rodar o código, não entendo o porque. Já olhei os índices, estão de acordo com as colunas que contém os valores para soma e multiplicação.

    Segue meu grid view:

                

    <asp:GridView ID="gvProdutos" runat="server" AutoGenerateColumns="False"  OnDataBound="gvProdutos_DataBound" 
                ShowFooter="True" OnRowEditing="gvProdutos_RowEditing" OnRowCancelingEdit="gvProdutos_RowCancelingEdit"
                OnRowUpdating="gvProdutos_RowUpdating">
                <Columns>
                    <asp:TemplateField HeaderText="Cod" Visible="False">
                        <EditItemTemplate>
                            <asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("orcCodigo") %>'></asp:TextBox>
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label ID="lbCodigo" runat="server" Text='<%# Bind("orcCodigo") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="CodOrc" Visible="False">
                        <EditItemTemplate>
                            <asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("orcNumero") %>'></asp:TextBox>
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label ID="lbCodOrc" runat="server" Text='<%# Bind("orcNumero") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:BoundField DataField="proNome" HeaderText="Produto" />
                    <asp:BoundField DataField="fabNome" HeaderText="Fabricante" />
                    <asp:BoundField DataField="proPreco" HeaderText="Preço Uni" />
                    <asp:TemplateField HeaderText="Quantidade">
                        <EditItemTemplate>
                            <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("orcQuantidade") %>'></asp:TextBox>
                        </EditItemTemplate>
                        <ItemTemplate>
                            <asp:Label ID="Label1" runat="server" Text='<%# Bind("orcQuantidade") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:BoundField HeaderText="Total Item" />
                    <asp:CommandField CancelText="Cancelar" EditText="Editar" HeaderText="Editar" 
                        SelectText="Selecionar" ShowEditButton="True" UpdateText="Atualizar" />
                    <asp:CommandField DeleteText="Remover" HeaderText="Remover" 
                        ShowDeleteButton="True" />
                </Columns>


            </asp:GridView>

    e o código onde está dando erro:

                                   

    protected void gvProdutos_DataBound(object sender, EventArgs e)
        {

            decimal valor = 0;
            decimal Total = 0;

          foreach (GridViewRow row in gvProdutos.Rows)
           {
               decimal preco = decimal.Parse(row.Cells[4].Text);
     int qtde = Int32.Parse(row.Cells[5].Text);

    // aqui está dando erro: Input string was not in a correct format.                                                                                                    // antes funcionava. Agora está vindo vazio, devia ter o valor da coluna 5, já preenchida

               Total = preco * qtde;
               row.Cells[6].Text = Total.ToString();

               valor += Decimal.Parse(row.Cells[6].Text);

           }

          GridViewRow footer = gvProdutos.FooterRow;
          footer.Cells[0].ColumnSpan = 8;
          footer.Cells[0].HorizontalAlign = HorizontalAlign.Center;
          footer.Cells.RemoveAt(4);
          footer.Cells.RemoveAt(3);
          footer.Cells[0].Text = string.Format("Total: {0:n2}", valor);

        }

    Alguém pode me ajudar? Obrigado.


    Diego
    Técnico em Informática
    Desenvolvedor Web



    • Editado Diego Frans sexta-feira, 2 de novembro de 2012 18:08
    sexta-feira, 2 de novembro de 2012 17:56

Respostas

  • Olá Diego.

    Note que em seu código a coluna que contem a quantidade é um template field com um Label no ItemTemplate. Desta forma voce tem que recuperar o valor do Label.

    protected void gvProdutos_DataBound(object sender, EventArgs e) { // ... codigos do metodo if (e.Row.RowType == DataControlRowType.DataRow) { Label quantidade = e.Row.FindControl("Label1") as Label; if (quantidade != null) { // Aqui voce coloca as contas que voce precisa fazer
    int qtde = Int32.Parse(quantidade.Text);

    } } // ... Restante do seu codigo }

    Abraços.


    Washington Luíz | MCP, MCTS
    O Senhor é minha força e somente Nele confio.

    • Marcado como Resposta Diego Frans sexta-feira, 9 de novembro de 2012 11:07
    terça-feira, 6 de novembro de 2012 20:55

Todas as Respostas

  • aparentemente o erro está dando porque o campo da celula 5 (4 porque o indice começa com 0) não pode ser convertido para int.

    Debug seu código que veja que valor está retornando


    Sou só uma little padawan que tem sorte de andar com jedis, mas farei o possível por quem precisar :)

    Se precisar: @MayogaX

    segunda-feira, 5 de novembro de 2012 10:12
  • Oi Priscila Brigado por responder.

    Então...

    int qtde = Int32.Parse(row.Cells[5].Text);

    Dessa forma, o valor que é vazio ""

    Se alterar para:

    int qtde = Int32.Parse(row.Cells[4].Text);

    Retorna o valor da coluna "Preço Uni"

    Na lógica, teria que pegar o valor, e no banco de dados a quantidade está inserida


    Diego
    Técnico em Informática
    Desenvolvedor Web

    terça-feira, 6 de novembro de 2012 20:17
  • Olá Diego.

    Note que em seu código a coluna que contem a quantidade é um template field com um Label no ItemTemplate. Desta forma voce tem que recuperar o valor do Label.

    protected void gvProdutos_DataBound(object sender, EventArgs e) { // ... codigos do metodo if (e.Row.RowType == DataControlRowType.DataRow) { Label quantidade = e.Row.FindControl("Label1") as Label; if (quantidade != null) { // Aqui voce coloca as contas que voce precisa fazer
    int qtde = Int32.Parse(quantidade.Text);

    } } // ... Restante do seu codigo }

    Abraços.


    Washington Luíz | MCP, MCTS
    O Senhor é minha força e somente Nele confio.

    • Marcado como Resposta Diego Frans sexta-feira, 9 de novembro de 2012 11:07
    terça-feira, 6 de novembro de 2012 20:55
  • Olá Washington,

    É verdade, não prestei atenção que a coluna estava convertida em template field.
    Bom, na maneira que vc escreveu acima, usei, mas informa que 'Row' não faz parte do método.

    Label quantidade = e.Row.FindControl("Label1") as Label;

    Então fiz desta forma:

     protected void gvProdutos_DataBound(object sender, EventArgs e)
        {

            decimal valor = 0;
            decimal Total = 0;
            Label lbQTD = FindControl("lbQTD") as Label;



            foreach (GridViewRow row in gvProdutos.Rows)
            {
                decimal preco = decimal.Parse(row.Cells[4].Text);
                
                //Label lbQTD = FindControl("lbQTD") as Label;
                int qtde = Convert.ToInt32(lbQTD);
                

                Total = preco * qtde;

                row.Cells[6].Text = Total.ToString();

                valor += Decimal.Parse(row.Cells[6].Text);

            }

            GridViewRow footer = gvProdutos.FooterRow;
            footer.Cells[0].ColumnSpan = 9;
            footer.Cells[0].HorizontalAlign = HorizontalAlign.Right;
            footer.Cells.RemoveAt(4);
            footer.Cells.RemoveAt(4);
            footer.Cells[0].Text = string.Format("Total: {0:n2}", valor);
            
        }

    Não está mais dando o erro anterior, encontra o valor da Quantidade de Produtos, porém
    o valor Total, na coluna 6 não é calculado, retorna zero.
    (lembrando que estou contando a coluna a partir do da primeira, coluna zero)


    Diego
    Técnico em Informática
    Desenvolvedor Web



    • Editado Diego Frans quinta-feira, 8 de novembro de 2012 11:29
    quinta-feira, 8 de novembro de 2012 11:22
  • Olá Diego. Não encontrou o e.Row, pois o evento não possui a assinatura correta. Não notei isso quando te passei o codigo.

    O evento Row_DataBound do GridView, por padrão, ele cria uma assinatura como esta:

    No HTML

    <asp:GridView ID="gvProdutos" runat="server" 
            OnRowDataBound="gvProdutos_RowDataBound">
    ... suas colunas
    </asp:GridView>

    No Code-Behind

    protected void gvProdutos_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            Label quantidade = e.Row.FindControl("Label1") as Label;
            if (quantidade != null)
            {
                // Aqui voce coloca as contas que voce precisa fazer
                int qtde = Int32.Parse(quantidade.Text);
            }
        }
    }

    Note que no HTML do GridView, eu defino o evento e no code-behind, a assinatura tem que possuir o parametro GridViewRowEventArgs e não EventArgs. Altere suas configurações e refaça o teste, por favor.

    Abraços.


    Washington Luíz | MCP, MCTS
    O Senhor é minha força e somente Nele confio.

    quinta-feira, 8 de novembro de 2012 11:44
  • Washington,

    Ficou desta forma meu Code-Behind:

                                    

    protected void gvProdutos_RowDataBound(object sender, GridViewRowEventArgs e)

        {

            decimal Total = 0;

            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                Label quantidade = e.Row.FindControl("lbQTD") as Label;
                if (quantidade != null)
                {

                    decimal preco = decimal.Parse(e.Row.Cells[4].Text);
                    // Aqui voce coloca as contas que voce precisa fazer
                    int qtde = Int32.Parse(quantidade.Text);

                    Total = preco * qtde;

                    e.Row.Cells[6].Text = Total.ToString();


                }
            }

        }

        protected void gvProdutos_DataBound(object sender, EventArgs e)
        {

                decimal valor = 0;

                foreach (GridViewRow row in gvProdutos.Rows)
                {

                    valor += Decimal.Parse(row.Cells[6].Text);

                }

                GridViewRow footer = gvProdutos.FooterRow;
                footer.Cells[0].ColumnSpan = 7;
                footer.Cells[0].HorizontalAlign = HorizontalAlign.Right;
                footer.Cells.RemoveAt(0);
                footer.Cells.RemoveAt(1);
                footer.Cells[6].Text = string.Format("Total: {0:n2}", valor);

        }

    E o HTML ou ASP.NET

    <asp:GridView ID="gvProdutos" runat="server" AutoGenerateColumns="False" OnRowDataBound="gvProdutos_RowDataBound"  
                ShowFooter="True" OnDataBound="gvProdutos_DataBound"  OnRowDeleting="gvProdutos_RowDeleting">

    Funcionou!!

    Demorei a postar a resposta, porque estava finalizando toda a aplicação do Sistema de Orçamento. algumas partes estava meio complicadas, como Atualizar e Cancelar a edição da coluna quantidade, outro dia pego pra aprimorar, o necessário está pronto.

    Muito Obrigado Washington Luíz, me ajudou muito. 


    Diego
    Técnico em Informática
    Desenvolvedor Web

    sexta-feira, 9 de novembro de 2012 11:06
  • Muito bom Diego. Parabéns pelo seu esforço.

    Precisando de mais alguma coisa é só falar. Sucesso!

    Abraços.


    Washington Luíz | MCP, MCTS
    O Senhor é minha força e somente Nele confio.

    sexta-feira, 9 de novembro de 2012 11:42