C# 在ListView上水平滚动

C# 在ListView上水平滚动,c#,xaml,listview,windows-runtime,windows-phone-8.1,C#,Xaml,Listview,Windows Runtime,Windows Phone 8.1,我目前正在捕获页面上的PointerMoved事件,以便与水平菜单一起使用。因此,用户可以向左/向右滑动,页面将相应地设置动画 当用户触摸一个静态元素(TextBlock等)时,这会起作用,但如果他们触摸一个ListView,它会捕获触摸事件 我如何实现ListView,这样当用户垂直滚动时,它可以正常工作,但当用户水平滚动时,它会将事件传递给我的代码?这是可能的,但您需要一个小技巧。作为参考,我放在这里 让我们开始: 第一,你的活动在哪里答案很简单-当您启用了ScrollViewer时,所有事

我目前正在捕获页面上的
PointerMoved
事件,以便与水平菜单一起使用。因此,用户可以向左/向右滑动,页面将相应地设置动画

当用户触摸一个静态元素(TextBlock等)时,这会起作用,但如果他们触摸一个ListView,它会捕获触摸事件


我如何实现ListView,这样当用户垂直滚动时,它可以正常工作,但当用户水平滚动时,它会将事件传递给我的代码?

这是可能的,但您需要一个小技巧。作为参考,我放在这里

让我们开始:

  • 第一,你的活动在哪里答案很简单-当您启用了
    ScrollViewer
    时,所有事件都会被它截获并处理。您的
    ListView
    将只获得
    PointerEntered
    事件,在它退出
    pointereexit
    之后,所有进一步的过程都由
    ScrollViewer处理。这就是问题所在。但正如我所说,有一种方法可以满足你的需求

  • 为此,我们假设您仅使用VerticalScroll定义了
    ListView

    <ListView Name="myList" ScrollViewer.HorizontalScrollMode="Disabled">
    
    这里没什么奇怪的-我只是订阅了事件,并声明了两个变量
    firstPoint
    listcrollviewer
    ,我稍后需要它们

  • 我们还需要获得我们的
    列表视图的
    滚动查看器
    ——以下方法可以完成这项工作:

    public static ScrollViewer GetScrollViewer(DependencyObject depObj)
    {
        if (depObj is ScrollViewer) return depObj as ScrollViewer;
    
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            var child = VisualTreeHelper.GetChild(depObj, i);
    
            var result = GetScrollViewer(child);
            if (result != null) return result;
        }
        return null;
    }
    
  • 我们将在触发
    PointerEntered
    事件时禁用
    ScrollViewer
    。在这一步中,我们还将记住按下的
    指针点
    ——因为我们禁用了
    滚动查看器
    ,我们将不得不手动滚动它——这就是我们需要这个
    指针点
    的原因

    private void myList_PointerEntered(object sender, PointerRoutedEventArgs e)
    {
        firstPoint = e.GetCurrentPoint(myList);
        if (listScrollviewer == null) listScrollviewer = DisableScrolling(myList);
    }
    
  • 最后,我们的
    PointerMoved
    事件将被触发,因为我们禁用了
    ScrollViewer
    -移动
    ScrollViewer
    +需要放在那里的其他代码:

    private void myList_PointerMoved(object sender, PointerRoutedEventArgs e)
    {
        if (listScrollviewer != null)
        {
            PointerPoint secondPoint = e.GetCurrentPoint(myList);
            double verticalDifference = secondPoint.Position.Y - firstPoint.Position.Y;
            listScrollviewer.ChangeView(null, listScrollviewer.VerticalOffset - verticalDifference, null);
        }
        // some other code you need
    }
    

  • 几句话:

    • 这种方法仍然需要很多调整,但Hopediy将向您展示如何实现您的目标
    • 您可能还需要将一些小的水平运动与垂直运动分开
    • 如果您的
      ListView
      或其他控件具有水平滚动,则还需要禁用并处理它
    • 此方法可能不会像原始的
      ScrollViewer
      那样顺利工作
    我还举了一个简单的工作示例

    private void myList_PointerEntered(object sender, PointerRoutedEventArgs e)
    {
        firstPoint = e.GetCurrentPoint(myList);
        if (listScrollviewer == null) listScrollviewer = DisableScrolling(myList);
    }
    
    private void myList_PointerMoved(object sender, PointerRoutedEventArgs e)
    {
        if (listScrollviewer != null)
        {
            PointerPoint secondPoint = e.GetCurrentPoint(myList);
            double verticalDifference = secondPoint.Position.Y - firstPoint.Position.Y;
            listScrollviewer.ChangeView(null, listScrollviewer.VerticalOffset - verticalDifference, null);
        }
        // some other code you need
    }