人気ブログランキング | 話題のタグを見る
(.Net)DataGridViewでの入力チェックはCellValidatingだけではダメ
現在、CellValidatingイベントでセルの入力チェックを行っていたのですが、どうやら CellValidating だけでチェックしたのではダメっぽいです。
たとえば複数列の DataGridView で全列Null不可の条件かつ登録ボタンを押下すれば、DBに反映するというような場合、新規行のどっかのセルに値を入れて、そのまま登録ボタンを押下すれば、null値がDBに登録されてしまい、DBがnullを許してないため、例外が発生します。

なので、入力チェックは CellValidating イベントだけでなく、RowValidating も使ってやる必要ありそうです。
RowValidating なら、ここで全セルをチェックしてやればいいだけですからね。

ということで、簡単なサンプルです。
これは、CellValidating と、RowValidating で入力チェックを行っています。
RowValidating だけでもいいんでしょうが、こまかい制御をかけさせたいという要件もあると思うので CellValidating でもチェックさせます。

DBにはMDBを、列IDはオートナンバー型なのでここの値の割り振りはJETエンジンに任せてます。
列name1は文字列、列name2は数値型で、両方とも空値は認めません。
DataSetは下記のようなイメージで作ってます。
(.Net)DataGridViewでの入力チェックはCellValidatingだけではダメ _e0091163_17225147.jpg


Public Class Form1
 
'DataTable
Private mTable1Dtbl As New Database1DataSet.table1DataTable()
'TableAdapter
Private mTable1Adp As New Database1DataSetTableAdapters.table1TableAdapter()
 
''' <summary>
''' フォームロード
''' </summary>
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'DataTableにDBの情報を取得し、DataGridViewにバインドさせる
mTable1Adp.Fill(mTable1Dtbl)
Me.DataGridView1.DataSource = mTable1Dtbl
End Sub
 
''' <summary>
''' 登録ボタン押下
''' </summary>
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'DataGridView-->DataTableの情報をDBに反映
mTable1Adp.Update(mTable1Dtbl)
'DBから情報取得し、DataGridViewに表示
mTable1Adp.Fill(mTable1Dtbl)
End Sub
 
''' <summary>
''' セルのValidating
''' </summary>
Private Sub DataGridView1_CellValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellValidatingEventArgs) Handles DataGridView1.CellValidating
Dim dgv As DataGridView = CType(sender, DataGridView)
'入力チェックに引っ掛かれば、イベントをキャンセルする
'新規行はチェックしない
If dgv.Rows(e.RowIndex).IsNewRow Then
Return
End If
If dgv.Columns(e.ColumnIndex).Name = "name1" Then
If Not InputCheck_name1(e.FormattedValue) Then
Console.WriteLine("CellError")
e.Cancel = True
Return
End If
End If
If dgv.Columns(e.ColumnIndex).Name = "name2" Then
If Not InputCheck_name2(e.FormattedValue) Then
Console.WriteLine("CellError")
e.Cancel = True
Return
End If
End If
End Sub
 
 
''' <summary>
''' 行のValidating
''' </summary>
Private Sub DataGridView1_RowValidating(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellCancelEventArgs) Handles DataGridView1.RowValidating
Dim dgv As DataGridView = CType(sender, DataGridView)
'入力チェックに引っ掛かれば、イベントをキャンセルする
'新規行、コミットされてない行がない場合はチェックしない
If dgv.Rows(e.RowIndex).IsNewRow OrElse Not dgv.IsCurrentRowDirty Then ' OrElse e.RowIndex = dgv.NewRowIndex OrElse dgv("id", e.RowIndex).Value Is Nothing Then
Return
End If
 
If Not InputCheck_name1(dgv.Rows(e.RowIndex).Cells("name1").Value.ToString()) OrElse Not InputCheck_name2(dgv.Rows(e.RowIndex).Cells("name2").Value.ToString()) Then
Console.WriteLine("RowError")
e.Cancel = True
End If

 
End Sub
 
''' <summary>
''' name1列の入力チェック
''' </summary>
Private Function InputCheck_name1(ByVal value As String) As Boolean
If String.IsNullOrEmpty(value) Then
MessageBox.Show("入力エラーname1")
Return False
End If
Return True
End Function
 
''' <summary>
''' name2列の入力チェック
''' </summary>
Private Function InputCheck_name2(ByVal value As String) As Boolean
If String.IsNullOrEmpty(value) Then
MessageBox.Show("入力エラーname2")
Return False
End If
If Not Integer.TryParse(value, 0) Then
MessageBox.Show("入力エラーname2")
Return False
End If
Return True
End Function
End Class


この場合だと、一つでも入力エラーとなれば、正しい値を入れるまで何もできない(フォームを閉じることさえ)ので、実装には工夫が必要ですね。

参考:
MSDNフォーラム:レコードにNull値があるか調べる方法
by jehoshaphat | 2009-02-05 22:19 | .Net開発 | Comments(0)


<< (.Net)DataGridV... (.Net)DataGridV... >>