Attualmente, quando si utilizza il datimepicker, dopo aver inserito il mese è necessario premere la freccia destra o "/" per spostarsi al giorno. C'è una proprietà che posso impostare o un modo per sapere che il mese è finito e passare al giorno e passare all'anno dopo che l'utente ha finito il giorno? Questo è lo stesso comportamento con le applicazioni scritte nei vecchi giorni FoxPro/Clipper.DateTimePicker passa automaticamente alla data successiva
risposta
Non c'è Proprietà per farlo funzionare come quello che vuoi, penso che devi gestire l'evento keypress e farlo per codice.
Come dice @Wael Dalloul, non c'è proprietà per fare ciò che vuoi. Dopo un sacco di giocherellare e di lavoro Spy ++, mi sono imbattuto la seguente soluzione:
Ereditando da
System.Windows.Forms.DateTimePicker
, e dichiarando campi privati per le bandiere:public class DPDateTimePicker : DateTimePicker { private bool selectionComplete = false; private bool numberKeyPressed = false;
Definire le costanti e le strutture per Win API:
private const int WM_KEYUP = 0x0101; private const int WM_KEYDOWN = 0x0100; private const int WM_REFLECT = 0x2000; private const int WM_NOTIFY = 0x004e; [StructLayout(LayoutKind.Sequential)] private struct NMHDR { public IntPtr hwndFrom; public IntPtr idFrom; public int Code; }
E 'anche necessario includere un'istruzione using per
System.Runtime.InteropServices
al fine di utilizzare Win API.Ignora
OnKeyDown
e imposta o deseleziona un flag in base a se il tasto premuto era un numero (e deseleziona la seconda bandiera in basso).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
e intrappolare il messaggioWM_REFLECT+WM_NOTIFY
, estrarre ilNMHDR
dalParam
, quindi impostare un'altra bandiera, se il codice è -759 (questo evento viene attivato dopo uno dei campi è completamente riempito con la tastiera e una data è selezionata).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
e se entrambe le bandiere sono impostati e il tasto premuto è stato un certo numero, chiamata manualmentebase.WndProc
con unWM_KEYDOWN
seguita da unWM_KEYUP
conKeys.Right
, quindi cancellare le bandiere. È possibile impostare lolParam
di questi messaggi su 0 e non preoccuparsi, eHWnd
è ovviamentethis.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; } }
Ci scusiamo per la mancanza di righe vuote nel codice, ma non sarebbe visualizzare giusto con le righe vuote, così li ho tirato fuori. Fidati di me, questa è la versione più leggibile.
Si lavorerà su WinForms datetimepicker
su evento di modifica del valore incolla il codice qui sotto
sendkeys.send(".");