如何禁用GridView中的ScrollViewer的滚动

这篇文章所讨论的问题似乎有些基础,因为ScrollViewer控件有Horizontal/VerticalScrollMode属性可以用来控制滚动条的行为,如设定成ScrollMode.Disabled的期望结果就是能够禁用滚动操作。

一开始我们也是这样认为的,直到我们发现,在GridView中,如果当前使用的是触控,则通过此方法能够得到期望的结果,但是如果当前是在鼠标模式,那在设置成ScrollMode.Disabled之后,仍旧能够通过鼠标滚轮来进行ScrollViewer的滚动。

在Windows Store App中,无论是使用触屏还是传统的鼠标键盘,我们总是试图能够提供相对一致的用户体验,但是这里似乎在控件行为上两种输入方式产生了差异。

最初我们尝试通过捕获控件的PointerWheelChanged事件,但是由于这是属于RoutedEvent,所以即使我们在某一个层级UIElement的PointerWheelChanged设定了handled=true,也无法阻止visual tree中下层控件捕捉到滚动操作并响应。

经过多次尝试,我们最终得出了以下的解决方案,即当我们想要冻结滚动的时候,先获取到SV控件,然后获取到其偏移值,然后再绑定这个控件的ViewChanged事件,在每次事件触发时对其执行强制ScrollTo指令,测试可用。

 ScrollViewer sv = GetVisualChild<ScrollViewer>(itemGridView);
 var frozenOffset = sv.HorizontalOffset;
 sv.ViewChanged += (ss,ee) => {
     sv.ScrollToHorizontalOffset(frozenOffset);
 };
  

希望这个这个小贴士能够解决开发中碰到的实际问题。