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
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ã.
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:
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;
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.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); }
Override
WndProc
và bẫy thông điệpWM_REFLECT+WM_NOTIFY
, trích xuất cácNMHDR
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); }
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ọibase.WndProc
với mộtWM_KEYDOWN
theo sau là mộtWM_KEYUP
vớiKeys.Right
, sau đó xóa cờ của bạn. Bạn có thể đặtlParam
của các thư này thành 0 và đừng lo lắng về điều đó vàHWnd
là tất nhiênthis.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.
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(".");