Telerik blogs

It is clear that a good data driven Windows Phone 7 application must have a smart approach of handling large amounts of data and keeping jagged scrolling and long lasting loading screens away from the end-users. There are a bunch of approaches which handle similar situations but recently I had a discussion with a developer using our controls which focused on implementing data paging as a way of coping with large amounts of data.

During this discussion I came up with an idea to utilize the OnDemandManual data virtualization mode of our RadDataBoundListBox to implement a mechanism which loads pages of data and allows the end user to navigate between pages by providing previous and next buttons at the end of the scrollable list.

The XAML code for this scenario is as simple as that:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.Resources>
        <DataTemplate x:Key="DataVirtualizationTemplateNextPrev">
            <StackPanel Orientation="Horizontal">
                <Button x:Name="btnPrev" Content="back" Click="btnPrev_Click"/>
                <Button x:Name="btnNext" Content="next" Click="btnNext_Click"/>
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="DataVirtualizationTemplateNext">
            <StackPanel Orientation="Horizontal">
                <Button x:Name="btnNext" Content="next" Click="btnNext_Click"/>
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="DataVirtualizationTemplatePrev">
            <StackPanel Orientation="Horizontal">
                <Button x:Name="btnPrev" Content="back" Click="btnPrev_Click"/>
            </StackPanel>
        </DataTemplate>
    </Grid.Resources>
    <telerikPrimitives:RadDataBoundListBox x:Name="listBox" DataVirtualizationMode="OnDemandManual">
        <telerikPrimitives:RadDataBoundListBox.ItemTemplate>
            <DataTemplate>
                <Border Background="ForestGreen" MinHeight="150">
                    <TextBlock Text="{Binding}"/>
                </Border>
            </DataTemplate>
        </telerikPrimitives:RadDataBoundListBox.ItemTemplate>
    </telerikPrimitives:RadDataBoundListBox>
</Grid>

 

As you can see, I have a RadDataBoundListBox control which has its DataVirtualizationMode property set to OnDemandManual and defines a simple data template for its items. In the resources dictionary of my layout root I have defined three additional data templates which I am going to use to display the navigation buttons discussed above. You may ask why three templates instead of one? The answer is simple: I do not want to display a previous button when I am at the first page, and do not want to display a next button when I am at the last page. Also, I want to display both buttons when I am somewhere in between.I am also going to access these templates in code and switch between them as the end user navigates trough pages.

The code-behind file of this example is also straightforward. The following snippet shows the method that loads the data according to the current page and decides which DataVirtualizationItemTemplate which will be used according to the current page. The DataVirtualizationItemTemplate defines the appearance of the specialized data virtualization item which will be displayed at the end of the scrollable list and which, when tapped, fires the DataRequested event which can be used to load further data items:

private void LoadPage(int page)
{
    List<string> source = new List<string>();
    int endIndex = page + this.pageSize;
    for (int i = page; i < endIndex; i++)
    {
        source.Add(this.dataSource[i]);
    }
  
    if (endIndex == 200)
    {
        this.listBox.DataVirtualizationItemTemplate = this.LayoutRoot.Resources["DataVirtualizationTemplatePrev"] as DataTemplate;
    }
    else if (this.pageStartIndex == 0)
    {
        this.listBox.DataVirtualizationItemTemplate = this.LayoutRoot.Resources["DataVirtualizationTemplateNext"] as DataTemplate;
    }
    else
    {
        this.listBox.DataVirtualizationItemTemplate = this.LayoutRoot.Resources["DataVirtualizationTemplateNextPrev"] as DataTemplate;
    }
  
    this.listBox.ItemsSource = source;
}

 

The page argument of this method is actually the page index which I will be loading. I also have a pageSize  field which defines how many items will be loaded at a time. The dataSource is a collection of data items which is used to load the paged data. In the real-life scenario this would be a web service that allows for requesting items from a given index and with a given count (ODATA for instance).

Here is what happens when the user taps on a navigation button:

private void btnPrev_Click(object sender, RoutedEventArgs e)
{
    this.pageStartIndex -= this.pageSize;
    this.LoadPage(this.pageStartIndex);
}
private void btnNext_Click(object sender, RoutedEventArgs e)
{
    this.pageStartIndex += this.pageSize;
    this.LoadPage(this.pageStartIndex);
}

 

Here is how this looks like on the WP7 emulator:

 

 

Some more information about the new Data Virtualization modes of the RadDataBoundListBox can be found here:

http://blogs.telerik.com/deyanginev/posts/11-06-01/raddataboundlistbox-learns-new-data-virtualization-techniques.aspx

and here:

http://www.telerik.com/help/windows-phone/raddataboundlistbox-features-datavirtualization-overview.html

You can find attached the whole WP7 app that implements this scenario and play with it to further explore the specifics of this approach.

OnDemandManualDemo.zip


Deyan Ginev
About the Author

Deyan Ginev

Deyan has been with Telerik for more than ​six years working on several different products with main focus on mobile technologies. Deyan is currently working on NativeScript– a platform for developing native mobile apps with JavaScript. Find him on Twitter via
@deyan_ginev.

Comments

Comments are disabled in preview mode.