2008年10月2日木曜日

.NET DateTimePickerで1桁入力しTabキーで移動すると入力値が取得できない

DateTimePickerで日付などを1桁入力し、Tabキーで移動するとDateTimePickerのValidatingイベント、Validatedイベントで入力値を取得することができません。

VS2005、VS2008で確認しました。
このような画面でDateTimePickerの日付部分に1桁「1」を入力し、Tabキーでコントロールを移動します。


Formには以下のようなコードを書きました。
Public Class Form1

Private Sub DateTimePicker1_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles DateTimePicker1.Leave
Console.WriteLine("Leave:" & Me.DateTimePicker1.Value.ToString)
End Sub

Private Sub DateTimePicker1_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles DateTimePicker1.Validated
Console.WriteLine("Validated:" & Me.DateTimePicker1.Value.ToString)
End Sub

Private Sub DateTimePicker1_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles DateTimePicker1.Validating
Console.WriteLine("Validating:" & Me.DateTimePicker1.Value.ToString)
End Sub

Private Sub DateTimePicker1_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DateTimePicker1.ValueChanged
Console.WriteLine("ValueChanged:" & Me.DateTimePicker1.Value.ToString)
End Sub

End Class


実行結果は以下のようになりました。
Leave:2008/10/02 8:54:24
Validating:2008/10/02 8:54:24
Validated:2008/10/02 8:54:24
ValueChanged:2008/10/01 8:54:24

これは年月日のいずれでも1桁入力し、Tabキーで移動した場合に発生します。

回避方法はLeaveイベントでMe.ActiveControl = Me.ActiveControlを記述します。
Public Class Form1

Private Sub DateTimePicker1_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles DateTimePicker1.Leave
     '1桁入力しTabキーで移動した際に入力値が取得できない問題を回避します。
     Me.ActiveControl = Me.ActiveControl
Console.WriteLine("Leave:" & Me.DateTimePicker1.Value.ToString)
End Sub

Private Sub DateTimePicker1_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles DateTimePicker1.Validated
Console.WriteLine("Validated:" & Me.DateTimePicker1.Value.ToString)
End Sub

Private Sub DateTimePicker1_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles DateTimePicker1.Validating
Console.WriteLine("Validating:" & Me.DateTimePicker1.Value.ToString)
End Sub

Private Sub DateTimePicker1_ValueChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles DateTimePicker1.ValueChanged
Console.WriteLine("ValueChanged:" & Me.DateTimePicker1.Value.ToString)
End Sub

End Class


実行結果は以下のようになりました。
ValueChanged:2008/10/01 9:12:40
Leave:2008/10/01 9:12:40
Validating:2008/10/01 9:12:40
Validated:2008/10/01 9:12:40

DateTimePickerを継承したカスタムコントロールを作成し、Leaveイベントで以下のようにしておくと便利かと思います。
Public Class CustomControl1
Inherits System.Windows.Forms.DateTimePicker

Protected Overrides Sub OnLeave(ByVal e As System.EventArgs)
Me.FindForm.ActiveControl = Me.FindForm.ActiveControl
MyBase.OnLeave(e)
End Sub
End Class

0 件のコメント: