This blog post describes a Windows Phone 7 NavigationList control, a list control designed for navigation pages. The NavigationList renders twice as fast as a ListBox and has a slightly simpler API.
A few months ago I blogged about the relative performance of the Windows Phone 7 emulator versus the same code being run on the real hardware. There were a couple of take-home messages from this blog post, firstly the performance on real hardware is typically much slower than the emulator, and secondly an ItemsControl
can render the same content as a ListBox
in less time, making them a better choice for rendering lists of items for navigation.
The recent NoDo updates included some performance improvements, most of which focus on load performance. I re-ran the tests from my previous blog post pre-NoDo and after installing NoDo on the phone (Samsung Omnia), but saw no difference in performance between my measurements, which is pretty much what I expected:
Load time is still a significant issue for Windows Phone 7 Silverlight applications, and anything that can be done to reduce this will make your application more slick and useable.
I still see examples on the internet of people using the ListBox
for navigation within Windows Phone 7 application, despite the poor performance when compared with an ItemsControl
. This is probably because ListBox
has a slightly simpler API. In order to combat this I have come up with a NavigationList
control, which is based on an ItemsControl
. This control wraps up all the ItemsControl
configuration and click / manipulation handling to give a fast and easy-to-use control which simply raises a Navigation
event in response to user interactions.
NavigationList Control
The NavigationList
control is a lightweight control that can be used to render a list of items (base on an ItemTemplate
). The following XAML snippet shows how to use this control:
The NavigationList
has an ItemsSource
property which is used to supply your list of items, and an optional ItemTemplate
template where you specify how they are rendered.
The control fires a Navigation
event whenever the user clicks on an item. This event has an Item
argument which contains the item (from the ItemsSource
) that was selected. This is typically used to navigate to a new page, as in the example below:
So, how does the NavigationList
compare to a ListBox
? In terms or performance, it is a clear winner. The example project for this blog post has a test which renders exactly the same content with a ListBox
and a NavigationList
. Here's how the load time of the page compares:
A page which uses a NavigationList
renders twice as fast as an equivalent page that uses a ListBox
!
Another problem with using ListBox
is that selection state is 'persisted' in the back stack, therefore when you navigate back to the page, you must clear the SelectedItem
. Interestingly I just spotted a blog post by a WP7 developer who's application was rejected during the marketplace submission process for forgetting to do just this!
NavigationList Implementation
The control itself is quite simple, the template includes an ItemsControl
, which binds to the NavigationList
ItemsSource
and ItemTemplate
dependency properties. The ItemsControl
uses a VirtualizingStackPanel
for the ItemsPanel
to give a faster load time (as does the ListBox
):
ItemsControlEx
is a simple subclass of ItemsControl
which raises an event each time an item is added to the panel:
The NavigationControl
locates the ItemsControlEx
instance from its template to handle this event. Each time an element is added, handlers are added to various events:
The above could have been achieved without the use of ItemsControlEx
by providing a container for each item that is added, much the same was as the ListBox
contains items within a ListBoxItem
instance. However, the aim here is to make the control as lightweight as possible, which means minimizing the number of visual elements created.
The Element_MouseLeftButtonUp
event handler raises the Navigation
event, but what are the manipulation event handlers for? This is because if the NavigationList
is used within a control that performs some action due to manipulation, the Pivot
control which reacts to swipe for example, a mouse up event is still fired when the manipulation ends and this results in a navigation firing incorrectly.
So there you have it, the NavigationList
, simple and fast.
Now people ... please stop using ListBox
for navigation, it is slow and it's API is cumbersome!
You can download the sourcecode here:NavigationListControl.zip
Regards, Colin E.