locked
カーソルキーによるScrollViewerのスクロール抑制について RRS feed

  • 質問

  • 損と申します。
    Silverlight4+VS2010+Blend4で開発しております。

    ScrollViewerの中にTextBoxを配置して、TextBoxにフォーカスがある状態で←↑→↓を押すと、ScrollViewerがスクロールします。
    これはSilverlight標準の動作かと思いますが、この動きを抑制する方法はあるでしょうか。

    TextBoxをカスタムコントロールにして、TextBoxのOnKeyDownやKeyDownでイベントをハンドリングすることは可能ですが、もっと単純に実現できる方法があればご教示頂けますでしょうか。

    2011年8月2日 4:18

回答

  • この場合、ScrollViewer以下の全てのコントロールに対してこの処理を追加する必要があり、現実的で無いと考えております。

    ScrollViewer内の子コントロールをScrollViewer直下ではなく、、一旦Grid内に配置するようにすれば、GridのKeyDownイベントでのみ処理すれば良いようになります。KeyDownをそこから先にバブルさせないようにすることには変わりはないのですが、ScrollViewerそのものには手を入れていないので、ScrollViewerで発生したKeyDownイベントは問題なくバブルしていきます。元々、ScrollViewer内の子コントロールで発生した矢印キーのKeyDownイベントがScrollViewerに伝わらなければ良いので、これで良いように思いますが、いかがでしょうか?

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク 2011年8月5日 1:16
    2011年8月3日 5:37
    モデレータ

すべての返信

  • 実現されたいことをきちんと理解できていないかもしれませんが、TextBoxをカスタムコントロールにしなくてもKeyDownやKeyUpは補足して無視することは可能です。

     

    <TextBox Name="textBox1" Width="120" AcceptsReturn="True" KeyDown="textBox1_KeyDown" />
    
    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
     if (e.Key == Key.Up || e.Key == Key.Down)
      e.Handled = true;
    }
    

     

    #KeyDownは、一番上の行、もしくは一番下の行で、これ以上スクロールできない場合にのみ発生するようです。このタイミングで上記のようにKeyDownを読み捨てれば、ScrollViewerがスクロールすることはありませんでした。

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    2011年8月2日 14:58
    モデレータ
  • ご返信、有難うございます。

    言葉足らずで申し訳ございません。確かにカスタムコントロールにしなくてもKeyDownイベントを読み捨てることは可能ですが、この場合、ScrollViewer以下の全てのコントロールに対してこの処理を追加する必要があり、現実的で無いと考えております。
    このため、例えばScrollViewerのプロパティやイベントに、矢印キーによるスクロールの抑制手段があったり、または他の方法があるのではないか、ということで質問させて頂きました。

    また、KeyDownイベントをScrollViewer以下でハンドリングしてしまうと、本来上位に通知されるはずだった矢印キーのKeyDownイベントを全て握りつぶしてしまうため、動作に不安が残ります。
    何かスマートな方法があると良いのですが・・・。

    2011年8月3日 2:56
  • この場合、ScrollViewer以下の全てのコントロールに対してこの処理を追加する必要があり、現実的で無いと考えております。

    ScrollViewer内の子コントロールをScrollViewer直下ではなく、、一旦Grid内に配置するようにすれば、GridのKeyDownイベントでのみ処理すれば良いようになります。KeyDownをそこから先にバブルさせないようにすることには変わりはないのですが、ScrollViewerそのものには手を入れていないので、ScrollViewerで発生したKeyDownイベントは問題なくバブルしていきます。元々、ScrollViewer内の子コントロールで発生した矢印キーのKeyDownイベントがScrollViewerに伝わらなければ良いので、これで良いように思いますが、いかがでしょうか?

     


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
    • 回答としてマーク 2011年8月5日 1:16
    2011年8月3日 5:37
    モデレータ
  • ScrollViewer内の子コントロールをScrollViewer直下ではなく、、一旦Grid内に配置するようにすれば、GridのKeyDownイベントでのみ処理すれば良いようになります。

    確かに、直下のPanelのKeyDownをハンドルするだけでいいですね。全てのコントロールのKeyDownを書くつもりでおりました。助かりました。

    ただ、やはりScrollViewerより上にKeyDownイベントが通知されないのは懸念が残ります。また、上位側でもAddHandlerを使ってKeyDownを拾うことはできると思いますが、なんでもかんでも拾ってしまうので最終手段にしたいと思っております。なるべく影響範囲をScrollViewer周辺のみにしたいと考えているので、もう少し考えてみたいと思います。

    2011年8月3日 8:44