Derzeit bei Verwendung des Datentimepickers danachSie geben den Monat ein, den Sie entweder mit dem Rechtspfeil oder dem "/" drücken müssen, um zum Tag zu gelangen. Gibt es eine Eigenschaft, die ich einstellen kann, oder eine Möglichkeit, zu wissen, dass der Monat fertig ist, und zu dem Tag und dem Jahr wechseln, nachdem der Benutzer den Tag beendet hat? Dies ist dasselbe Verhalten bei Anwendungen, die in den alten FoxPro / Clipper-Tagen geschrieben wurden.
Antworten:
7 für die Antwort № 1Wie @Wael Dalloul sagt, gibt es keine Eigenschaft, um das zu tun, was Sie wollen. Nach vielem Geigen und Spy ++ - Arbeit bin ich auf folgende Lösung gestoßen:
Erben von
System.Windows.Forms.DateTimePicker
und private Felder für Flags deklarieren:public class DPDateTimePicker : DateTimePicker { private bool selectionComplete = false; private bool numberKeyPressed = false;
Konstanten und Strukturen für Win API definieren:
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; }
Es ist auch notwendig, eine using-Anweisung für einzufügen
System.Runtime.InteropServices
um Win API zu verwenden.Überschreiben
OnKeyDown
und ein Flag setzen oder löschen, je nachdem, ob die gedrückte Taste eine Zahl war (und das zweite Flag unten löschen).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); }
Überschreiben
WndProc
und falle dieWM_REFLECT+WM_NOTIFY
Nachricht extrahierenNMHDR
vonlParam
Setzen Sie dann ein anderes Flag, wenn der Code -759 lautet (dieses Ereignis wird ausgelöst, nachdem eines der Felder vollständig mit der Tastatur ausgefüllt wurde und ein Datum ausgewählt ist).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); }
Überschreiben
OnKeyUp
und wenn beide Flags gesetzt sind und die Taste eine Nummer ist, rufen Sie manuell anbase.WndProc
mit einemWM_KEYDOWN
gefolgt von einemWM_KEYUP
mitKeys.Right
dann löschen Sie Ihre Flaggen. Sie können das einstellenlParam
von diesen Nachrichten auf 0 und keine Sorge, undHWnd
ist natürlichthis.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; } }
Entschuldigung für das Fehlen von Leerzeilen im Code, aber es würde nicht direkt mit den Leerzeilen angezeigt, also habe ich sie herausgenommen. Vertrauen Sie mir, dies ist die besser lesbare Version.
2 für die Antwort № 2
Es wird auf Winforms Datentimepicker funktionieren
Bei einem Wertänderungsereignis fügen Sie den folgenden Code ein
sendkeys.send(".");
0 für die Antwort № 3
Es gibt kein Eigentum Damit es so funktioniert, wie Sie es wollen, denke ich, müssen Sie das Tastendruck-Ereignis behandeln und es per Code tun.