Wednesday, December 14, 2011

Data Virtualization in Metro-style apps with ISupportPlaceholder

Update 8th April 2012 : Modified to reflect changes upon release of Windows 8 Consumer Preview - References to IVirtualizingVector replaced with ISupportPlaceholder.

In my last post I introduced an implementation of the IObservableVector<T> interface that allows Windows 8 Metro-style applications to automatically update data bound XAML items controls as the underlying data source changes. In this post I am going to delve one stage deeper by demonstrating an implementation of the ISupportPlaceholder interface that enables data virtualization

A Background to Data Virtualization

To start I will provide some background to data virtualization and explain why this is becoming essential for modern applications to improve performance with large data sets. In a traditional, non-data-virtualized application, lists of data must be fully loaded into memory before they can be displayed to the user. When this data is held in a local database or file system this may mean loading many hundred items into memory before being shown in the user interface. With modern cloud-connected applications this becomes more of an issue as they must all be downloaded across what is a relatively slow connection.
In web applications this problem has been solved by the concept of paging – only a small number of items are shown at any one time, and the user can move between the pages by following links. In client based applications however the user expects a more seamless experience – a single list that can be scrolled through as desired.
Data virtualization solves this problem by only downloading and storing in memory the data that is required, deferring the download of further items until they are scrolled into view. The user sees a single list as if they are viewing the total data set, however as they move through the list any newly visible items are obtained on demand.

Data Virtualization for Metro-Style Apps

In Windows 8, Metro style applications support virtualized lists through the ISupportPlaceholder interface,

public interface ISupportPlaceholder
{
    bool IsPlaceholder(object item);
}

At first sight it is not immediately obvious how this can be used to virtualize a list, however it provides the vital link between a virtualization aware data set and a data bound user interface. An ISupportPlaceholder implementation is responsible for providing any data virtualization logic,


  • In general the list should behave as you would expect for an IObservableVector<T> implementation
  • When the items are requested the list should return the actual item if this is available, or a placeholder item if it has yet to be downloaded
  • The IsPlaceholder(…) method may then be called with each item returned in the list, and the ISupportPlaceholder implementation should return true if this is a placeholder item, otherwise false
  • It is also the responsibility of the  ISupportPlaceholder implementation to download any requested items in the background and update the list as these are available.

In return the standard Metro-style items controls will show any items for which IsPlaceholder(…) returns true as a grey rectangle,



An ISupportPlaceholder Implementation


To assist with data virtualization in .Net based Metro-style applications a base implementation is provided as part of the freely available Cocoon framework. This is provided as the Cocoon.Data.VirtualizingVector abstract class, into which you simply provide your custom data retrieval logic. You will either be requested for the number of items in the list or a specific item, and once obtained should then call the UpdateCount(…) or UpdateItem(…) methods

public class PersonCollection : VirtualizingVector
{
    protected override void FetchCount()
    {
        // Perform custom code here to retrieve
        //     the number of items in the dataset
 
        UpdateCount(itemCount);
    }
 
    protected override void FetchItem(int index)
    {
        // Perform custom code here to retrieve
        //     the specified item from the dataset
 
         UpdateItem(index, retrievedItem);
    }
}

The VirtualizingVector class then takes care of implementing IObservableVector<T> and ISupportPlaceholder, returning of suitable placeholder objects for items as they are requested, and updating items with real data as it is made available.

Of course this approach would still consume large amounts of memory when displaying a list with a large number of placeholder items. The VirtualizingVector class overcomes this by using the provided VirtualizingList<T> implementation. Without going into detail, this behaves as you would expect for a list with a large number of elements, whilst allocating memory efficiently to store only those items that are not virtualized.

Summary


In conclusion, the Cocoon framework provides an ISupportPlaceholder implementation designed to enable data virtualization for Metro-style applications. The code is freely available for download from the Cocoon CodePlex site (to get the latest version go to the “Source Code” tab, select the first change set and use the “Download” link).
In my introduction to the Cocoon framework I stated that one of my aims was to bridge the divide between the stateless paging model of most web APIs and the “fast and fluid” interfaces of Metro-style applications. Now that I have provided the fundamentals, next time I will try to bridge this gap by introducing “data lists” and “data list sources”.

10 comments:

Anonymous said...

I have tried to use Cocoon. I have a dataset of ~1000 items, they all display. But it loads all items up front. i.e. FetchItem gets called 1000 times even though only the first 20 visible items should be??

Unknown said...

Sorry to hear you are having some problems... Are you using the Windows 8 Consumer Preview? There is a known issue with the Visual Studio templates in this release that disables data virtualization (see this forum post).

If you remove the ScrollViewer around the GridView in the template you should see virtualization as expected, although unfortunately this doesn't give the desired layout. I am currently investigating an alternative virtualization strategy that may circumvent this problem. Get in touch via the contact link in the right-hand pane and I can update you by e-mail with any progress I am making.

GMan said...
This comment has been removed by the author.
GMan said...

This is so good Andrew, thanks for this.

Sorry I am fairly new to XAML and of course Metro, from what I understand from your articles your Cocoon framework, (specifically the data virtualization I am most interested in via the placeholder) you created this incorporating existing Microsoft interfaces and/or classes to address the current Metro/Win8 shortcomings, but are you saying Microsoft will fix all this up by RTM and we will have controls data binding fluidly like your PagedDataListSource out-of-the-box?

Unknown said...

GMan,

Good to hear that the information here is of interest to you.

Regarding what Microsoft provides vs the Cocoon framework... Windows 8 contains several UI controls for displaying lists of data and placeholders where data doesn't exist. Determining when to show a placeholder is just an interface and it is up to the app developer to determine if a placeholder should be shown in place of an item. This is the part that the Cocoon framework aids with through its data framework (either VirtualizingVector or VirtualizingDataList).

I do not anticipate that this situation will change on RTM of Windows 8. In my comment above I mentioned a known issue, however this relates to templating of some of the controls rather than accessing data.

Hope this clarifies things.

Abner said...

Hi Andy,

Excellent simple framework for working with paged data.

Have you made any progress on sorting the scrollviewer issue removing virtualisation?

If you have any pointers they would be much appreciated.

A. Doon

Unknown said...

Abner,

Sorry to report that I have no further news on this currently. My understanding from the MSDN forums was that this was a known issue with the templates that was being investigated.

I was holding off until the Windows 8 Release Preview (start of June) to see if this issue is fixed. If not I have a few ideas for workarounds that I will investigate then.

Andy

Abner said...

Thanks for the response Andy.

I'm also awaiting the June drop to see if it solves this (Which you would hope so).

Have seen numerous posts on the forums with people being hit by this issue.

Kate Dunkin said...

Great post! I came across your blog while I was looking into hiring a information technology specialist because I know they can really help enhance a business. This was really informative, thank you for sharing this with us!

Ampcus Inc said...

Cisco Data Virtualization
Unified provides an enhanced collaboration experience with Cisco’s Collaboration Room End Points for a wide set of business purposes. Cisco’s Collaboration Room EndPoints gives a steady experience to the users when grouped with customer partnership, discussion solutions and integrated communication.