2010-03-08 36 views
5

當前,使用datetimepicker時,輸入月份後必須按右箭頭或「/」移動到當天。是否有我可以設置的屬性或一種方法來知道該月完成並移動到當天,並在用戶完成一天之後移動到一年?這與在舊的FoxPro/Clipper日子中編寫的應用程序的行爲相同。DateTimePicker自動移動到下一個日期部分

回答

0

沒有屬性使它像你想要的那樣工作,我認爲你必須處理按鍵事件並通過代碼來完成。

7

正如@Wael Dalloul所說,沒有財產去做你想做的事。大量的小提琴演奏和Spy ++的工作後,我來到了以下解決方案:

  1. System.Windows.Forms.DateTimePicker繼承,並聲明私有字段標誌:

    public class DPDateTimePicker : DateTimePicker 
    { 
        private bool selectionComplete = false; 
        private bool numberKeyPressed = false; 
    
  2. 定義爲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; 
        }  
    

    這也是必要的,包括爲了用Win API using語句爲System.Runtime.InteropServices

  3. 重寫OnKeyDown並根據按下的鍵是否是數字(並清除下面的第二個標誌)來設置或清除標誌。

    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. 覆蓋WndProc和陷阱WM_REFLECT+WM_NOTIFY消息,提取NMHDRlParam,然後設置另一個標誌,如果該代碼爲-759(該事件中的一個字段與所述鍵盤被完全填充在後觸發日期被選中)。

    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. 覆蓋OnKeyUp如果兩個標誌設置和按下的鍵是一個數字,手動調用base.WndProcWM_KEYDOWN接着用Keys.Right一個WM_KEYUP,然後清除標誌。您可以將這些消息的lParam設置爲0而不用擔心,而HWnd當然是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; 
        } 
    } 
    

道歉缺乏代碼空行,但它不會正確使用空行顯示,所以我就拿出來。相信我,這是更可讀的版本。

1

它將在WinForms的價值變化事件的DateTimePicker

粘貼下面的代碼

sendkeys.send("."); 
工作
相關問題