2009-06-17 6 views
0

J'ai un datagridview avec un dataTable comme source de données. L'utilisateur peut ajouter de nouvelles lignes à la grille de données, mais je n'affiche pas la colonne de la clé primaire (pour des raisons évidentes) et la règle sur .visible = false. Lorsque j'ai besoin de mettre à jour les informations de la base de données, j'utilise le sqlClient.SqlCommandBuilder pour mettre à jour la source de données sous-jacente (le dataTable mentionné ci-dessus). Maintenant, parce que la colonne cachée est la clé primaire, je parcourt le datagridview et ajoute par programme le champ de clé primaire requis à chaque nouvelle ligne qui ne contient pas déjà une clé primaire (lignes ajoutées par l'utilisateur). Cela fonctionne très bien 95% du temps ...DataGridView dans VB.net ne me permettra pas de mettre à jour

Le problème est lorsque l'utilisateur donne d'une manière ou d'une autre un certain point (n'importe quel point) à cette rangée du bas sur le datagridview, en dessous de leurs lignes ajoutées, qui est utilisé pour ajouter de nouvelles lignes La commande de mise à jour me donne une erreur indiquant qu'elle ne peut pas insérer null dans le champ de clé primaire, même si lors de la vérification de toutes les valeurs de chaque ligne, elle n'est certainement null pour aucun d'entre eux.

J'ai essayé d'intercepter row.isNewRow (car le champ ne montre jamais null) et de supprimer cette ligne, mais j'obtiens une erreur indiquant que je ne peux pas supprimer une ligne non validée. Si le focus n'est jamais donné à cette ligne vide sous les lignes existantes et les lignes ajoutées par l'utilisateur, la mise à jour fonctionne correctement.

Que se passe-t-il ?!

Répondre

0

Il semble que votre code tente de supprimer la nouvelle ligne vide de la base de données, mais il ne figure pas encore dans la base de données; il est "détaché", et juste dans la mémoire de DataGridView ... donc c'est là que vous devez le supprimer. Vous pouvez le faire avec une ligne dans vos événements de validation, qui bien sûr sera (ou devrait) être appelée avant de sauvegarder.

Une façon de gérer est d'inviter l'utilisateur à remplir complètement la nouvelle ligne:

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 

Une autre façon de le manipuler est d'enlever le (vide) ligne de la 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 

Une troisième façon populaire ce qui peut être manipulé est d'avoir votre validation annuler l'édition de la ligne actuelle quand rien ne se fait:

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 

(De plus, sur une note de côté: si votre champ de clé primaire (a/k/a identity) est défini sur auto-number, vous pouvez trouver que ADO.NET est mieux en mesure de gérer les détails de l'ID suivant tel pendant les arrêts. Pour plus d'informations, consultez la MSDN article on "Retrieving Identity of Autonumber Values" et this great set of examples for both SQL Server and MS Access.)

0
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

Il serait utile de décrire la façon dont ce code répond à la question. – Jason

Questions connexes