DATAGRIDVIEW COM E SEM DADOS VINDOS DE TABELA

EDUARDONICE 14/02/2014 16:46:20
#434804
Olá pessoal, sou iniciante em .Net e estou com o seguinte problema: quero trazer os dados de uma tabela para um datagridview e depois inserir no mesmo informações que estão em campos textbox.

Vou tentar explicar melhor:
- Tenho duas tabelas no Access: Ped (Pedidos) e PedItem (Itens do Pedido)
- Cinco textbox (txtPedido, txtItem, txtProduto, txtQuantidade, txtPreco)
- Um Datagridview para conter os itens do pedido (Item, Produto, Quantidade e Preco)
- Três botões: btoAdicionar (para Adicionar dados no Grid), btoRetirar (para Retirar itens do Grid) btoGravar (para Atualizar a tabela)
- No anexo está o meu form

O funcionamento é simples:
1 - Digitar o número do pedido
1.1 - Se o pedido existir exibir os dados no grid (Está fazendo)

2- Ao acionar o botão Adicionar, os dados dos textbox (txtItem, txtProduto, txtQuantidade e txtPreco) devem ser inseridos no datagridview (Não estou conseguindo fazer porque está dando o erro: [Ô]Rows cannot be programmatically added to the DataGridView[ô]s rows collection when the control is data-bound.[Ô])

3- Ao acionar o botão Retirar, os dados do grid devem ser excluídos do grid (Consegui fazer)

4- Ao acionar o botão gravar, vou ler o grid e gravar as informações na tabela (ainda não fiz, mas não vejo muitos problemas aqui)

Resumindo, meu problema é que não consigo inserir os dados que estão nos textbox no grid.

Seguem abaixo, os trechos quando digito o número do pedido e recupero os dados e quando aciono o botão Adicionar

Private Sub txtPedido_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtPedido.Leave
Dim Sql As String
With dgvProdutos
.ForeColor = Color.Black
.MultiSelect = False
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
.DefaultCellStyle.SelectionBackColor = Color.LightYellow
.DefaultCellStyle.SelectionForeColor = Color.Black
.ColumnHeadersDefaultCellStyle.Font = New Font([Ô]Dejavu Sans Mono[Ô], 8, FontStyle.Regular)
.DefaultCellStyle.Font = New Font([Ô]Dejavu Sans Mono[Ô], 8, FontStyle.Bold)
End With
dgvProdutos.Columns.Clear()
conn.ConnectionString = cnxGTE
Sql = [Ô]Select IDITEM as ITEM, PRODIT as PRODUTO, QUANTIT as QUANTIDADE, PRECOIT as PREÇO from PedItem where IDPIT = [Ô] & txtPedido.Text & [Ô];[Ô]
cmd.CommandText = Sql
Dim Adapter As New OleDbDataAdapter(Sql, cnxGTE)
Dim dt As New DataTable([Ô]PEDITEM[Ô])
Adapter.Fill(dt)
dgvProdutos.DataSource = dt
AbrirBco()
Dim Vetor As OleDbDataReader = cmd.ExecuteReader()
Vetor.Close()
FecharBco()
End Sub

Private Sub btoAdicionar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btoAdicionar.Click
Dim Linha As Integer
Linha = dgvProdutos.Rows.Count
dgvProdutos.Rows.Insert(Linha)
dgvProdutos.Rows(Linha).Cells(0).Value = txtItem.Text
dgvProdutos.Rows(Linha).Cells(1).Value = txtProduto.Text
dgvProdutos.Rows(Linha).Cells(2).Value = txtQuantidade.Text
dgvProdutos.Rows(Linha).Cells(3).Value = txtPreco.Text
End Sub
KERPLUNK 14/02/2014 17:21:04
#434806
Quando você buscou os dados dos ítens do pedido e associou ao grid usando isso:

dgvProdutos.DataSource = dt


Você fez um DataBound, ou seja, você associou o grid à uma fonte de dados, no seu caso, um datatable. Portanto, você não pode adicionar linhas com [Ô]dgvProdutos.Rows += 1[Ô] ou algo parecido, porque o grid já está associado à uma fonte de dados, e é isso que sua mensagem de erro está dizendo. Tem várias soluções diferentes para isso, algumas mais simplórias e outras mais complexas, mas mais corretas.
EDUARDONICE 14/02/2014 19:38:05
#434809
Kerplunk

Qual seria a solução mais simples ? Não tenho idéia nem de como começar. Estou tentando aprender na [Ô]raça[Ô] e é muito difícil.
NILSONTRES 14/02/2014 23:18:22
#434813
Resposta escolhida
KERPLUNK,
EDUARDONICE,
Me permita utilizar o seu tópico, mas servira para vc como aprendizado também.

KERPLUNK,, é por isso que digo e já fui criticado aqui por outros colegas, digo criticado na boa, mas eu não costumo carregar datagrid vinculado a dados, por esse tipo de coisa mesmo, o datagrid é o controle que mais tenho em minhas aplicações, fora os labels e textbox é claro. Só faço esse carregamento via datasource em casos raros , onde a base a ser carrega é extremamente grande e ou tenho certeza que não precisarei manipular esse datagrid.
O que vc tem a me dizer a esse respeito. Gostaria de sua opinião pois sei que vc é um defensor de carregar via data source, mas e nesses casos ?

Obrigado.

GUIMORAES 15/02/2014 11:03:20
#434827
Simples, adiciona em um DataRow.
Ex:

[ô]Carreguei os dados na grid
dgvTeste.DataSource = dtExemplo

Dim dt as new DataTable [ô]Criei um novo dataTable
Dim dRow as DataRow [ô]Criar um dataRow

[ô]Defino ao dataTable a fonte de dados que provem do dataGrid.
dt = dgvTeste.DataSource

[ô]defino ao dataRow uma nova linha, com base no dataTable
dRow = dt.NewRow.


[ô]Ai você define ao dRow as linhas

dRow(0) = [Ô]TESTE[Ô]
dRow(1) = [Ô]TESTE 1[Ô]
dRow(2) = [Ô]TESTE[Ô]

[ô]no final você adiciona a grid.

dt.Rows.Add(dRow)
dt.AcceptChanges()

Pronto, linha adicionada, mesmo o dataGrid estando associado a uma fonte de dados.

Bom, agora depois de explicar tudo isto, não vejo a mínima utilidade de fazer o mesmo, se as informações estão vindo de uma fonte de dados, por qual motivo você não adiciona o registro na tabela e carrega novamente o dataGrid?

Você tem todo o trabalho de adicionar um dataRow, verificar em qual posição está a coluna x, linha y. Se você usar orientação a objetos, você pode define os valores a classe e adiciona na tabela, utilizando operações CRUD, muito mais simples.

é como o Kerplunk disse, existem formas de fazer isto, umas mais simples e outras mais complexas, porem mais corretas.
NILSONTRES 15/02/2014 14:34:07
#434831
GUIMORAES123,
Mas para fazer tudo isso, carrega logo o datagrid manualmente sem datasource, um datagrid se utliza para n coisas.

select from tabela

while tabela.read
grid.rows.add
grid.rows(grid.rows.count-1).cells(0).value=tabela.item(campo[Ô]).tostring
end while

Citação:

se as informações estão vindo de uma fonte de dados, por qual motivo você não adiciona o registro na tabela e carrega novamente o dataGrid?


Não vamos esquecer das transações, que são indispensaveis em casos de tela de venda.
EDUARDONICE 17/02/2014 10:26:23
#434900
Agradeço a todos que se manifestaram. Não imaginava que um simples tópico como este pudesse ter soluções bem diferentes. Como já escrevi, tenho pouca experiência em linguagens como .Net e até mesmo VB, e convenhamos, aprender na [Ô]raça[Ô] é um pouco difícil, mas acho que estou no caminho certo, principalmente recebendo a ajuda de vocês.

Ao Guimaraes123 que me fez uma pergunta, a idéia era aproveitar quem tem pedidos em aberto e simular novos acréscimos, podendo ou não serem gravados na tabela.

A resposta do NilsonTres, me pareceu a mais simples, embora eu ainda não tenha implementado, já que terei que fazer outras coisas nesta semana. Por enquanto, deixo o tópico em aberto, até mesmo porque podem surgir outras respostas e também porque existe um pedido de opinião ao Kerplunk que talvez ainda ele não tenha lido e queira responder.

Por enquanto obrigado pessoal. Depois eu pontuo.
KERPLUNK 17/02/2014 14:52:51
#434908
Citação:

:
KERPLUNK,
EDUARDONICE,
Me permita utilizar o seu tópico, mas servira para vc como aprendizado também.

KERPLUNK,, é por isso que digo e já fui criticado aqui por outros colegas, digo criticado na boa, mas eu não costumo carregar datagrid vinculado a dados, por esse tipo de coisa mesmo, o datagrid é o controle que mais tenho em minhas aplicações, fora os labels e textbox é claro. Só faço esse carregamento via datasource em casos raros , onde a base a ser carrega é extremamente grande e ou tenho certeza que não precisarei manipular esse datagrid.
O que vc tem a me dizer a esse respeito. Gostaria de sua opinião pois sei que vc é um defensor de carregar via data source, mas e nesses casos ?

Obrigado.


Carrego sim via DataSource. A grande sacada, é que NUNCA, carrego objetos de banco de dados, mas sim List<T> ou BindingList<T>onde cada entidade da lista, possui as decorações corretas para descrição de cabeçalho de grid e todos os outros parâmetros necessários.
Em tempo, uso List<T> quando o grid não sofrerá edição e BindingList<T> caso sofra edição.
JONATHANSTECKER 18/02/2014 08:51:35
#434944
Citação:

Carrego sim via DataSource. A grande sacada, é que NUNCA, carrego objetos de banco de dados, mas sim List<T> ou BindingList<T>onde cada entidade da lista, possui as decorações corretas para descrição de cabeçalho de grid e todos os outros parâmetros necessários.
Em tempo, uso List<T> quando o grid não sofrerá edição e BindingList<T> caso sofra edição.


Perfeito KERPLUNK!

EDUARDONICE, se você está iniciando o sistema agora, pesquise bem e faça da forma mais prática possível.
No começo com certeza será uma dor de cabeça, mas futuramente você verá que todo o esforço valeu a pena.
Tópico encerrado , respostas não são mais permitidas