Emotion Wave Tech Blog

福岡にあるエモーションウェーブ株式会社のエンジニアが書いています。

VB.NETでテキストボックスとコンボボックスの連動を簡単に実装出来るようにしてみた

かなり個別な業務要件かと思いますが、
区分値入力のテキストボックスとコンボボックスが並んでいて、お互いに連動するという仕様がありました。
テキストボックスに「1」って入力すると、その入力値によりコンボボックスも選択値が変わるって感じです。

で、各画面で個別にイベント拾って実装するってのも面倒くさいので、共通クラスで実装してみました。
皆が簡単に実装出来て、コードもすっきりした?と思います。

環境は、VisualBasic2010、.NET Framework 4、コントロールとしてInfragisticsのWindows Formを使用。
NetAdvantage for Windows Forms

こんなクラスを作成。クラス名とか適当。
例外処理は未実装です。

Public Class TextComboEventMapper
    ''' <summary>
    ''' テキストボックスとコンボボックスの関連付け
    ''' </summary>
    ''' <remarks></remarks>
    Private _textBoxToComboBoxMapping As Dictionary(Of String, TextComboMpping)
    ''' <summary>
    ''' コンボボックスとテキストボックスの関連付け
    ''' </summary>
    ''' <remarks></remarks>
    Private _comboBoxToTextBoxMapping As Dictionary(Of String, TextComboMpping)

    ''' <summary>
    ''' テキストボックスとコンボボックスを格納するクラス
    ''' </summary>
    ''' <remarks></remarks>
    Private Class TextComboMpping
        Public Property NumEditor As Infragistics.Win.UltraWinEditors.UltraNumericEditor
        Public Property ComboBoxEditor As Infragistics.Win.UltraWinGrid.UltraCombo
        Public Property DefaultValue As Object = Nothing
    End Class

    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New()
        Me._textBoxToComboBoxMapping = New Dictionary(Of String, TextComboMpping)
        Me._comboBoxToTextBoxMapping = New Dictionary(Of String, TextComboMpping)
    End Sub

    ''' <summary>
    ''' コントロールを追加
    ''' </summary>
    ''' <param name="numEditor">テキストボックス</param>
    ''' <param name="comboBox">コンボボックス</param>
    ''' <remarks></remarks>
    Public Sub Add(ByVal numEditor As Infragistics.Win.UltraWinEditors.UltraNumericEditor,
                   ByVal comboBox As Infragistics.Win.UltraWinGrid.UltraCombo)
        Me.Add(numEditor, comboBox, Nothing)
    End Sub

    ''' <summary>
    ''' コントロールを追加
    ''' </summary>
    ''' <param name="numEditor">テキストボックス</param>
    ''' <param name="comboBox">コンボボックス</param>
    ''' <remarks></remarks>
    Public Sub Add(ByVal numEditor As Infragistics.Win.UltraWinEditors.UltraNumericEditor,
                   ByVal comboBox As Infragistics.Win.UltraWinGrid.UltraCombo,
                   ByVal defaultValue As Object)
        'テキストボックスのLeaveイベントにメソッドを追加
        AddHandler numEditor.Leave, AddressOf NumEditor_Leave
        'コンボボックスValueChangedイベントにメソッドを追加
        AddHandler comboBox.ValueChanged, AddressOf ComboBox_ValueChanged
        'テキストボックスのNameをキーに組み合わせを追加
        Me._textBoxToComboBoxMapping.Add(numEditor.Name,
                                         New TextComboMpping With {
                                             .ComboBoxEditor = comboBox,
                                             .DefaultValue = defaultValue})
        'コンボボックスNameをキーに組み合わせを追加
        Me._comboBoxToTextBoxMapping.Add(comboBox.Name,
                                         New TextComboMpping With {
                                             .NumEditor = numEditor,
                                             .DefaultValue = defaultValue})
    End Sub

    ''' <summary>
    ''' テキストボックスLeave時の処理
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub NumEditor_Leave(sender As Object, e As System.EventArgs)
        'テキストボックスにキャスト
        Dim numEditor = TryCast(sender, Infragistics.Win.UltraWinEditors.UltraNumericEditor)
        'Nameをキーに取得
        Dim map = Me._textBoxToComboBoxMapping.Item(numEditor.Name)
        If (numEditor.Value Is Nothing OrElse IsDBNull(numEditor.Value)) And
            map.DefaultValue IsNot Nothing Then
            '未入力の場合、デフォルト値を設定
            numEditor.Value = map.DefaultValue
            map.ComboBoxEditor.Value = map.DefaultValue
        Else
            map.ComboBoxEditor.Value = numEditor.Value
        End If
    End Sub

    ''' <summary>
    ''' コンボボックス値変更時の処理
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub ComboBox_ValueChanged(sender As Object, e As System.EventArgs)
        'コンボボックスにキャスト
        Dim comboBox = TryCast(sender, Infragistics.Win.UltraWinGrid.UltraCombo)
        'Nameをキーに取得
        Dim map = Me._comboBoxToTextBoxMapping.Item(comboBox.Name)
        If (comboBox.Value Is Nothing OrElse IsDBNull(comboBox.Value)) And
            map.DefaultValue IsNot Nothing Then
            '未入力の場合、デフォルト値を設定
            comboBox.Value = map.DefaultValue
            map.NumEditor.Value = map.DefaultValue
        Else
            map.NumEditor.Value = comboBox.Value
        End If
    End Sub
End Class

で、各画面はFormのLoad時に以下の様に書いとく。

Dim em As New TextComboEventMapper
em.Add(Me.numOyakoKbn, Me.cmbOyakoKbn, "0")
em.Add(Me.numShohizeiKbn, Me.cmbShohizeiKbn, "1")

すると、各コントロールのイベントでテキストボックスとコンボボックスの値が連動されたりします。