2010-03-08 13 views
5

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

0

Non c'è Proprietà per farlo funzionare come quello che vuoi, penso che devi gestire l'evento keypress e farlo per codice.

7

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:

  1. 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; 
    
  2. 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.

  3. 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); 
    } 
    
  4. Override WndProc e intrappolare il messaggio WM_REFLECT+WM_NOTIFY, estrarre il NMHDR da lParam, 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); 
    } 
    
  5. Override OnKeyUp e se entrambe le bandiere sono impostati e il tasto premuto è stato un certo numero, chiamata manualmente base.WndProc con un WM_KEYDOWN seguita da un WM_KEYUP con Keys.Right, quindi cancellare le bandiere. È possibile impostare lo lParam di questi messaggi su 0 e non preoccuparsi, e HWnd è ovviamente this.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.

1

Si lavorerà su WinForms datetimepicker

su evento di modifica del valore incolla il codice qui sotto

sendkeys.send("."); 
Problemi correlati