Over a million developers have joined DZone.

Page-based browsing in a list on Windows Phone

· Mobile Zone

There are several ways content can be browsed inside a list on Windows Phone. Most of the current applications (like Facebook) are using the "Load More" method - by modifying the default ItemPresenter it is possible to add an extra Button control at the end that will trigger the list update (for the list that is currently bound). This is a pretty decent method to split a large collection in smaller chunks and then access it that way. However, the situation becomes a bit more complicated when the items are already loaded and all that needs to be done is navigate through the existing set.

NOTE: In this article I am showing the navigation concept. It will later be implemented as a custom control.

I decided to try a different approach and apply pseudo-paged navigation in a list. I am calling it pseudo-page because I am not using any actual pages but rather use a quick binding trick to go through a list. For a sample, let's suppose there is a ListBox that is bound to some collection located in a given generic ViewModel:

<ListBox x:Name="MainList">

</ListBox>

I also added two buttons to the main page (where the list is located) - one button to navigate back and the other one to navigate forward. Ultimately, there is a single number of items that should be displayed in a list at once. So here is what I came up with.

Notice that there is no initial binding present here - the actual linking will happen once the entire collection is loaded.

There is a ViewModel present in my sample application that contains some generalized data. First of all, I have the total number of pages (TotalPages) and the current page (CurrentPage). These numbers are calculated manually, depending on the collection count.

For example, here is how I calculate the total number of pages:

ViewModel.TotalPages = ((int)Math.Ceiling((double)total/(double)10));

Here, total is the number of items in the global collection. 10 is the number of items per page (of course, it can be modified).

When I navigate across pages, I need to keep track of the current starting point (since there is one collection) - I am using GetRange to go through subsets of the same collection and display chunks instead of loading the whole set.

First of all, there is a current variable that will keep count of the position in the collection. It is a regular int and it is initialized as zero (0). You can put it anywhere in the main page (where the navigation is happening).

Now let's look at how I am performing the navigation forward.

if (ViewModel.CurrentPage < ViewModel.TotalPages)
{
    current += 10;
    if (ViewModel.CurrentPage == ViewModel.TotalPages - 1)
    {
        MainList.ItemsSource = ViewModel.MyCollection.GetRange(current,
            Convert.ToInt32(ViewModel.TotalItemsInCollection) 
            - (ViewModel.CurrentPage * 10));
    }
    else
    {
        MainList.ItemsSource = ViewModel.Games.GetRange(current, 10);
    }
    ViewModel.CurrentPage++;
}

First thing I do is make sure that the current page has a value less than the total number of pages. That way, if the user is on the last page, there is no way he will go further with the navigation and cause an exception. I am incrementing current by 10, because I am displaying 10 items per page.

Remember, that since the collection indexes start with 0, the item with the index 10 will actually be the 11th item and will be the start of a new page.

If the page is the one before the last one, I am making sure that I am pulling the exact number of items remaining in the collection, calculated by the following formula:

items to pull = total items in the collection - (page before last * items per page)

The range is then pulled from the collection starting with current (the starting point). In case the page is not the one before the last one, then I am simply pulling the next 10 items. Once items are obtained (or to be exact - the references to those items), I am incrementing the current page.

Going backwards is done fairly easy (by doing the opposite process):

if (ViewModel.CurrentPage != 1)
{
    current -= 10;
    MainList.ItemsSource = ViewModel.MyCollection.GetRange(current, 10);
    ViewModel.CurrentPage--;
}

It's much simpler here - I am only decrementing the cursor (selection point in the collection) and decrementing the current page number. That's pretty much it - now I can have a back/forward micro-system for paged navigation in a list.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}