6

現在、datetimepickerを使用する場合、月を入力した後、右矢印または「/」を押して日に移動する必要があります。設定できるプロパティや、月が終わったことを知り、その日に移動して、ユーザーがその日を終えた翌年に移動する方法はありますか?これは、FoxPro/Clipperの昔のアプリケーションで作成されたものと同じ動作です。

4

3 に答える 3

11

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

    また、System.Runtime.InteropServicesWin API を使用するには、using ステートメントを含める必要があります。

  3. OnKeyDown押されたキーが数字であるかどうかに基づいてフラグをオーバーライドし、設定またはクリアします (そして、以下の 2 番目のフラグをクリアします)。

    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してトラップし、 fromを抽出し、コードが -759 の場合は別のフラグを設定します (このイベントは、フィールドの 1 つがキーボードで完全に入力され、日付が選択された後にトリガーされます)。WM_REFLECT+WM_NOTIFYNMHDRlParam

    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.WndProcで a にWM_KEYDOWN続けてWM_KEYUPwithを呼び出してKeys.Rightから、フラグをクリアします。これらのメッセージの を 0 に設定してlParamも問題ありません。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;
        }
    }
    

コードに空白行がないことをお詫びしますが、空白行があると正しく表示されないため、それらを削除しました。私を信じてください、これはより読みやすいバージョンです。

于 2010-05-20T08:58:21.253 に答える
3

winformsのdatetimepickerで動作します

値変更イベントで、以下のコードを貼り付けます

sendkeys.send(".");
于 2016-04-12T05:11:53.187 に答える
0

希望どおりに機能させるためのプロパティはありません。keypressイベントを処理し、コードで実行する必要があると思います。

于 2010-03-08T08:30:03.397 に答える