え〜と、VB.NETでオブジェクトの生成時にクラスを指定する方法の「名前」が判らずどうやってコーディングするねんと思っていましたが、別の調べ物をしてたときに出てきた「ジェネリッククラス」がどうやらそれっぽいので試しに実装してみましたよと。
Public Module ComboItems ' コンボボックスの特殊最上段アイテムの種類 Public Enum emTopItemKind ALL ' すべて None ' なし End Enum End Module ' コードとテキストを保持するコンボボックスアイテムの基底クラス ' ToStringで「Code: Text」形式の文字列を返す Public Class ComboItemCodeText Dim piCode As Integer = 0 Dim psText As String = "" Dim peTopItem As ComboItems.emTopItemKind = emTopItemKind.None Dim pbIsTopItem As Boolean = False ' 空のアイテムを作成 Public Sub New() Code = 0 Text = "" End Sub ' CodeとTextを指定してアイテムを作成 Public Sub New(ByVal aCode As Integer, ByVal aText As String) Code = aCode Text = aText End Sub ' 特殊最上段アイテムを作成 Public Sub New(ByVal aTopItem As ComboItems.emTopItemKind) peTopItem = aTopItem pbIsTopItem = True End Sub ' ComboBoxに表示するテキストを取得 Public Overrides Function ToString() As String If IsTopItem Then Return ToTopItemString(Me.TopItem) Else Return piCode.ToString + ": " + psText End If End Function ' 最上段アイテムの名前を取得(オーバーライド可能) Protected Overridable Function ToTopItemString(ByVal aItemKind As emTopItemKind) As String Select Case aItemKind Case emTopItemKind.ALL Return "(すべて)" Case emTopItemKind.None Return "(なし)" Case Else Return "" End Select End Function Public Property Code As Integer Get Return piCode End Get Set(ByVal value As Integer) piCode = value End Set End Property Public Property Text As String Get Return psText End Get Set(ByVal value As String) psText = value End Set End Property ' 最上段アイテムを作成するにはコンストラクタで指定するしかない(多分その方が安全) Public ReadOnly Property TopItem As emTopItemKind Get Return peTopItem End Get End Property Public ReadOnly Property IsTopItem As Boolean Get Return pbIsTopItem End Get End Property End Class
VB.NETで名前空間に定数とか宣言するのってPublic Moduleでいいのかな?
includeやusesの概念がない、スコープがゆるゆりゆるゆるなVB.NETはいやらしいわん。
' コードとテキストに併せてジェネリッククラスのオブジェクトを保持するコンボボックスアイテム ' ToStringで、オブジェクトのToStringを返す Public Class ComboItemHasObject(Of T) Inherits ComboItemCodeText Dim poItem As T = Nothing Public Sub New(ByVal aItem As T) MyBase.New() poItem = aItem End Sub Public Sub New(ByVal aCode As Integer, ByVal aText As String, ByVal aItem As T) MyBase.New(aCode, aText) poItem = aItem End Sub ' 特殊最上段アイテムの場合はオブジェクトを格納しない Public Sub New(ByVal aTopItem As ComboItems.emTopItemKind) MyBase.New(aTopItem) End Sub Public Overrides Function ToString() As String If IsTopItem Then Return MyBase.ToString Else Return poItem.ToString End If End Function Public ReadOnly Property Item As T Get Return poItem End Get End Property End Class
あ、このコードは全くテストしてない*1ので利用は自己責任で。
特に、Tのバインドがいつ行われるか知らないので、コーディングの時点で「oComboItemHasObject.Item.***」としてTに指定したクラスのメンバにアクセス出来るかどうかが定かではありません。出来ないと型キャストの嵐になりそうです。
それでも、格納するクラスごとにComboItemCodeTextを継承したクラスを羅列していた今までのコードよりはすっきりしそうですが。