11
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

WPFでネストしたScrollVIewerの親ScrollViewerがスクロールできなくなる現象を何とかする

Posted at

WPFのScrollViewerはネストするとビジュアルツリー上で末端の方にあるScrollViewerがマウススクロールイベントを握りつぶしてしまい、上にあるScrollViewerがスクロールできなくなる糞仕様がある。これを末端ScrollViewerのスクロールを無効化し、上のScrollViewerがスクロール出来るようにする。

糞の原因

ScrollViewerがMouseWheelイベントをhandle = trueにしており、ここでスクロールイベントが握りつぶされている。そのため、MouseWheelイベントがScrollViewerより上へバブルしてくれない。

対策

ScrollViewerのPreviewMouseWheelイベントを購読し、握りつぶすこれに代わってMouseWheelを親要素で投げてやる。なお、当然"親"要素で投げてやる必要がある。ScrollViewerで投げると握り潰される。Behavior<ScrollViewer>として書くといい感じ。

public class WheelScrollKillBehavior : Behavior<ScrollViewer>
{
    protected override void OnAttached()
    {
      base.OnAttached();
      AssociatedObject.PreviewMouseWheel += AssociatedObject_PreviewMouseWheel;
    }
    protected override void OnDetaching()
    {
      base.OnDetaching();
      AssociatedObject.PreviewMouseWheel -= AssociatedObject_PreviewMouseWheel;
    }
    void AssociatedObject_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
      e.Handled = true;
      var newEventArgs = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
      {
        RoutedEvent = UIElement.MouseWheelEvent
      };
      ((UIElement)AssociatedObject.Parent).RaiseEvent(newEventArgs);
    }
}
11
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?