DATAGRIDVIEW COM E SEM DADOS VINDOS DE TABELA
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
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.
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.
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.
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.
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.
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.
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.
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.