5

我使用 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使用特殊ManipulationModeSystem,但我想要一个垂直滚动列表,其中包含响应水平操作/手势的元素。谁能想到一个创造性的解决方法可以使这成为可能?

4

2 回答 2

10

可能很长时间,但没有找到任何好的解决方案。我很容易就达到了我想要的。

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

我希望我的 MovableGrid 在 X 轴上移动,并且我有想要使用 scrollviewer 滚动的 MovableGrid 列表。这足以做到这一点。

于 2015-02-09T17:55:32.767 回答
8

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

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

编辑 2*

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

于 2012-09-28T21:45:31.447 回答