ScrollViewer 和处理子元素上的操作事件 [英] ScrollViewer and handling manipulation events on child elements

查看:27
本文介绍了ScrollViewer 和处理子元素上的操作事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 C#/XAML 创建了一个 Windows 8 商店应用程序.我的界面包含一个可滚动列表,该列表使用 ScrollViewer 呈现.我希望能够处理列表中元素上的操作事件,但是,在列表元素上将 ManipulationMode 设置为 None 以外的任何内容会导致我的列表不再滚动.

I have created a Windows 8 Store App using C# / XAML. My interface includes a scrollable list, which is rendered using an ScrollViewer. I would like to be able to handle manipulation events on the elements within the list, however, setting ManipulationMode to anything other than None on the list element causes my list to no longer scroll.

这是用户界面的简化版本:

Here is a simplified version of the UI:

<ScrollViewer>
  <Border/> <!-- these contain child content -->
  <Border/>
  <Border/>
  <!-- Set ManipulationMode on an element in order to receive manipulation events -->
  <!-- This causes the scroll viewer to stop working! -->
  <Border ManipulationMode="All"
          ManipulationDelta="..."/>
  <Border/>
  <Border/>
</ScrollViewer>

我了解 WinRT ScrollViewer 出于性能原因使用 System 的特殊 ManipulationMode,但我想要一个垂直滚动列表,包含响应水平操作/手势的元素.谁能想到一个创造性的解决方法来使这成为可能?

I understand that the WinRT ScrollViewer uses a special ManipulationMode of System for performance reasons, but I would like to have a vertically scrolling list, containing elements that respond to horizontal manipulation / gestures. Can anyone think of a creative workaround that would make this possible?

推荐答案

我所做的是在 ScrollViewer 顶部放置一个透明矩形并在那里处理操作.当我发现操作应该滚动 ScrollViewer 时 - 我使用 ScrollToHorizo​​ntal/VerticalOffset() 方法滚动 ScrollViewer.在 ManipulationStarted 上,我还使用 VisualTreeHelper.FindElementsInHostCoordinates 来检查我也可以操作的项目,然后我可以根据各种条件决定是否操作该项目.不过,这是相当多的自定义代码.当用户尝试拖动超过最小/最大偏移量以模仿 ScrollViewer 默认行为、处理鼠标滚轮等时,您还需要更新 ScrollViewer 中 ScrollContentPresenter 的 RenderTransform.当然没有您无法处理的事情.不幸的是,我找不到更好的方法,如果有人找到,我很感兴趣.

What I have done was I put a transparent rectangle on top of the ScrollViewer and handle manipulations there. When I find the manipulation should scroll the ScrollViewer - I scroll the ScrollViewer using the ScrollToHorizontal/VerticalOffset() methods. On ManipulationStarted I also use VisualTreeHelper.FindElementsInHostCoordinates to check which item I could manipulate too and then I can decide whether to manipulate that item or not depending on various conditions. It's quite a bit of custom code though. You would also need to update the RenderTransform of the ScrollContentPresenter in the ScrollViewer when the user tries to drag farther than minimum/maximum offset to immitate the ScrollViewer default behavior, handle mouse scrollwheel etc. Nothing YOU could not handle of course. I could not find a better way unfortunately and I am interested if someone finds one.

编辑*我在尝试回答时想到的另一种解决方案 另一个类似的问题是使用另一个 ScrollViewer 作为子项并使用其 ViewChanged 事件而不是操作事件.

EDIT* Another solution I thought of when trying to answer another similar question was to use another ScrollViewer as a child item and use its ViewChanged events instead of manipulation events.

编辑 2*

此外,在 Windows 8.1 中,您可以获得 ManipulationModes.System,它与其他模式结合应该允许您处理 ScrollViewer 内部的操作.然后你可以调用 CancelDirectManipulations() 一旦您希望其父元素 ScrollViewers 停止处理平移和缩放操作.

Also with Windows 8.1 you get ManipulationModes.System which combined with other modes should allow you to handle manipulations inside of a ScrollViewer. Then you can call CancelDirectManipulations() on the manipulated element once you want its parent ScrollViewers to stop processing manipulations for pan&zoom.

这篇关于ScrollViewer 和处理子元素上的操作事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆