[Windows 8(.1)] How to load items incrementally when using a FlipView ?

February 3rd, 2014 | Posted by Tom in .NET | Article | Windows 8 | Read: 1,875

The FlipView control is very useful to display a set of data and display them with a DataTemplate. But imagine that you need to load 1000000 of customers: you’ll need to load all of them and set the ItemsSource property so the data can be shown. But loaded 1000000 objects in memory is not a very good idea in terms of performance so, let’s take a look at how we could prevent that!

First, you need to add an event handler to the SelectionChanged method of the FlipView:

private async void OnFlipViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    await this._viewModel.LoadMoreItemsAsync(this.flipView.SelectedIndex);
}

As you can see, we just call a method of our ViewModel, passing in parameters the current index of the FlipView. So all the magic is in the LoadMoreItemsAsync method of our ViewModel:

private int _offset;

private ObservableCollection<PostViewModel> _posts;
public ObservableCollection<PostViewModel> Posts
{
    get { return this._posts; }
    set { this.SetProperty(ref this._posts, value); }
}

public async Task LoadMoreItemsAsync(int currentIndex)
{
    if (currentIndex > 0)
    {
        var globalIndex = currentIndex % 10;
        var itemIndex = currentIndex - globalIndex;

        if (itemIndex <= 5)
        {
            this._offset = this._offset - 1;

            var rangedPost = await this.GetPostsAsync(this._offset);
            var posts = rangedPost as IList<Post> ?? rangedPost.ToList();
            if (posts.Any())
            {
                for (int i = 0; i <= posts.Count - 1; i++)
                {
                    var post = posts.ElementAt(i);

                    this.Posts.Insert(i, this.CreatePostViewModel(post));
                }
            }
        }
        else if (currentIndex >= this.Posts.Count - 5)
        {
            this._offset = this._offset + 1;

            var rangedPost = await this.GetPostsAsync(this._offset);
            var posts = rangedPost as IList<Post> ?? rangedPost.ToList();
            if (posts.Any())
            {
                foreach (var post in posts)
                {
                    var postViewModel = this.CreatePostViewModel(post);
                    if (postViewModel != null)
                    {
                        this.Posts.Add(postViewModel);
                    }
                }
            }
        }
    }
}

So how this method works exactly ? Well, basically, we load our “pages” by set of 10 items so we just check if we need to add the items at the end of the property bound to the ItemsSource or if we need to insert the items (starting from the index 0). Also, don’t forget to use an ObservableCollection (instead of a simple List) for the property databound otherwise, your GUI won’t be refreshed.

Of course, to make this happened, you need to have a service/backend that accepts to send data/items according to a page index.

Maybe there are other solutions (I’ve haven’t checked yet if ISupportIncrementalLoading can be used, in Windows 8.1, with the FlipView control but as far as I know, it didn’t work on Windows 8) but this one is pretty simple isn’t it ? :)

 

Happy coding!

You can follow any responses to this entry through the RSS 2.0 You can leave a response, or trackback.

One Response

Add Comment Register



Leave a Reply