Windowsフォームの入力項目の値をデータテーブルに格納する際、画面項目にデータテーブルをバインドする際の備忘録です。
今回は不慣れなVB.NETでの開発に挑みました。
データテーブルの内容を参照元・更新先のDBのカラムの値に合わせようと少し工夫してみた話です。
テキストボックスはTextプロパティをバインドするのですが、チェックボックスやラジオボタンは、"1" か "0" でデータを持っておきたい。
Checkedプロパティをどうやって"1"や"0"にすべきか・・・
というわけで、調べて検証した結果、Binding.Parseと.Formatを使うことで対応できました。
以下のようなソースになったので貼り付けます。参考にしてみてください。
(画面構成は以下のとおりです。)
Public Class Form1
Private bind As BindingSource
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
bind = New BindingSource
'データテーブルおよび列の設定
Dim dt = New DataTable("FORM")
dt.Columns.Add("DT_" & TextBox1.Name, GetType(String))
dt.Columns.Add("DT_" & CheckBox1.Name, GetType(String))
dt.Columns.Add("DT_" & RadioButton1.Name, GetType(String))
dt.Columns.Add("DT_" & RadioButton2.Name, GetType(String))
dt.Rows.Add(dt.NewRow)
'データテーブルをバインドする
bind.DataSource = dt
Dim binder As Binding
For Each ctrl As Control In Me.Controls
Select Case ctrl.Name
Case "TextBox1"
'テキストボックスのテキストプロパティをバインドデータの列にバインドする
ctrl.DataBindings.Add("Text", bind, "DT_" & ctrl.Name, True, DataSourceUpdateMode.OnPropertyChanged)
Case "CheckBox1", "RadioButton1", "RadioButton2"
'チェックボックス、ラジオのチェックプロパティをバインドデータの列にバインドする
binder = New Binding("Checked", bind, "DT_" & ctrl.Name, True, DataSourceUpdateMode.OnPropertyChanged)
AddHandler binder.Format, AddressOf Binder_Format
AddHandler binder.Parse, AddressOf Binder_Parse
ctrl.DataBindings.Add(binder)
End Select
'フォーカスアウト時にバインドデータの表示値を最新化する
AddHandler ctrl.Leave, AddressOf Control_Accept
Next
DataGridView1.DataSource = bind
End Sub
Private Sub Binder_Format(ByVal sender As Object, ByVal e As System.Windows.Forms.ConvertEventArgs)
Debug.WriteLine("Format(1):" & DirectCast(sender, Binding).Control.Name & "=" & e.Value.ToString)
'バインドデータを画面コントロールの値に変換する(String(0 or 1) -> Boolean)
If e.Value Is Nothing Then
e.Value = False
Else
e.Value = IIf("1".Equals(e.Value.ToString), True, False)
End If
Debug.WriteLine("Format(2):" & DirectCast(sender, Binding).Control.Name & "=" & e.Value.ToString)
End Sub
Private Sub Binder_Parse(ByVal sender As Object, ByVal e As System.Windows.Forms.ConvertEventArgs)
Debug.WriteLine("Parse(1):" & DirectCast(sender, Binding).Control.Name & "=" & e.Value.ToString)
'画面コントロールの値をバインドデータの値に変換する(Boolean -> String(0 or 1)
If e.Value Is Nothing Then
e.Value = "0"
Else
e.Value = IIf(e.Value.ToString.Equals(True.ToString), "1", "0")
End If
Debug.WriteLine("Parse(2):" & DirectCast(sender, Binding).Control.Name & "=" & e.Value.ToString)
End Sub
Private Sub Control_Accept(ByVal sender As Object, ByVal e As System.EventArgs)
Debug.WriteLine("ControlAccept:" & sender.ToString)
bind.ResetBindings(False)
End Sub
Private Sub DataGridView1_CellValidated(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellValidated
bind.ResetBindings(False)
End Sub
End Class