2010-03-08 32 views
5

Hiện tại, khi sử dụng bảng kê dữ liệu, sau khi bạn nhập tháng bạn phải nhấn mũi tên phải hoặc "/" để di chuyển đến ngày đó. Có một tài sản mà tôi có thể thiết lập hoặc một cách để biết rằng tháng được thực hiện và di chuyển đến ngày và di chuyển đến năm sau khi người dùng được thực hiện với ngày? Đây là hành vi tương tự với các ứng dụng được viết trong các ngày FoxPro/Clipper cũ.DateTimePicker tự động di chuyển đến ngày tiếp theo

Trả lời

0

Không có Thuộc tính để làm cho nó hoạt động như những gì bạn muốn, tôi nghĩ bạn phải xử lý sự kiện nhấn phím và thực hiện theo mã.

7

Như @Wael Dalloul nói, không có tài sản để làm những gì bạn muốn. Sau rất nhiều không quan trọng và làm việc Spy ++, tôi đến khi các giải pháp sau đây:

  1. Thừa hưởng từ System.Windows.Forms.DateTimePicker, và tuyên bố các lĩnh vực tư nhân cho cờ:

    public class DPDateTimePicker : DateTimePicker 
    { 
        private bool selectionComplete = false; 
        private bool numberKeyPressed = false; 
    
  2. Xác định hằng số và cấu trúc cho 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; 
        }  
    

    Cũng cần bao gồm tuyên bố sử dụng cho System.Runtime.InteropServices để sử dụng API Win.

  3. Ghi đè OnKeyDown và đặt hoặc xóa cờ dựa trên nếu phím được nhấn là số (và xóa cờ thứ hai bên dưới).

    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 và bẫy thông điệp WM_REFLECT+WM_NOTIFY, trích xuất các NMHDR từ lParam, sau đó thiết lập cờ khác nếu mã là -759 (sự kiện này được kích hoạt sau khi một trong những lĩnh vực là hoàn toàn đầy với bàn phím và một ngày được chọn).

    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 và nếu cả hai lá cờ được thiết lập và phím bấm là một con số, bằng tay gọi base.WndProc với một WM_KEYDOWN theo sau là một WM_KEYUP với Keys.Right, sau đó xóa cờ của bạn. Bạn có thể đặt lParam của các thư này thành 0 và đừng lo lắng về điều đó và HWnd là tất nhiên 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; 
        } 
    } 
    

Xin lỗi cho việc thiếu các dòng trống trong các mã, nhưng nó sẽ không hiển thị đúng với các dòng trống, vì vậy tôi đã đưa họ ra ngoài. Tin tôi đi, đây là phiên bản dễ đọc hơn.

1

Nó sẽ làm việc trên winforms DateTimePicker

trên sự kiện thay đổi giá trị dán mã dưới đây

sendkeys.send("."); 
Các vấn đề liên quan