的DateTimePicker自动移动到下一个日期部分 [英] DateTimePicker automatically move to next datepart

查看:124
本文介绍了的DateTimePicker自动移动到下一个日期部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,使用的DateTimePicker的时候,你进入一个月后你要么击中右箭头或​​/它移动到一天。是否有一个属性,我可以设置还是有办法知道这个月完成,并移动到白天和移动到一年后,用户与天做了什么?这是写在旧的FoxPro /帆船天应用程序相同的行为。

Currently, when using the datetimepicker, after you enter the month you have to either hit the right arrow or the "/" for it to move to the day. Is there a property that I can set or a way to know that the month is done and move to the day and move to the year after the user is done with the day? This is the same behavior with applications written in the old FoxPro/Clipper days.

推荐答案

由于@Wael Dalloul说,没有物业做你想要什么。很多摆弄和​​Spy ++的工作后,我来到了以下解决方案:

As @Wael Dalloul says, there is no property to do what you want. After a lot of fiddling and Spy++ work, I came upon the following solution:

  1. System.Windows.Forms.DateTimePicker 继承,并宣布私人领域的标志:

  1. Inheriting from System.Windows.Forms.DateTimePicker, and declaring private fields for flags:

public class DPDateTimePicker : DateTimePicker
{
    private bool selectionComplete = false;
    private bool numberKeyPressed = false;

  • 定义的常量和结构为Win API:

  • Defining constants and structs for 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;
        }    
    

    这也是必要的,包括一个使用语句了System.Runtime.InteropServices 为了用Win API。

    It's also necessary to include a using statement for System.Runtime.InteropServices in order to use Win API.

    覆盖的onkeydown ,并设置或清除的基础上,如果关键pressed是数字的标志(并清除下面的第二个标志)。

    Override OnKeyDown and set or clear a flag based on if the key pressed was a number (and clear the second flag below).

    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);
    }
    

  • 覆盖的WndProc 和陷阱 WM_REFLECT + WM_NOTIFY 消息,提取 NMHDR 的lParam ,然后设置另外一个标志,如果code为-759(此事件被触发后的一个字段完全填满在用键盘和一个日期被选中)。

  • Override WndProc and trap the WM_REFLECT+WM_NOTIFY message, extract the NMHDR from lParam, then set another flag if the code is -759 (this event is triggered after one of the fields is completely filled in with the keyboard and a date is selected).

    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);
    }
    

  • 覆盖的onkeyup 如果两个标志设置和关键pressed是一个数字,手动调用 base.WndProc WM_KEYDOWN 后跟一个 WM_KEYUP Keys.Right ,然后清除标志。您可以设置的lParam 这些消息为0,不用担心,和 HWND 当然是 this.Handle

  • Override OnKeyUp and if both flags are set and the key pressed was a number, manually call base.WndProc with a WM_KEYDOWN followed by a WM_KEYUP with Keys.Right, then clear your flags. You can set the lParam of these messages to 0 and not worry about it, and HWnd is of course 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;
        }
    }
    

  • 道歉缺乏在code空白行,但它不会显示正确的空白行,所以我带他们出去。相信我,这是更具可读性的版本。

    这篇关于的DateTimePicker自动移动到下一个日期部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆