【.NET】DateTimePickerを年月表示で利用する際の注意点

こんにちは、irislabのちひろです。

今回の内容はMicrosoft .NET Framework(C#, VB.NET)のプログラムでDateTimePickerコントロールを年月表示にして使用する際の注意点です。

標準状態のDateTimePickerは年月日を表示していますが、場合によっては年月のみを表示したい場合があります。
それ自体は、以下のようにプロパティを設定することで実現することができます。

[C#]

1
2
dateTimePicker1.CustomFormat = "yyyy年MM月";
dateTimePicker1.Format = System.Windows.Formas.DateTimePickerFormat.Custom;

[VB.NET]

1
2
DateTimePicker1.CustomFormat = "yyyy年MM月"
DateTimePicker1.Format = System.Windows.Formas.DateTimePickerFormat.Custom

しかし、上記のままでは実行時に以下のようなエラーが発生する場合があります。

型 'System.ArgumentOutOfRangeException' のハンドルされていない例外が mscorlib.dll で発生しました。追加情報:Year、Month および Day パラメーターが表現できない DateTime を示しています。

エラーが発生するタイミングとしてはDateTimePickerのValueプロパティが2015/11/30のような月末日になっている状態で、年月が2月となるように入力した場合があります。
DateTimePicker内部の動きはわかりませんが、文字入力時に2015/02/30という無効な日付になってしまうことで上記のようなエラーが発生しているのでは?と思います。
ただ、2015/10/31を11月にする場合は問題がなかったりするので、エラーを見たことが無い人も居るかもしれません。

さて、前置きが長くなってしまいましたが対策です。
今回は年月しか使用しないという前提のため、DateTimePickerのValueプロパティが変化した際に値を2015/11/01のような月初日に変更してしまいます。

下の例では分かりやすさ重視のためDateTimePickerを継承したクラスを作成しています。

[C#]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System;
 
public class DateTimePickerEx
    : System.Windows.Forms.DateTimePicker
{
    public DateTimePickerEx()
    {
        ValueChanged += DateTimePickerEx_ValueChanged;
        Value = DateTime.Now;
        CustomFormat = "yyyy年MM月";
        Format = System.Windows.Formas.DateTimePickerFormat.Custom;
    }
 
    private void DateTimePickerEx_ValueChanged(object sender, EventArgs e)
    {
        Value = Value.AddDays(Value.Day * -1 + 1);
    }
}

[VB.NET]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Imports System
 
Public Class DateTimePickerEx
    Inherits DateTimePicker
 
    Public Sub New()
 
        AddHandler ValueChanged, AddressOf DateTimePickerEx_ValueChanged
        Value = DateTime.Now
        CustomFormat = "yyyy年MM月"
        Format = System.Windows.Formas.DateTimePickerFormat.Custom
 
    End Sub
 
    Private Sub DateTimePickerEx_ValueChanged(sender As Object, e As EventArgs)
 
        Value = Value.AddDays(Value.Day * -1 + 1)
 
    End Sub
 
End Class

完全に余談となりますがラムダ式を使用してもう少しだけ簡潔に記載できますのでお好みでどうぞ。

[C#]

1
2
3
4
5
6
7
8
9
10
11
12
13
using System;
 
public class DateTimePickerEx
    : System.Windows.Forms.DateTimePicker
{
    public DateTimePickerEx()
    {
        ValueChanged += (sender, e) => { Value = Value.AddDays(Value.Day * -1 + 1); };
        Value = DateTime.Now;
        CustomFormat = "yyyy年MM月";
        Format = System.Windows.Formas.DateTimePickerFormat.Custom;
    }
}

[VB.NET]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Imports System
 
Public Class DateTimePickerEx
    Inherits DateTimePicker
 
    Public Sub New()
 
        AddHandler ValueChanged, Sub(sender, e) Value = Value.AddDays(Value.Day * -1 + 1)
        Value = DateTime.Now
        CustomFormat = "yyyy年MM月"
        Format = System.Windows.Formas.DateTimePickerFormat.Custom
 
    End Sub
 
End Class

関連する記事

カテゴリー: .Net タグ: , , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれないコメントは無視されますのでご注意ください。(スパム対策)