How does one implement pull-to-refresh with a LongListSelector in Windows Phone 8?

孤者浪人 提交于 2019-12-03 09:04:36

You do not.

Pull-to-refresh is not a standard Windows Phone interaction, and you therefore should not implement it.

No native/first-party Windows Phone application use this functionality, and almost no third-party application does either. There is a reason for that.

To refresh the content of a page (or in your case, a LongListSelector), you should use a refresh ApplicationBacIconButton, just like in the Mail app. That's the standard and preferred way to manage refreshes.

Windows Phone is not Android, nor is it iOS. Keep that in mind when designing an application for it.

It is not a zoo, there are rules.

Actually, I just discovered a project uploaded to the Windows Phone Dev Center on November 30, 2012 that implements "infinite scrolling" using Twitter Search and Windows Phone 8 LongListSelector.

Download this project at: http://code.msdn.microsoft.com/wpapps/TwitterSearch-Windows-b7fc4e5e

If you really must do this (see answer by Miguel Rochefort) then details can be found at http://blogs.msdn.com/b/jasongin/archive/2011/04/13/pull-down-to-refresh-a-wp7-listbox-or-scrollviewer.aspx

Basically, the ScrollViewer has hidden/undocumented states that allow for detecting "compression" at the top or bottom of the list and you can use this to trigger the loading.

This is not completely trivial, but one way of doing it is to use GestureService

        this.gestureListener = GestureService.GetGestureListener(containerPage);
        this.gestureListener.DragStarted += gestureListener_DragStarted;
        this.gestureListener.DragCompleted += gestureListener_DragCompleted;
        this.gestureListener.DragDelta += gestureListener_DragDelta;

However, it has some bugs. For example, DragCompleted is not always raised, so you need to double-check for that using ManipulationCompleted event, which seems to be more reliable.

        containerPage.ManipulationStarted += delegate { this.manipulationInProgress = true; };
        containerPage.ManipulationCompleted += delegate
        { 
            this.manipulationInProgress = false;
            PerformDragComplete(); 
        };

Another issue is that DragDelta occasionally reports bad coordinates. So you would need a fix like this:

    Point refPosition = e.GetPosition(null);
    if (refPosition.X == 0 && refPosition.Y == 0)
    {
        Tracer.WriteLine("Skipping buggy event");
        return;
    }

Finally, you can find if list is all the way at the top:

public double VerticalOffset
{
    get
    {
        ViewportControl viewportControl = this.FindChildByName("ViewportControl") as ViewportControl;
        if (viewportControl != null)
        {
            Tracer.WriteLine("ViewPort.Bounds.Top=" + viewportControl.Bounds.Top +  " ViewPort.Top=" + viewportControl.Viewport.Top.ToString() + " State=" + this.ManipulationState);
            return viewportControl.Bounds.Top - viewportControl.Viewport.Top;
        }
        return double.NaN;
    }
}

You can check out the samples in https://github.com/Kinnara/WPToolkit it has an excellent implementation something called a ListView extension of the longllistselector control, that will really help you out.

and remember with longlistselector always try to load 20 items atleast. =)

Patrick Sachet

As the WP8 LLS doesn't use a scrollviewer, I guess you will have to inspect the UI tree to get a hold on the viewport control and see what you can do with ViewportControl.Viewport property ...

Oh ... the twitter application is now using the pull to refresh interaction. I like the UI guidelines of the WP platform but rules, once mastered, are made to be broken ;)

This post here can give you hints on how to get the viewport control and retreive the scrolling offset. this scrolling offset must be of a particular value when the list is bouncing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!