У меня есть несвязанный datagridview, установите параметр, позволяющий пользователю добавлять строку в True, и все, что я хочу, это то, что после того, как я «завершу» строку, datagridview автоматически должен создать новую пустую строку, поэтому я установил метод
DataGridView1.Rows.Add()
в событии DataGridView1_Leave, но как только строка будет завершена и возникнет исключение: Произошло необработанное исключение типа «System.InvalidOperationException» в System.Windows.Forms.dll — невозможно завершить эту операцию в этом обработчике событий. Что это означает? Это должен быть простой простой код, но я не знаю, как решить
Вот ситуация: Это получатель DataGridView. Когда я нахожусь в первой пустой строке (которая создается с помощью AllowUserToAddRow = true) и нажимаю F3, открывается модальная форма с другим DataGridView, содержащим продукты для выбора
а вот код события KeyDown в DataGridView получателя
Private Sub DataGridView1_KeyDown(sender As Object, e As KeyEventArgs) Handles DataGridView1.KeyDown
If e.KeyCode = Keys.F3 Then
If frmZoomArticoli.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim codart As String = frmZoomArticoli.DataGridView1.CurrentCell.Value.ToString()
RicercaxCodiceArticolo(codart)
End If
End If
End Sub
Здесь подпрограмма RicercaxCodiceArticolo(codart), которая заполняет получатель DataGridView выбранным продуктом:
Private Sub RicercaxCodiceArticolo(ByVal codiceart As String)
Dim strsql As String
Dim cmd As SqlCommand
Dim source As New BindingSource
'Dichiariamo le variabili che ospitano i dati di riga
Dim codice As String
Dim descrizione As String
Dim unitamisura As String
Dim quantita As Double = 1.0
Dim codiceiva As Double
Dim costobase As Double
Dim prezzobase As Double
Dim costoultimo As Double
Dim giacenza As Double
Dim sconto1 As Double
Dim sconto2 As Double
connection.Open()
strsql = "SELECT CODICEARTICOLO AS 'Codice', DESCRIZIONEARTICOLO AS 'Descrizione', UNITAMISURA AS 'Um', CODICEIVA AS 'Iva' " _
& ", COSTOBASE AS 'Costo', PREZZOBASE AS 'Prezzo', SCONTO1 As 'Sc1', SCONTO2 As 'Sc2', COSTOULTIMO AS 'CostoUlt' " _
& ", BARCODE AS 'Barcode', NOTEARTICOLO AS 'Note' ,CATEGORIAARTICOLO AS 'Categ.Art.', GIACENZA AS 'Giacenza' " _
& ", FORNITOREPREF AS 'Fornit. Pref.' FROM Articoli " _
& " WHERE CODICEARTICOLO = '" & codiceart & "'"
cmd = New SqlCommand()
cmd.CommandText = strsql
cmd.CommandType = CommandType.Text
cmd.Connection = connection
source.DataSource = cmd.ExecuteReader()
'Assegniamo i dati letti nel bindingsource alle variabili
codice = source.Current!Codice
descrizione = source.Current!Descrizione
unitamisura = source.Current!Um
codiceiva = Convert.ToDouble(source.Current!Iva)
costobase = Convert.ToDouble(source.Current!Costo)
prezzobase = Convert.ToDouble(source.Current!Prezzo)
costoultimo = Convert.ToDouble(source.Current!Costoult)
giacenza = Convert.ToDouble(source.Current!Giacenza)
sconto1 = Convert.ToDouble(source.Current!Sc1)
sconto2 = Convert.ToDouble(source.Current!Sc2)
'Riempiamo le celle con i dati estratti dal BindingSource
With DataGridView1.CurrentRow
.Cells("grdCodice").Value = codice
.Cells("grdDescrizione").Value = descrizione
.Cells("grdUM").Value = source.Current!Um
.Cells("grdQuantita").Value = quantita
If TipoMovimento = "Carico" Then
.Cells("grdPrezzoUnitario").Value = source.Current!CostoUlt
Else
.Cells("grdPrezzoUnitario").Value = source.Current!Prezzo
End If
.Cells("grdSconto1").Value = sconto1
.Cells("grdSconto2").Value = sconto2
.Cells("grdSconto3").Value = 0.0
.Cells("grdSconto4").Value = 0.0
'Per calcolare il prezzo totale di riga dobbiamo tenere presente le
'informazioni che abbiamo gia' in anagrafica, ovvero il costo/prezzo
'e gli sconti
'Blocco di controllo sul tipo movimento
If TipoMovimento = "Carico" Then
If sconto1 > 0 Then
.Cells("grdPrezzoTotale").Value = quantita * (costoultimo * (costoultimo * sconto1 / 100))
Else
.Cells("grdPrezzoTotale").Value = quantita * costoultimo
End If
ElseIf TipoMovimento = "Scarico" Then
If sconto1 > 0 Then
.Cells("grdPrezzoTotale").Value = quantita * (prezzobase * (prezzobase * sconto1 / 100))
Else
.Cells("grdPrezzoTotale").Value = quantita * prezzobase
End If
End If
.Cells("grdAliquotaIva").Value = codiceiva
End With
connection.Close()
End Sub
и это результат в DataGridView получателя:
теперь предположим, что я не хочу редактировать выбранную строку, потому что мне не нужно редактировать количество, цену или что-то еще, а я просто хочу вставить новую строку, чтобы продолжать вставлять другие продукты. Когда я нажимаю вкладку до конца строки, я хочу создать новую строку, и поэтому я написал DataGridView1.Rows.Add() в событии RowLeave DataGridView, но здесь возникает исключение: Мне жаль, что все описания на итальянском языке, но если вам нужны какие-либо другие подробности, не стесняйтесь спрашивать. Если я ничего не могу сделать, все, что остается, это добавить кнопку вне DataGridView, которая добавляет оттуда новую строку. Любое другое решение приветствуется.
AllowUserToAddRows = true позволяет мне иметь по крайней мере первую пустую строку, кроме строки, содержащей заголовки. Я хочу решить, что если пользователь не вносит никаких изменений в текущую строку, а только принимает значения такими, какие они есть, и продолжает нажимать вкладку до конца строки, когда текущая строка завершена, необходимо создать новую .
NewRow
всегда рядом с AllowUserToAddRows = true
, а не только тогда, когда у вас нет данных в сетке. Когда пользователи хотят добавить новые данные, они просто начинают редактировать ячейку, и новая строка автоматически добавляется ниже предыдущей NewRow
. -- Вы хотите просто переместить CurrentRow
на этот (ряд с [Row]Index = [DataGridView].NewRowIndex
) при каком-то условии? Вы пытаетесь заставить пользователей редактировать некоторые ячейки? Может быть, вы можете использовать строки и / или ячейки ErrorText
, если что-то не изменилось, как ожидалось? (т. е. возникает событие DataError
или в коде генерируется ошибка синтаксического анализа)
Извините, но я не понимаю, что вы описываете… если пользователь вводит «один» символ в одну из «пустых» ячеек в сетке «новая» строка… создается и отображается «новая» строка и ячейка, введенная пользователем into больше не находится в «новой» строке. Когда вы хотите, чтобы клавиша TAB создавала новую строку? И можете ли вы продемонстрировать, «когда» новая строка не существует, как ожидалось, учитывая, что сетка позволяет добавлять новые строки?
Хорошо, я понимаю, почему вам трудно понять, чего я пытаюсь достичь. Я непреднамеренно упустил, что datagridview не является полностью несвязанным: у него нет источника данных, но он получает данные из вторичного datagridview, где пользователь выбирает строку, и эта строка передается получателю datagridview. У меня нет своего компьютерного банкомата, но я обещаю, что опубликую скрин (и еще немного кода), чтобы лучше понять, о чем я говорю. Еще раз извините за мою ошибку
Есть ли какая-то причина, по которой вы не используете DataSource
для сетки? Затем вы можете просто добавить строку в DataSource
.
Если вы настаиваете на добавлении строк вручную, проблема заключается в том, что код никогда не «добавляет» новую строку в сетку. Код просто использует сетки CurrentRow
для установки значений. Это может работать, но «новая» строка сетки не будет создана.
Использование сеток CurrentRow
таким образом сомнительно... Поэтому вместо того, чтобы использовать для этого сетки CurrentRow
, я предлагаю вам «добавить» новую строку в методе RicercaxCodiceArticolo
. Что-то вроде ниже должно добавить новую строку, а пустая строка «новая-новая» должна быть внизу…
Dim newRowIndex As Int32
newRowIndex = DataGridView1.Rows.Add()
With DataGridView1.Rows(newRowIndex)
.Cells("grdCodice").Value = codice
.Cells("grdDescrizione").Value = descrizione
'.....
End With
Причина, по которой я не использую DataSource для получателя DataGridView, заключается в отсутствии опыта программирования: я не хочу все испортить, используя DataSource, но, возможно, в будущем я исправлю эту часть. Предоставленный вами код работает нормально. Теперь осталось исправить только то, что при добавлении новой строки с помощью вашего метода фокус переходит на новую пустую строку ниже, а не остается на строке, где я вызвал RicercaxCodiceArticolo, но с этим я могу справиться. Большое спасибо.
С
AllowUserToAddRows = true
элемент управления уже показывает пустую новую строку внизу. Новый добавляется, как только вы начинаете редактировать предыдущийNewRow
. То есть непонятно, какую проблему вы пытались решить в первую очередь.