DataGridView в VB.net не позволит мне обновить - PullRequest
0 голосов
/ 18 июня 2009

У меня есть сетка данных с таблицей данных в качестве источника данных. Пользователь может добавлять новые строки в представление данных, но я не отображаю столбец первичного ключа (по понятным причинам) и задаю для него значение .visible = false. Когда мне нужно обновить информацию в сетевом представлении базы данных, я использую sqlClient.SqlCommandBuilder, чтобы затем обновить базовый источник данных (таблица данных, упомянутая выше).

Теперь, поскольку скрытый столбец является первичным ключом, я перебираю сетку данных и программно добавляю обязательное поле первичного ключа в каждую новую строку, которая еще не содержит первичного ключа (строки, добавленные пользователем). Это прекрасно работает в 95% случаев ...

Проблема заключается в том, что пользователь каким-то образом фокусируется в некоторой точке (любой точке) на той нижней строке в сетке данных, под добавленными строками, которая используется для добавления новых строк. Команда update выдает ошибку, утверждая, что она не может вставить ноль в поле первичного ключа, хотя при проверке всех значений в каждой строке она определенно НЕ является нулевой для любого из них.

Я пытался перехватить row.isNewRow (поскольку поле никогда не показывает ноль) и удалял эту строку, но я получаю сообщение об ошибке, в котором говорится, что я не могу удалить незафиксированную строку. Если фокус никогда не уделяется той пустой строке под существующими строками и добавленными пользователем строками, обновление работает нормально.

Что происходит?!

Ответы [ 2 ]

0 голосов
/ 18 мая 2011
Private Sub dataGridView1_RowValidating(ByVal sender As Object, ByVal e As DataGridViewCellCancelEventArgs)
    If dataGridView1.Rows(e.RowIndex) IsNot Nothing AndAlso Not dataGridView1.Rows(e.RowIndex).IsNewRow Then
        Dim [error] As String = ""

        If dataGridView1.Rows(e.RowIndex).Cells("Field1").Value Is Nothing OrElse dataGridView1.Rows(e.RowIndex).Cells("Field1").Value.ToString().Trim() = "" Then
            [error] += " * Field #1" & vbLf
        End If

        If dataGridView1.Rows(e.RowIndex).Cells("Field2").Value Is Nothing OrElse dataGridView1.Rows(e.RowIndex).Cells("Field2").Value.ToString().Trim() = "" Then
            [error] += " * Field #2" & vbLf
        End If

        If [error] <> "" Then
            MessageBox.Show("The following required fields were left blank:" & vbLf & vbLf & [error], "Row Validation Error", MessageBoxButtons.OK, MessageBoxIcon.[Error])
            e.Cancel = True
        End If
    End If
End Sub
0 голосов
/ 15 апреля 2010

Похоже, ваш код пытается удалить новую пустую строку из базы данных - но ее еще нет в базе данных; он «отсоединен» и просто находится в памяти DataGridView ... вот где вам нужно его удалить. Вы можете сделать это с помощью строки в ваших событиях проверки, которые, конечно, будут (или должны) вызываться перед сохранением.

Один из способов справиться с этим - попросить пользователя полностью заполнить новую строку:

Private Sub dataGridView1_RowValidating(ByVal sender As Object, ByVal e As DataGridViewCellCancelEventArgs)
    If dataGridView1.Rows(e.RowIndex) IsNot Nothing AndAlso Not dataGridView1.Rows(e.RowIndex).IsNewRow Then
        Dim [error] As String = ""

        If dataGridView1.Rows(e.RowIndex).Cells("Field1").Value Is Nothing OrElse dataGridView1.Rows(e.RowIndex).Cells("Field1").Value.ToString().Trim() = "" Then
            [error] += " * Field #1" & vbLf
        End If

        If dataGridView1.Rows(e.RowIndex).Cells("Field2").Value Is Nothing OrElse dataGridView1.Rows(e.RowIndex).Cells("Field2").Value.ToString().Trim() = "" Then
            [error] += " * Field #2" & vbLf
        End If

        If [error] <> "" Then
            MessageBox.Show("The following required fields were left blank:" & vbLf & vbLf & [error], "Row Validation Error", MessageBoxButtons.OK, MessageBoxIcon.[Error])
            e.Cancel = True
        End If
    End If
End Sub

Другой способ справиться с этим - удалить (пустую) строку из DataGridView:

Private Sub dataGridView1_RowValidating(ByVal sender As Object, ByVal e As DataGridViewCellCancelEventArgs)
    If dataGridView1.Rows(e.RowIndex) IsNot Nothing AndAlso Not dataGridView1.Rows(e.RowIndex).IsNewRow Then
        dataGridView1.Rows.Remove(e.RowIndex)
    End If
End Sub

Третий популярный способ сделать это - отменить проверку текущей строки, когда ничего не сделано:

Private Sub dataGridView1_RowValidating(ByVal sender As Object, ByVal e As DataGridViewCellCancelEventArgs)
    Dim drv As DataRowView = TryCast(dataGridView1.CurrentRow.DataBoundItem, DataRowView)
    If drv IsNot Nothing AndAlso drv(0) = DBNull.Value Then
        drv.CancelEdit()
        e.Cancel = True
    End If
End Sub

(Также, на заметку: если для вашего первичного ключа (a / k / a identity) установлено значение auto-number, вы можете обнаружить, что ADO.NET лучше справляется с деталями получения следующего идентификатора и тому подобное во время сохранения. Для получения дополнительной информации ознакомьтесь со статьей MSDN «Получение идентификатора значений автонумерации» и , которая представляет собой великолепный набор примеров для SQL Server и MS Access .)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...