Windows 8 ScrollViewer和处理子元素上的操作事件

Windows 8 ScrollViewer和处理子元素上的操作事件,windows-8,windows-runtime,windows-store-apps,winrt-xaml,Windows 8,Windows Runtime,Windows Store Apps,Winrt Xaml,我已经使用C#/XAML创建了一个Windows 8应用商店应用程序。我的界面包括一个可滚动列表,该列表使用ScrollViewer呈现。我希望能够处理列表中元素的操纵事件,但是,将列表元素上的ManipulationMode设置为除None以外的任何选项都会导致我的列表不再滚动 以下是UI的简化版本: <ScrollViewer> <Border/> <!-- these contain child content --> <Border/&g

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

以下是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
的特殊
操作模式
,但我希望有一个垂直滚动列表,其中包含响应水平操作/手势的元素。有人能想出一个创造性的解决方法来实现这一点吗?

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

编辑*我在尝试回答时想到的另一个解决方案是将另一个ScrollViewer用作子项,并使用其ViewChanged事件而不是操纵事件

编辑2*


Windows 8.1还提供了
操作模式。系统
与其他模式相结合,应允许您在
滚动查看器
中处理操作。然后,当您希望其父元素ScrollViewer停止处理平移和缩放操作时,可以调用被操纵元素。

可能需要很长时间,但没有找到任何好的解决方案。我只是很容易地实现了我想要的

public MovableGrid()
        {
            ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.System;
            AddHandler(ManipulationDeltaEvent, new ManipulationDeltaEventHandler(UIElement_OnManipulationDelta), true);
            AddHandler(ManipulationCompletedEvent, new ManipulationCompletedEventHandler(UIElement_OnManipulationCompleted), true);
        }

我希望我的移动网格在X轴上移动,我有一个移动网格列表,我想用scrollviewer滚动它。这就足够了。

哇,这是一项艰巨的工作。所以你基本上是自己负责滚动
ScrollViewer
?这是否意味着您还必须执行自己的惯性计算,以便它自然滚动?或者,当你改变垂直偏移时,它会自动做到这一点吗?木星上的操作默认启用了内置惯性,所以你可以覆盖它。如果滚动是由于惯性造成的,您只需要确保不会挤压列表末尾的ScrollContentPresenter。操作通常非常平滑,但您可能会使用ScrollViewer动画(如中的动画)在使用滚轮时平滑滚动。顺便说一句,我忘了提到,当你点击覆盖时,你可能还想处理设置项目焦点…:)@ColinE检查我对的回答以获得另一个解决方案。现在正在ScrollViewer上进行另一个自定义输入处理的实现…看起来可能还有另一个选项(使用AddHandler)。我已经成功地在一个带有透明层的网格上使用了这个方法,该层将其事件设置为handeld,但是由于某些原因,我无法让它与ScrollViewer一起工作谢谢!这正是我需要的!