none
Datetimepickerについて問題 RRS feed

  • 質問

  •  

    仕様どうり共通コントロールを作っています。

    DatetimepickerでEnterキーを押して、フォーカスは下記のように移動します。

    年==>月==>日==>次のコントロール

     

    それはできますか?

    フォーカスは「日」に在ったかどうか判断できません。

     

    誰はいい方法があれば、ぜひ教えてお願いします。

    2007年11月12日 8:30

すべての返信

  • こんなのはいかがですか?

     

    コード ブロック

    private void dateTimePicker1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (e.KeyChar == (char)Keys.Enter)
        {
            SendKeys.SendWait("{UP}");
            DateTime test = ((DateTimePicker)sender).Value.Date;
            SendKeys.SendWait("{DOWN}");
            TimeSpan span =

                test - ((DateTimePicker)sender).Value.Date;

            bool isInDay = Math.Abs(span.Days) == 1;
            bool shift =

                (Control.ModifierKeys & Keys.Shift) == Keys.Shift;

            if (!isInDay || shift)
                SendKeys.Send(shift ? "{LEFT}" : "{RIGHT}");
            else
                SendKeys.Send("{TAB}");

            e.Handled = true;
        }
    }

     

     

    ただし、ValueChanged イベントが発生するという弊害があります。
    不都合でしたら OnValueChanged をオーバーライドして握りつぶすとか(^^;

    2007年11月15日 10:24
  • こんにちは、ファクトです。

    すごいコードですね(^^;

     

    ただ、DateTimePickerは日付部分で↑キーを押すと、31日なら1日に戻ってしまう動きをするので、このコードだとちょっとマズイようです。また、1月31日だと、月を2に変えると同時に日付が28日になってしまったりするので、そこも注意しないとならなそうです。

     

    この修正路線に乗るのであれば、こんな感じでしょうか?実際に動かす時は、描画を抑止する機能とかも入れた方がよさそうですが。

    コード ブロック

    private void dateTimePicker1_KeyPress(object sender, KeyPressEventArgs e)
    {
      if (e.KeyChar == (char)Keys.Enter)
      {
        DateTimePicker control = sender as DateTimePicker;
        
        //↓キーを押して変わった値により、どのエリアにいたかを判断する
        DateTime testValue;
        DateTime originalValue = control.Value.Date;
        try
        {
          SendKeys.SendWait("{DOWN}");
          testValue = control.Value.Date;
        }
        finally
        {
          control.Value = originalValue;
        }

     

        //日だけ変わっていたら日エリアにいたという事
        bool isInDay =
          (
            testValue.Year == originalValue.Year
            && testValue.Month == originalValue.Month
            && testValue.Day != originalValue.Day
          );

     

        //Shiftキーの状態を判定
        bool shift =
          (Control.ModifierKeys & Keys.Shift) == Keys.Shift;

     

        //場所によって→・←・TABキーで移動する
        if (!isInDay || shift)
          SendKeys.Send(shift ? "{LEFT}" : "{RIGHT}");
        else
          SendKeys.Send("{TAB}");

     

        e.Handled = true;
      }
    }

     

    #この方式だと、表示フォーマットを変えて、日付が最後にこなくなったら終わりですがw

    2007年11月15日 13:53
  • ファクトさんこんにちは。


    >すごいコードですね(^^;
    お褒めいただき、ありがとうございます。って褒められてるのかな?(^^;
    いろいろあったマズイところのフォロー、ありがとうございます!きれいになってますね。

     

    年のところで Shift+Enter すれば前のコントロールに戻る場合を付け加えさせてもらいます。要件にはないですけど

     

    コード ブロック

    ・・・・
    //年が変わっていれば、年エリア
    bool isInYear = testValue.Year != originalValue.Year;
    //日だけ変わっていたら日エリアにいたという事
    bool isInDay =
      (
        !isInYear
        && testValue.Month == originalValue.Month
        && testValue.Day != originalValue.Day
      );
    ・・・・
    //場所によって→・←・TABキーで移動する
    if (isInYear && shift || isInDay && !shift)
        SendKeys.Send("{TAB}");
    else
        SendKeys.Send(shift ? "{LEFT}" : "{RIGHT}");
    ・・・・

     

     

    2007年11月16日 0:44