3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

(.Net)DataGridViewでの入力チェックに引っ掛かったら行を消す方法

(.Net)DataGridViewでの入力チェックはCellValidatingだけではダメの続きとなります。

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

今回はその工夫の1つで、間違った入力をされたら、その行は消すという方法です。

列数が1つとか2つかの場合には有効だと思います。

実際に行を消すのは RowValidated イベントで行っています。

厄介だったのは、Row.Delete() のときにまた、RowValidated イベントが走ってしまうという点です。

これを回避するために、賢い方法ではないですが、例外を捕まえてキャンセルさせるという方法にしました。もっといい方法はないんでしょうかね。

下記がコードです。DataTable等の環境は前回と同じです。

Public Class Form1

 

'DataTable

Private mTable1Dtbl As New Database1DataSet.table1DataTable()

'TableAdapter

Private mTable1Adp As New Database1DataSetTableAdapters.table1TableAdapter()

 

'''

''' フォームロード

'''

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

 

'''

''' 登録ボタン押下

'''

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

 

 

'''

''' セルのValidating

'''

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

 

'''

''' 行のValidated

'''

Private Sub DataGridView1_RowValidated(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.RowValidated

Dim dgv As DataGridView = CType(sender, DataGridView)

'DataRowViewはDataGridViewにDataTableをバインドしてる時の仲介役みたいなもの

Dim drv As DataRowView

 

'すでに削除された場合は処理させない

Try

drv = DirectCast(dgv.Rows(e.RowIndex).DataBoundItem, DataRowView)

Catch ex As IndexOutOfRangeException

Return

End Try

 

'新規行また、削除された行の場合は処理させない

If dgv.Rows(e.RowIndex).IsNewRow 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

'対象行が新規に追加されてたものなら削除

If drv.Row.RowState = DataRowState.Added Then

drv.Row.EndEdit()

'行削除

drv.Row.Delete()

End If

End If

End Sub

 

'''

''' name1列の入力チェック

'''

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

 

'''

''' name2列の入力チェック

'''

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

なかなか DataGridView は機能が豊富すぎて使いこなすまで時間かかりそうです。