概要
このTipsは、WPFの通常の使い方からは逸脱しているので、参考になるかは微妙です。
ただ、私と同じ状況に陥って悩んでいる方も居るかもしれないので、備忘録を兼ねて残します。
ScrollViewerは、ListViewのような(仮想的に)大きな子要素を表示するためのコントロールで、画面内に収まりきらない大きな領域をスクロールバーを使って、表示するUIを実現します。
スクロールしなければユーザーの目に入らないため一部の人からは、一覧性を損なう存在として嫌われていますが、とても便利なUIであることは間違いありません。
しかしながらWPFのScrollViewerは、汎用的に利用するには少々厄介な実装になっています。
Stack Overflowに何件か投稿されてる所をみると罠に嵌まる人も(私も含めて)居るようです。
問題点
画面いっぱいに、ScrollViewerを置き、その下へボタンを置いてください。
マウスイベントは、ScrollViewerに拾われボタンは反応しません。
WPFに慣れた技術者なら背景色を{x:Null}にすれば、イベントが透過する筈だと思うでしょう。
しかしながら努力は徒労に終わります。
筆者は、Templateまで潜って、どのコンポーネントがイベントをブロックしているのか調べましたが、こちらも上手く行きませんでした。
ちなみに、ScrollViewerのIsHitTestVisibleをfalseへ設定するとイベントは透過し下層のボタンは操作できます。
しかし、IsHitTestVisibleを設定してしまうとScrollViewer配下のコンテンツに含まれるコントロールも操作不能になってしまうという問題が残ります。
ScrollViewerは、カスタムヒットテストを持っている
Stack Overflowにヒットする質問と回答を丹念に調べていくとScrollViewerは、カスタムヒットテストを持っているので、オーバーライドすれば良いという回答を見つけることができました。
ScrollViewerを基底クラスにして派生クラスを作成して、下記のように、HitTestCoreメソッドをオーバーライドします。
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters)
{
return null;
}
完全に殺してしまって副作用がないのか心配ですが、今のところ問題は無いようです。