Currently, when using the datetimepicker, after you enter the month you have to either hit the right arrow or the "/" for it to move to the day. Is there a property that I can set or a way to know that the month is done and move to the day and move to the year after the user is done with the day? This is the same behavior with applications written in the old FoxPro/Clipper days.
There is no Property to make it work like what you want, I think you have to handle keypress event and do it by code.
As @Wael Dalloul says, there is no property to do what you want. After a lot of fiddling and Spy++ work, I came upon the following solution, inheriting from System.Windows.Forms.DateTimePicker
:
Override
OnKeyDown
and set or clear a flag based on if the key pressed was a number (and clear the second flag below).protected override void OnKeyDown(KeyEventArgs e) { numberKeyPressed = (e.Modifiers == Keys.None && ((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) || (e.KeyCode != Keys.Back && e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9))); selectionComplete = false; base.OnKeyDown(e); }
Override
WndProc
and trap theWM_REFLECT+WM_NOTIFY
message, extract theNMHDR
fromlParam
, then set another flag if the code is -759 (this event is triggered after one of the fields is completely filled in with the keyboard and a date is selected).protected override void WndProc(ref Message m) { if (m.Msg == WM_REFLECT + WM_NOTIFY) { var hdr = (NMHDR)m.GetLParam(typeof(NMHDR)); if (hdr.Code == -759) //date chosen (by keyboard) selectionComplete = true; } base.WndProc(ref m); }
Override
OnKeyUp
and if both flags are set and the key pressed was a number, manually callbase.WndProc
with aWM_KEYDOWN
followed by aWM_KEYUP
withKeys.Right
, then clear your flags. You can set thelParam
of these messages to 0 and not worry about it, andHWnd
is of coursethis.Handle
.protected override void OnKeyUp(KeyEventArgs e) { base.OnKeyUp(e); if (numberKeyPressed && selectionComplete && (e.Modifiers == Keys.None && ((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) || (e.KeyCode != Keys.Back && e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)))) { Message m = new Message(); m.HWnd = this.Handle; m.LParam = IntPtr.Zero; m.WParam = new IntPtr((int)Keys.Right); //right arrow key m.Msg = WM_KEYDOWN; base.WndProc(ref m); m.Msg = WM_KEYUP; base.WndProc(ref m); numberKeyPressed = false; selectionComplete = false; } }
Apologies for the lack of blank lines in the code, but it wouldn't display right with the blank lines, so I took them out. Trust me, this is the more readable version.