One of the most useful controls in Windows Phone 7 is the so called “JumpList” and its popup “Quick Jump Grid” UI – that is, according to the official Microsoft design guidelines, a “Way to help the user to scroll through long lists”.
The First Look example of RadJumpList in our demo application
Much like in Windows 7, the “quick jump grid” user experience enables you with fast navigation to a desired location within the associated list of items. In order to populate the jump grid with items, the underlying list should be grouped by some criteria. So, how do we do the grouping? Or, how do we do common data operations like grouping, sorting and filtering?
Following is a brief overview of what the available options are:
LINQ extensions over IEnumerable<T> instances
- Fastest possible solution
- Minimal memory footprint
- Cannot be declared through XAML.
- Does not track source collection changes – you should always update your data manually.
- Does not keep the current state of the data – e.g. is it grouped or how is it sorted?
- Does not track changes in each business object.
- Does not provide currency management.
QueryableCollectionView (QCV), available in our WPF and SL solutions
- Common solution, sharable among all XAML suites.
- Mature product with well adopted public API.
- Highly flexible and extensible.
- QCV relies heavily on the IQueryable interface and the extensions over it, lambda expressions and dynamic method emitting. The major problem here is that there is no IQueryable support for WP7 and no System.Reflection.Emit namespace. We have tried the only possible solution – to use the IQueryable implementation that comes with Mono. Although it seems pretty straightforward, the performance hit of evaluating all these expressions using reflection is enormous and simply unacceptable (see comparison table below).
System.Windows.Data.CollectionViewSource, residing in the System.Windows.Data namespace.
Provides filtering through a delegate and sorting through a property-based mechanism. Does not implement grouping – a NotImplementedException is thrown in case you try to get the GroupDescriptions property. Definitely not an option.
System.Windows.Data PagedViewCollection that comes with the Silverlight 3 System.Windows.Data assembly.
- XAML support.
- Common data collection users are familiar with.
- Relatively big memory footprint.
- Slow performance – it is about 2 times slower than LINQ extensions.
- Silverlight 3 assembly, which Visual Studio recognizes and warns for – the warning states that “Your program may become unstable if you use this assembly”, which is definitely something we do not want our users to experience.
- Not extensible and customizable.
Obviously none of the above described options is flexible enough to be used in RadJumpList. That is why we decided to implement our own data layer, specifically for Windows Phone 7. This layer is as minimalistic as possible and covers all the functionality needed to implement RadJumpList. It uses the well adopted “Descriptor” semantic and defines its data operations through abstract logical objects named “descriptors”. We know that performance is of great importance for a WP7 application and that is why we created the so called “Generic Descriptors” which accept delegates of type Func<TElement, TKey>. When such kind of descriptors is specified, our data layer will internally use LINQ and its extensions (as I mentioned earlier that is the fastest possible solution) to prepare its data. We also know that having XAML support is a very important part of any Silverlight application and that is why we created yet another kind of descriptors – the “Property Name” based one. These are descriptors that can be declared in XAML and use reflection to look-up the property values needed for the data operations. Although this data manipulation mode is slower, its performance is acceptable as it has lots of internal optimizations and is only about 20% slower than the LINQ based one.
Here is a table that compares the results of some performance tests (how much it takes to group data) we did while making our research:
| ||500 items in 50 groups ||1000 items in 50 groups ||5000 items in 50 groups |
|LINQ Extensions ||61ms ||85ms ||261ms |
|Telerik Data Layer ||66ms ||92ms ||268ms |
|PagedCollectionView ||149ms ||242ms ||961ms |
|QCV (using IQueryable from Mono) ||431ms ||531ms ||1121ms |
RadJumpList is currently the only consumer of this data layer. Another natural consumer would be a grid control which however is something pretty abstract in the mobile context and definitely differs from the standard desktop Grid View. We will be happy to hear your thoughts about what other usages this data layer may have within a Windows Phone 7 application.