DateTimePickerコントロールを和暦表示できるように拡張してみた

VB .NETで和暦で日付を表示するという要件があり、調べてみたところYamakiさんの記事えムナウさんの記事がみつかりました。

個別に制御用コードを書くよりもコントロールにしてしまった方がフォームデザイナーでペタペタ貼れて便利そうだし、表示ついでに入力もできたらラクなんじゃないかと思い、DateTimePickerコントロールを拡張してみました。

拡張したコントロールでは、フォーカスがあるときは入力用書式(InputFormatプロパティに設定された書式)に基づき入力が行い、フォーカスがないときは和暦で表示を行います。
無精ついでにUpdateDisplayFormatメソッドをオーバーライドすると表示用の書式を変更できるようにしています。
(動作確認はVisual Studio 2013 Update 4で行いました。)

※2017/01/28追記 開発初心者さんよりフォーム作成時の「年」と実行時の「年」が異なる際の挙動についてご指摘をいただき、InputFormatプロパティのセット時にも表示内容を更新するように変更しました。
開発初心者さん、ご指摘ありがとうございました。

'''
''' 和暦表示に対応したDateTimePickerコントロール
'''
'''
''' コントロールにフォーカスがあるときは、設定された入力用書式に基づき日時入力が行うことができる。
'''
Public Class JpDateTimePicker Inherits DateTimePicker

    Private _calendar As System.Globalization.JapaneseCalendar
    Private _culture As System.Globalization.CultureInfo
    Private _inputFormat As String

    '''
    '''
    '''
    Public Sub New()

        Me.Format = DateTimePickerFormat.Custom

        ' 和暦とカルチャーの初期化
        _calendar = New System.Globalization.JapaneseCalendar()
        _culture = New System.Globalization.CultureInfo("ja-JP")
        _culture.DateTimeFormat.Calendar = _calendar

        ' デフォルトの入力用書式設定
        _inputFormat = "yyyy/MM/dd"

        ' 表示用書式の適用
        UpdateDisplayFormat()

        ' ハンドラの定義
        AddHandler Me.GotFocus, AddressOf FocusChangedHandler
        AddHandler Me.LostFocus, AddressOf FocusChangedHandler
        AddHandler Me.ValueChanged, AddressOf ValueChangedHandler

    End Sub

    '''
    ''' 入力用書式の取得と設定
    '''
    '''
    '''
    Public Property InputFormat As String
        Get
            Return _inputFormat
        End Get
        Set(value As String)
            _inputFormat = value
            UpdateDisplayFormat()
        End Set
    End Property

    '''
    ''' GotFocus/LostFocusのハンドラ
    '''
    '''
    '''
    Private Sub FocusChangedHandler(ByVal sender As System.Object, ByVal e As System.EventArgs)

        ' コントロールにフォーカスがあるときは入力用のフォーマットに、
        ' ないときは表示用のフォーマットに
        If Me.Focused Then
            Me.CustomFormat = _inputFormat
        Else
            UpdateDisplayFormat()
        End If

    End Sub

    '''
    ''' ValueChangedのハンドラ
    '''
    '''
    '''
    Private Sub ValueChangedHandler(ByVal sender As System.Object, ByVal e As System.EventArgs)

        ' コントロールにフォーカスがあるときは表示の更新処理をパスする
        If Me.Focused Then
            Return
        End If

        ' 表示値の更新
        UpdateDisplayFormat()

    End Sub

    '''
    ''' 表示の更新
    '''
    ''' このメソッドをオーバーライドすると任意の書式で表示ができる
    Protected Overridable Sub UpdateDisplayFormat()
        Me.CustomFormat = Me.Value.ToString("ggyy", _culture) + "年MM月dd日 (ddd)"
    End Sub
End Class

動作イメージ。上段がフォーカスありで入力状態のDateTimePicker、下段がフォーカスなしで表示状態のDateTimePicker。
拡張したDateTimePickerの動作イメージ

makoto について

デジタルガジェット大好き!! 小さい機械を片手に、JavaとFlex、PHPなど、いろいろなプログラミング言語・環境を行ったり来たりしながらプログラムを書いています。 最近お気に入りな環境は、Visual StudioとFileMaker。
カテゴリー: コードスニペット, 技術的なメモ タグ: パーマリンク

DateTimePickerコントロールを和暦表示できるように拡張してみた への2件のフィードバック

  1. 開発初心者 のコメント:

    和暦を濫用(?)している職場で、かなり役立ちました!ありがとうございます!
    →上記コードのままでは、初期表示時(JpDateTimePickerを貼ったFormのLoad時)にCustomFormatが効いてないことがあり、「?」でした。
    検討しましたところ、16行目~36行目を通った後、43行目を通り、47行目でCustomFormatの値が「Visual Studioのプロパティウインドウ内で設定したCustomFormatの値」に変更されてしまいます。
    「Visual Studioのプロパティウインドウ内で設定したCustomFormatの値」は、”ggyy”部分が、コントロールを配置したときの年になるので、年が変わって実行すると(見た目だけ)Todayじゃない問題が発生します。
    正しい処理かわかりませんが、48行目の下にUpdateDisplayFormat()を追記したところ思った動きになりましたのでコメントさせていただきました。(結局29行目の記述も不要となります。)
    (Visual Studio 2013使用)

    • makoto のコメント:

      ご指摘ありがとうございます!!

      たしかにその通りですね。
      教えていただいたように修正して掲載いたします。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です