2010年1月27日水曜日

.NET 定数ファイルを作成する ~その5~ 定数のリストを作成する

.NET 定数ファイルを作成する ~その1~
.NET 定数ファイルを作成する ~その2~
.NET 定数ファイルを作成する ~その3~
.NET 定数ファイルを作成する ~その4~ インテリセンスに候補を表示する


以前も書きましたが、WeekDayTypeクラスに定義されている定数メンバをコンボボックスのDataSourceに設定したい場面があります。
その都度リストを作るのが面倒なので、WeekDayTypeクラスに定数リストを持たせたいと思います。

またWeekDayTypeのCd=1のWeekDayTypeオブジェクトを取得できるようにしたいと思います。
こちらはデータベースなどにWeekDayTypeのCd「1」が保存されており、それに対応したWeekDayTypeオブジェクトを取得したいなどといった場面で使用します。


WeekDayTypeクラスにはItemsメンバを追加し、コンストラクタでItemsに定数を追加していきます。
Namespace Constant

    ''' <summary>
    ''' 曜日
    ''' </summary>
    Public NotInheritable Class WeekDayType : Inherits ConstantItem
        
        Public Shared ReadOnly Items As New ConstantItemCollection(Of WeekDayType)

        Public Shared ReadOnly Sun As New WeekDayType(1, "日曜日", "日")
        Public Shared ReadOnly Mon As New WeekDayType(2, "月曜日", "月")
        Public Shared ReadOnly Tue As New WeekDayType(3, "火曜日", "火")
        Public Shared ReadOnly Wed As New WeekDayType(4, "水曜日", "水")
        Public Shared ReadOnly Thr As New WeekDayType(5, "木曜日", "木")
        Public Shared ReadOnly Fri As New WeekDayType(6, "金曜日", "金")
        Public Shared ReadOnly Sat As New WeekDayType(7, "土曜日", "土")

        Private Sub New(ByVal cd As Integer, ByVal name As String, ByVal aliasname As String)
            MyBase.new(cd, name, aliasname)
            Items.Add(Me)
        End Sub

    End Class
End Namespace

ConstantItemCollectionクラス
定数を追加するためのコレクションクラスです。
ConstantItemまたはその派生クラスのみを格納できるListクラスです。
コンボボックスのDataSouceに設定する際、コピーーできるようICloneableインタフェースを実装します。
Namespace Constant
Namespace Constant
    ''' <summary>
    ''' 定数アイテムを管理するコレクションクラスです。
    ''' </summary>
    Public Class ConstantItemCollection(Of T As ConstantItem)
        Inherits List(Of T)
        Implements ICloneable
        
        ''' <summary>
        ''' 定義されている定数アイテムより、引数に指定したcdをもつアイテムを検索します。
        ''' </summary>
        Public Function GetItem(ByVal cd As Integer) As T
            For idx As Integer = 0 To Me.Count - 1
                If cd = CType(Me.Item(idx), ConstantItem).Cd Then
                    Return CType(Me.Item(idx), T)
                End If
            Next
            Return Nothing
        End Function

        ''' <summary>
        ''' 定義されている定数アイテムより、引数に指定したnameをもつアイテムを検索します。
        ''' </summary>
        Public Function GetItem(ByVal name As String) As T
            For idx As Integer = 0 To Me.Count - 1
                If name = CType(Me.Item(idx), ConstantItem).Name Then
                    Return CType(Me.Item(idx), T)
                End If
            Next
            Return Nothing
        End Function
        
        ''' <summary>
        ''' Copyメソッド
        ''' </summary>
        Public Function Copy() As ConstantItemCollection(Of T)
            Return DirectCast(Me.Clone(), ConstantItemCollection(Of T))
        End Function

        '-----ICloneableインターフェースのimplementsメソッド-----

        ''' <summary>
        ''' Cloneメソッド
        ''' </summary>
        Private Function Clone() As Object Implements System.ICloneable.Clone
            '戻り値がObject型だと不便なのでPrivateにしCopyメソッドをPublicで公開します。
            Return Me.MemberwiseClone()
        End Function
        
    End Class
End Namespace

ConstantItemクラスはToStringメソッドをオーバーライドしました。
Namespace Constant

    ''' <summary>
    ''' 定数アイテムの基底クラスです。
    ''' </summary>
    Public MustInherit Class ConstantItem

        '-----フィールド-----

        ''' <summary>コード</summary>
        Protected _iCd As Integer
        ''' <summary>名前</summary>
        Protected _sName As String
        ''' <summary>別名</summary>
        Protected _sAliasName As String

        '-----Publicプロパティ-----

        ''' <summary>コードを取得します</summary>
        Public ReadOnly Property Cd() As Integer
            Get
                Return Me._iCd
            End Get
        End Property
        ''' <summary>名前を取得します。</summary>
        Public ReadOnly Property Name() As String
            Get
                Return Me._sName
            End Get
        End Property
        ''' <summary>別名を取得します。</summary>
        Public ReadOnly Property AliasName() As String
            Get
                Return Me._sAliasName
            End Get
        End Property

        '-----コンストラクタ-----

        ''' <summary>引数を取らないコンストラクタ</summary>
        Private Sub New()
        End Sub
        ''' <summary>コードと名前を引数に取るコンストラクタ</summary>
        Public Sub New(ByVal cd As Integer, ByVal name As String)
            MyBase.New()
            Me._iCd = cd
            Me._sName = name
        End Sub
        ''' <summary>コードと名前と別名を引数に取るコンストラクタ</summary>
        Public Sub New(ByVal cd As Integer, ByVal name As String, ByVal aliasname As String)
            Me.New(cd, name)
            Me._sAliasName = aliasname
        End Sub
        
        '-----Public Overridesメソッド-----

        ''' <summary>
        ''' ToStringメソッド
        ''' </summary>
        Public Overrides Function ToString() As String
            Return String.Format("Cd={0},Nmae={1},AliasName={2}", Me._iCd, Me._sName, Me._sAliasName)
        End Function

    End Class
End Namespace

テストコードです。
フォームにコンボボックスを2つとボタンを1つ配置し、以下のコードを実行します。
Public Class Form1

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        'コンボボックス1にWeekDayTypeの定数リストを設定します。
        Me.ComboBox1.ValueMember = "Cd"
        Me.ComboBox1.DisplayMember = "Name"
        Me.ComboBox1.DataSource = Constant.WeekDayType.Items
        
         'コンボボックス2にWeekDayTypeの定数リストを設定します。
         '※Copyを設定しないとコンボボックス1と連動してしまいます。
        Me.ComboBox2.ValueMember = "Cd"
        Me.ComboBox2.DisplayMember = "Name"
        Me.ComboBox2.DataSource = Constant.WeekDayType.Items.Copy
    End Sub

    Private Sub ComboBox1_SelectedValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectedValueChanged
        'コンボボックスで選択されているWeekDayTypeオブジェクトを取得します。
        Dim weekday As Constant.WeekDayType
        weekday = DirectCast(Me.ComboBox1.SelectedItem, Constant.WeekDayType)
        Console.WriteLine(weekday)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'Cd=2のWeekDayTypeオブジェクトを取得します。
        Dim iWeekDayCd As Integer = 2
        Dim weekday As Constant.WeekDayType = Constant.WeekDayType.Items.GetItem(iWeekDayCd)
        Console.WriteLine(weekday)
    End Sub

End Class

0 件のコメント: