【问题标题】:ScrollViewer and handling manipulation events on child elementsScrollViewer 和处理子元素上的操作事件
【发布时间】:2015-02-10 01:55:32
【问题描述】:

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

【问题讨论】:

    标签: windows-8 windows-runtime windows-store-apps winrt-xaml


    【解决方案1】:

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

    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 列表。这样做就足够了。

    【讨论】:

    • 谢谢!这正是我所需要的!
    【解决方案2】:

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

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

    编辑 2*

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

    【讨论】:

    • 哇——工作量很大。所以你基本上会自己滚动ScrollViewer?这是否意味着您还必须执行自己的惯性计算才能使其自然滚动?还是当您更改垂直偏移时它会自动执行此操作?
    • Jupiter 中的操作默认启用了内置惯性,因此您可以了解这一点。如果由于惯性而发生滚动,您只需要确保不会在列表末尾挤压 ScrollContentPresenter。操作通常非常流畅,但您可以使用类似 WinRT XAML Toolkit 中的 ScrollViewer 动画来平滑使用滚轮时的滚动。顺便说一句,我忘了提到您可能还想在点击叠加层时将焦点设置在项目上...... :)
    • @ColinE 检查我对this question 的回答以获得另一个解决方案。
    • 现在正在对 ScrollViewer 进行自定义输入处理的另一种实现...
    • 看起来可能是另一种选择(使用 AddHandler)。 msdn.microsoft.com/en-us/library/windows/apps/…我已经成功地在一个带有透明层的网格上使用了这个方法,它将它的事件设置为handeld,但是由于某些原因我不能让它与scrollviewer一起工作
    猜你喜欢
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    相关资源
    最近更新 更多