本文介绍了在ListView的水平滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在捕捉页面上的 PointerMoved 事件与横向菜单来使用。因此用户可以刷卡左/右的页面将相应的动画。

I'm currently capturing the PointerMoved event on the page to use with a horizontal menu. So the user can swipe left/right and the page will animate accordingly.

这工作当用户触摸静态元素(TextBlock的等),但如果他们接触一个ListView它抓住了触摸事件。

This works when the user touches a static element (TextBlock etc.) but if they touch a ListView it captures the touch events.

我如何能实现在ListView因此当用户垂直滚动它工作正常,但是当用户水平滚动它传递的事件,以我的code?

How can I implement the ListView so when the user scrolls vertically it works as normal, but when the user scrolls horizontally it passes the events to my code?

推荐答案

这是可能的,但你需要一个小窍门。作为一个REFFERENCE我把这里的。

It is possible, but you will need a small trick. As a refference I put here Rob Caplan's article.

让我们开始:


  1. 第一 - 在这里是你的事件? - 答案很简单 - 当你有的ScrollViewer 启用,所有事件都是由它拦截和handeled。您的ListView 将只得到 PointerEntered 事件,只是后 PointerExited ,所有进一步proccesing由的ScrollViewer handeled。这就是问题所在。但是,正如我已经说过有做你想要的东西的方法。

  1. First - where are your events? - answer is simple - while you have ScrollViewer enabled, all events are intercepted by it and handeled. You ListView will get only PointerEntered event and just after it PointerExited, all further proccesing is handeled by ScrollViewer. That is the problem. But as I've said there is a method to do what you want.

为此,让我们假设您已经定义了的ListView 仅VerticalScroll:

For this purpose lets assume that you have defined your ListView only with VerticalScroll:

<ListView Name="myList" ScrollViewer.HorizontalScrollMode="Disabled">

当然,这是可能的两个方向做,但它是一个简单的例子。

Of course it is possible to do for both directions, but it's a simple example.

现在让我们来看看构造一个

Now let's have a look at constructor of a Page:

PointerPoint firstPoint = null;
ScrollViewer listScrollviewer = null;

public MainPage()
{
  this.InitializeComponent();
  myList.ItemsSource = yourItemSource;
  myList.PointerEntered += myList_PointerEntered;
  myList.PointerMoved += myList_PointerMoved;
}

没有什么奇怪的在这里 - 我只是订阅事件,并宣布两个变量 firstPoint listScrollviewer ,这是我'以后会需要。

Nothing weird here - I just subscribe to events, and declare two variables firstPoint and listScrollviewer, which I'll need later.

我们将也需要得到我们的的ScrollViewer 我们的的ListView - 下面的方法将做工作:

We will need also to get our ScrollViewer of our ListView - the following method will do the job:

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;
}


  • 现在 - 使我们的活动,我们将需要禁用的ScrollViewer

    private ScrollViewer DisableScrolling(DependencyObject depObj)
    {
        ScrollViewer foundOne = GetScrollViewer(depObj);
        if (foundOne != null) foundOne.VerticalScrollMode = ScrollMode.Disabled;
        return foundOne;
    }
    


  • 我们将在 PointerEntered 这是触发的事件禁用的ScrollViewer 。在这一步中,我们还会记得pssed的$ P $ PointerPoint - 因为我们有禁用的ScrollViewer ,我们将不得不手动滚动它 - 这就是我们需要这个 PointerPoint

  • We will disable the ScrollViewer upon PointerEntered event which is fired. In this step we will also remember the pressed PointerPoint - as we have disable Scrollviewer, we will have to scroll it manually - that is what we need this PointerPoint for.

    private void myList_PointerEntered(object sender, PointerRoutedEventArgs e)
    {
        firstPoint = e.GetCurrentPoint(myList);
        if (listScrollviewer == null) listScrollviewer = DisableScrolling(myList);
    }
    


  • 最后,我们的 PointerMoved 事件,因为我们已经禁用了现在西港岛线被解雇的ScrollViewer - 移动的ScrollViewer +其他code,你需要把有:

  • Finally our PointerMoved event, which now wil be fired as we had disabled ScrollViewer - moving ScrollViewer + other code you need to put there:

    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
    }
    


  • 几句话:


    • 这种方法仍然需要很多调整,但hopefuly会告诉你如何实现自己的目标,

    • 您可能也需要一些小的水平运动距离垂直们分开,

    • 如果你的的ListView 或其它控制具有水平滚动,那么你还需要禁用和处理它,

    • 此方法不会工作,或许这么顺利就像原始的的ScrollViewer

    • this method still needs much tuning, but hopefuly will show you how to achieve your goal,
    • you may need also to separate some small horizontal movements from vertical ones,
    • if your ListView or other Control has horizontal scroll, then you will also need to disable and handle it,
    • this method won't probably work so smooth like original ScrollViewer.

    我也把一个简单的工作示例。

    I've also put a simple working example here at OneDrive.

    这篇关于在ListView的水平滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-16 04:23