ユーザーによる列の追加、削除を許可するDataGridViewの機能はOffとし、列の追加、列の削除ボタンを作って対応する(列追加許可をOnにすると動作がよくわからない。またOffにするとRowHeaderを表示する必要がなくなり、すっきりする?)
バインド元のDataTableでRows.Addを行うときに、もしCurrentCellが新規行のとき、動作が何か変。新規行上で動作がへんになるので、いっそユーザーによる追加を許可しない様にすればいいのか。
DataTableにバインドするときは、なぜかDataGridViewRow.DataBoundItemが(一見DataRowになりそうだが)DataRowViewになる
これは、DataTableがIListSourceを実装しており、GetListメソッドで返す値がDataRowViewだからかもしれない
以下がサンプルコード。
これでてっとり早く、制約を外して、かつエラーメッセージを出すことができる。(もしかしたら動作が遅いかもしれない)
サーバーに書きこむ前には、DataSet.EnForceConstraints = Trueとする(ここで、制約違反が残っている場合、例外が発生してConstraintが有効にならない)。
Private Sub DataGridView1_CellValidated(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValidated
Dim currentSourceRowView As DataRowView = CType(DataGridView1.Rows(e.RowIndex).DataBoundItem, DataRowView)
If Not currentSourceRowView Is Nothing Then
currentSourceRowView.EndEdit()
End If
Try
Me.ClearErrors()
DataSet1.EnforceConstraints = True
Catch ex As ConstraintException
' 制約違反については、無視する
End Try
DataSet1.EnforceConstraints = False
' 現在の行以外でのエラーアイコンを描写させるために必要
DataGridView1.Refresh()
End Sub
Private Sub ClearErrors()
Dim errorRows = DataSet1.DataTable1.GetErrors()
For Each row In errorRows
row.RowError = Nothing
Dim errorCells = row.GetColumnsInError()
For Each cell In errorCells
row.SetColumnError(cell.ColumnName, Nothing)
Next
Next
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
DataSet1.EnforceConstraints = False
End Sub