VB.NET チェックボックスやラジオの値をデータテーブルでは”0″、”1″で管理する

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
タイトルとURLをコピーしました