今、郵便番号を複数の画面で検索する場合を想定します。
郵便番号を入力して[住所検索]ボタンをクリックすると住所を表示し、住所を入力して[郵便番号検索]ボタンをクリックすると郵便番号を表示するというものです。
ここには、二つのTextBoxと二つのボタン、すなわち郵便番号を入出力するTextBox(あるいはMaskedTextBox)、住所を入出力するTextBox 、入力した郵便番号から住所を検索出力するためのボタン、逆に住所から郵便番号を検索出力するためのボタンがあります。
いまここで、ボタンにはそれぞれ郵便番号から住所を検索出力する、逆に住所から郵便番号を検索出力するプログラムが対応しているものとします。
あちこちの郵便番号検索画面で、これらのコントロールを配置しボタンのイベントプロシージャをその都度書くのは嫌です。
一つの解決策は、上のすべてのコントロールを一つにカスタムコントロールにする手があります。
が、少し大げさなので、次のようなクラスを一つ作っています。
主眼は、このクラスのインスタンスを作るとき、クライアントのコントロールをByRefで渡すこと、渡されたコントロールのイベントをこのクラスの中に定義することです。
Public Class cls住所検索 Friend WithEvents m_btn住所検索 As Button Friend WithEvents m_btn郵便番号検索 As Button Private m_msk郵便番号 As MaskedTextBox Private m_txt住所 As TextBox Sub New(ByRef btn住所検索 As Button, ByRef btn郵便番号検索 As Button, _ ByRef msk郵便番号 As MaskedTextBox, ByRef txt住所 As TextBox) m_btn住所検索 = btn住所検索 m_btn郵便番号検索 = btn郵便番号検索 m_msk郵便番号 = msk郵便番号 m_txt住所 = txt住所 End Sub Private Sub btn住所検索_Click(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles m_btn住所検索.Click Using frm As New frm住所取得 frm.Called郵便番号2住所(m_msk郵便番号.Text) If frm.DialogResult = Windows.Forms.DialogResult.OK Then m_txt住所.Text = frm.P_住所 Else MsgBox("この郵便番号は、有効ではありません。郵便番号を変更してください。", _ MsgBoxStyle.Exclamation, "住所検索") End If End Using End Sub Private Sub btn郵便番号検索_Click(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles m_btn郵便番号検索.Click Using frm As New frm郵便番号取得 frm.Called住所2郵便番号(m_txt住所.Text) If frm.DialogResult = Windows.Forms.DialogResult.OK Then m_msk郵便番号.Text = frm.P_郵便番号 Else MsgBox("この住所は、有効ではありません。住所を変更してください。", _ MsgBoxStyle.Exclamation, "郵便番号検索") End If End Using End Sub End Class
これを使う画面のコードは、次のようになります。
Private inst住所検索 As cls住所検索 Private Sub frm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load inst住所検索 = New cls住所検索(btn契約者住所検索, btn契約者郵便番号検索, _ msk契約者郵便番号, txt契約者住所1) End Sub
すなわち、各画面ではこのクラスのインスタンスを作るだけで、処理はすべてこのクラスが行います。
私はこのような仕組みをよく使います。
たとえば、氏名を漢字で入力するとそのふりがなを別のTextBoxに表示する場合も同様です。