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