This blog post presents a Windows Phone 7 Jump List control that I have developed.This post describes the API in detail and includes full sourcecode. Feel free to use and enjoy!
The video below shows the control working on the emulator, the video further down this page shows it working on a real device. Full sourcecode is linked at the end of this article.
Introduction
For Silverlight developers Windows Phone 7 is a dream come true, a mobile platform that supports a language / framework they already know, or as Jesse Liberty puts it, “You are already a Windows Phone Developer“. What I find really cool about Silverlight for WP7 is that exactly the same controls can be used both on the web and the mobile. However, the controls for Windows Phone 7 are tailored specifically for the mobile form factor having larger areas to ‘hit’, and gestures for scrolling for example. Despite this, there are times when you really need a control that is specific to the mobile platform.
Navigating long lists of data is a chore on a mobile device. On the desktop / web you can click on the scrollbar and navigate the full length of the list with a single gesture, whereas navigating the same list on a mobile requires multiple swipe gestures. This is where a Jump List comes in handy!
A Jump List groups the items within the long list into categories. Clicking on a category heading (or jump button) opens up a category view, where you can then click on one of the other categories immediately causing the list to scroll to the start of this newly selected category.
This blog post describes the API of the Jump List control I have developed. A link to the full sourcecode and a demo application can be found at the end of this blog post.
The video below shows the JumpList working (and performing well!) on a Samsung Omnia WP7. Apologies for the poor video quality!
Basic Example
The API for the JumpList is quite similar to that of the ListBox, it has an ItemsSource property which you set (or bind) the collection of objects you wish to render in the list. The appearance of each item is specified by an ItemTemplate. The example below shows a JumpList bound to a collection of simple Person objects:
public class Person { public string Surname { get; set; } public string Forename { get; set; } } // ItemsSource set in constructor of control .... list.ItemsSource = PersonDataSource.CreateList(50); |
(As an aside, the PersonDataSource above generates pseudo-random names using Markov Chains using some code I found online)
<l:JumpList x:Name="list" ScrollDuration="400"> <!-- category provider - details how the items are grouped --> <l:JumpList.CategoryProvider> <l:AlphabetCategoryProvider PropertyName="Surname"/> </l:JumpList.CategoryProvider> <!-- item template - details how each item is rendered in the list --> <l:JumpList.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" Margin="0,3,0,3" Height="40"> <Image Source="Head.png" Opacity="0.7" Width="40" Height="40"/> <TextBlock Text="{Binding Surname}" Margin="3,0,0,0"/> <TextBlock Text=", "/> <TextBlock Text="{Binding Forename}"/> </StackPanel> </DataTemplate> </l:JumpList.ItemTemplate> </l:JumpList> |

The main difference between the JumpList and a ListBox is that a JumpList requires that you supply a CategoryProvider. In the example above an AlphabetCategoryProvider was supplied which groups the supplied objects (in this case Person instances) based on the first letter of the property indicated by the PropertyName of the AlphabetCategoryProvider. In this example, the items are being grouped by the Surname property.
The animated scrolling as the list jumps from one category to the next can be controlled via the ScrollDuration property. The animated ‘reveal’ effect as the category buttons are drawn can be controlled via the CategoryTileAnimationDelay property which details the time between the animation being started for neighbouring category buttons.
Note, for very long lists with hundreds of items it makes sense to disable the scrolling effect as the list ‘jumps’ to the selected category.
The jump buttons that appear at the top of each group can be configured via properties that specify their style, template and item template. You can consult the API for more details. The category buttons which are rendered in the category view also have three similar properties. For example, you can use the JumpButtonStyle to make each button the same size, or the CategoryButtonStyle to create larger category buttons.
Selection
The JumpList exposes a SelectedItem property which can be used to get or set the currently selected item. This property also permits TwoWay binding to other controls or a View Model. The JumpList also exposes a SelectionChanged event which is fired whenever the SelectedItem property changed, this event is useful for more programmatic / non-databound usages.
The following code snippet shows a simple UI binding of the JumpList SelectedItem:
<StackPanel DataContext="{Binding Path=SelectedItem, ElementName=list}"> <TextBlock Text="SELECTED ITEM:"/> <!-- displays the Name property of the object bound to the JumpList --> <TextBlock Text="{Binding Name}"/> </StackPanel> <l:JumpList x:Name="list"> <!-- ItemTemplate etc ... --> </l:JumpList> |
Each item within the JumpList is contained within a JumpListItem. When an item is selected, the default JumpList item template changes the Foreground colour to PhoneAccentBrush. It is possible to style and template the JumpListItems via the JumpListItemStyle property. The following example adds a Border element and sets the Background colour of this Border when an item is selected:
<l:JumpList.JumpListItemStyle> <Style TargetType="l:JumpListItem"> <Setter Property="BorderThickness" Value="1"/> <Setter Property="Background" Value="#222"/> <Setter Property="Padding" Value="2"/> <Setter Property="Margin" Value="0"/> <Setter Property="HorizontalContentAlignment" Value="Right"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="l:JumpListItem"> <Border x:Name="LayoutRoot" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"/> <VisualState x:Name="MouseOver" /> <VisualState x:Name="Disabled"/> </VisualStateGroup> <VisualStateGroup x:Name="SelectionStates"> <VisualState x:Name="Unselected"/> <VisualState x:Name="Selected"> <Storyboard> <!-- change the background on selection --> <ColorAnimation Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="#555" Duration="0:0:0.5"> </ColorAnimation> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <ContentControl x:Name="ContentContainer" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" Foreground="{TemplateBinding Foreground}" /> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </l:JumpList.JumpListItemStyle> |

The Category Provider
As seen in the earlier example, the JumpList uses a category provider, specified via the JumpList.CategoryProvider property to place items into categories within the jump list. The CategoryProvider implements the following interface:
/// <summary> /// A category provider assigns items to categories and details /// the full category list for a set of items. /// </summary> public interface ICategoryProvider { /// <summary> /// Gets the category for the given items /// </summary> object GetCategoryForItem(object item); /// <summary> /// Gets the full list of categories for the given items. /// </summary> List<object> GetCategoryList(IEnumerable items); } |
The GetCategoryForItem method is used to determine the category for each item in the list, whilst GetCategoryList returns the full list of categories in order to display the category view.
The JumpList comes with a couple of ‘built in’ category providers:
The AlphabetCategoryProvider uses the first letter of a named property to identify the category for each item. The category list which AlphabetCategoryProvider provides is always the full alphabet. The category view ‘grays’ category buttons for which the source list has no items.
The DistinctPropertyValueCategoryProvider is a slightly more generic provider, placing items into categories based on the value of the property nominated via PropertyName. With this provider the category list displays all the unique or distinct values found for the given property.
For example, if you have a list of events which you want to group by month, you can use a DistinctPropertyValueCategoryProvider identifying a property on your object which indicates the month. For example:
public class JugglingEvent { public string Name { get; set; } public DateTime Date { get; set; } public string Description { get; set; } public int Month { get { return Date.Month; } } } |
The category provider is detailed as follows:
<!-- category provider groups by month--> <l:JumpList.CategoryProvider> <l:DistinctPropertyValueCategoryProvider PropertyName="Month"/> </l:JumpList.CategoryProvider> |
This will group the items by month. However, the Month property exposes an integer, and this will be supplied as the DataContext for the jump buttons and category buttons. In order to display the month indices as their respective strings, a value converter can be supplied to the jump button and category button item templates:
<!-- the jump button template renders the month as a string --> <l:JumpList.JumpButtonItemTemplate> <DataTemplate> <TextBlock Text="{Binding Path=., Converter={StaticResource MonthIndexToStringConverter}}"/> </DataTemplate> </l:JumpList.JumpButtonItemTemplate> <!-- the category template renders the month as a string --> <l:JumpList.CategoryButtonItemTemplate> <DataTemplate> <TextBlock Text="{Binding Path=., Converter={StaticResource MonthIndexToStringConverter}}"/> </DataTemplate> </l:JumpList.CategoryButtonItemTemplate> |

Custom Category Button Animations
When the category view is displayed, each category button is revealed via a storyboard. These storyboards are started sequentially with a delay, specified by the CategoryTileAnimationDelay property, between the start of neighbouring buttons.
The storyboards that define the animation are within the template of the category buttons. The JumpList control looks for two storyboards, name “ShowAnim” and “HideAnim”, and triggers these to show / hide the button respectively.
If you want to disable animations altogether, you can omit these storyboards. You can also specify your a custom animation by inserting your own storyboards into the category button template.
The example below adds a custom animation which reveals each button by rotating it around its centre:
<!-- create a custom category button animation --> <l:JumpList.CategoryButtonTemplate> <ControlTemplate TargetType="Button"> <Grid Background="Transparent" x:Name="Parent" RenderTransformOrigin="0.5,0.5"> <Grid.Resources> <Storyboard x:Key="ShowAnim"> <DoubleAnimation To="0" Duration="0:0:0.3" Storyboard.TargetName="Parent" Storyboard.TargetProperty="(Grid.Projection).(PlaneProjection.RotationX)"/> </Storyboard> <Storyboard x:Key="HideAnim"> <DoubleAnimation To="90" Duration="0:0:0.1" Storyboard.TargetName="Parent" Storyboard.TargetProperty="(Grid.Projection).(PlaneProjection.RotationX)"/> </Storyboard> </Grid.Resources> <Grid.Projection> <PlaneProjection RotationX="90"/> </Grid.Projection> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"/> <VisualState x:Name="MouseOver"/> <VisualState x:Name="Pressed"> <Storyboard> <ColorAnimation To="White" Duration="0:0:0" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"/> </Storyboard> </VisualState> <VisualState x:Name="Disabled"> <Storyboard> <DoubleAnimation To="1" Duration="0:0:0" Storyboard.TargetName="DisabledBackground" Storyboard.TargetProperty="(Rectangle.Opacity)"/> <DoubleAnimation To="0" Duration="0:0:0" Storyboard.TargetName="Background" Storyboard.TargetProperty="(Rectangle.Opacity)"/> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Rectangle x:Name="Background" Fill="{StaticResource PhoneAccentBrush}"/> <Rectangle x:Name="DisabledBackground" Fill="{StaticResource PhoneBackgroundBrush}" Opacity="0"/> <ContentControl x:Name="ContentContainer" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Padding="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/> </Grid> </ControlTemplate> </l:JumpList.CategoryButtonTemplate> |
If you have many categories, and want to disable the ‘reveal’ animation, simply supply a template without any storyboards, see the demo sourcecode for an example.
You can download the full sourcecode: WP7JumpList.zip
To run this code you will also need the Windows Phone 7 Toolkit.
If you have any feedback, ideas or bugs to report – please let me know!
Regards, Colin E.
Tags: Windows Phone 7


email: ceberhardt@scottlogic.co.uk
on Google+



Hello Colin,
Thank you very much not only for this great control, but also for your whole Blog, I am reading each of your articles as you publish them with great pleasure, and there is always something to learn – even when I thought to master the topic:-)
Related to the porting of this Control to WP7.1, the control is unfortunately broken in the WP7Contrib NuGet package too, it would be great if you can arrange a fix.
For your readers who need it earlier, here is the FIX (al least that’s what worked out for me):
It seems that the reason for the “Unspecified Error” mentioned in the last comments is due to the missing TargetType in three sections in the file “generic.xaml”.
To fix this, find the string “” in the mentioned file and replace it as follows (the leading lines are shown only to help you identifying the context):
<ControlTemplate>Line 58:
<ControlTemplate TargetType=”Button”>Line 223:
<ControlTemplate TargetType=”l:JumpList”>Line 272:
<ControlTemplate TargetType=”ItemsControl”>Hi Artur,
Thank you
… I promise I will fix this shortly – I have just been mega-busy!
Colin E.
Hi,
how do you port it to WP7.1 ? I have changed the suggested controlTemplates in generic.xaml and then changed the project to 7.1. Now when I build the project I get an error saying: “A namespace cannot not directly contain members such as fields or methods.”
What am I doing wrong? Any help is very appreciated
Hi there,
I posted a couple of days ago but it didn’t seem to take.
I’m trying, so far unsuccessfully, to use this control. I can run your sample code, no problem, but when I try to put a JumpList into a new, empty project I’m hitting difficulties. The xaml appears to be OK, but as soon as I assign anything to the ItemsSource I’m getting ‘Unspecified error’. This is when using the 7.1 build from WP7Contrib.
Is this build known to work?
Thanks
On closer reading my issue is identical to the one described below by talluri.
Note that putting the JumpList.ItemsSource = ….. within a try..catch block doesn’t catch the error. It still falls through to Application_UnhandledException.
I’m unable to get the source working in a project which targets 7.1.
Shame – it looks like a reat control, but I can’t use it. Interest to hear if anyone has got around this.
Sorry – been very busy recently. I hope to be able to look into and fix this issue next week.
Hi!
Any updates or workarounds for this? I’m getting the same error.
Thanks
Hello, I just want to know the effect to make an image or a button jumping like that. Thank you so much.
Has anyone got this working on 7.1 yet? Using the binaries downloaded from WP7Contrib so far has just changed the compilation errors.
nice work. i am trying to use this control.. but getting unspecified error..
I have created new project and added jumplistcontrol project to that. And added mainpage, demopageone,persondatasource and MarkovNameGenerator.cs. Am i missing any thing. I am using 7.1 version. I have already installed windows phone toolkit
The jump list control has been added to the WP7Contrib library which has a WP7.1 build.
I am using the WP7Contrib version of the JumpList control and having the same issue. I create an ObservableCollection and set the list.ItemsSource to that collection. The StackPanel holding the list is collapsed when I do this. When I make the StackPanel visible I always receive an “unspecifed error” that is caught by the Application_UnhandledException event. I know there is data in each item of the collection and have checked to make sure the Binding values are indeed in the collection of values. The AlphabetCategoryProvider has been set to a Key (included in each item of the collection) that is the alpanumeric letter for the category.
I am able to run the example project. I replaced the JumpListControl with the one from the WP7Contrib package and removed the old control from the project to insure I was using the WP7 version. My use of the control is very similar to the demopageone example only I am using an observablecollection instead of a list.
Not sure how to debug this…any advice would be appreciated.
David
OK – quite a few people are having issues – I’ll try to post an update shortly. Just a bit busy right now!
Curious if there was an update to this? I’ve just upgraded my project to Mango and after replacing the original JumpListControl reference with the new wp7contrib library, I’m still seeing this Unspecified Error. I couldn’t find a new blog post or any references to this on the codeplex site, and I also couldn’t see a relevant-looking checkin since the bug description given below on September 12th with a suggested fix.
Nice control, hope I haven’t just missed something obvious
Hi,
Thanks for this awesome control.
I downloaded the source code and it worked perfectly.
But I couldn’t use it in my project as my project targets Windows Phone 7.1
Jump list control works perfect with Windows Phone 7.0.
Can you provide me the control which is upgraded 7.1?
Thanks
Gautam
Hi, glad you like it. The JumpList control has been added to the WP7Contrib project (http://wp7contrib.codeplex.com/) you can find a 7.1 build for this control also.
Great control. Thanks for the efforts
Another scenario: While _categoryItemsControl is showing, navigate to another page. When you navigate back, _jumpListControl is disabled
The problem also happens with custom category animation. When the category list is showing, if you click one of the buttons to change animation style, category list is disappear and jump list is disabled.
I found a bug when updating the bound list. When the _categoryItemsControl is shown, if you change ItemSource of the list, _categoryItemsControl will dissappear and the _jumpListControl is disabled.
Please fix it. Thanks.
Hi,
first of all, thanks for your great control. It works fine under a WP7.0 project. But I’ve tried to add it to a 7.1(RC) project, with the latest Toolkit (august release) … damn I’ve a “unspecified error”. I’ve tried to update your project to 7.1 (without and after with updating toolkit), this is the same: “unspecified error”, and stacktrace from inner exception is:
at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.UIElement_Measure_WithDesiredSize(UIElement element, Size availableSize)
at System.Windows.UIElement.Measure_WithDesiredSize(Size availableSize)
at System.Windows.Controls.VirtualizingStackPanel.MeasureChild(UIElement child, Size layoutSlotSize)
at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint)
at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight)
at MS.Internal.XcpImports.MeasureOverrideNative(IntPtr element, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight)
at MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement element, Size availableSize)
at System.Windows.FrameworkElement.MeasureOverride(Size availableSize)
at System.Windows.Controls.ScrollContentPresenter.MeasureOverride(Size constraint)
at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight)
at MS.Internal.XcpImports.MeasureNative(IntPtr element, Single inWidth, Single inHeight)
at MS.Internal.XcpImports.UIElement_Measure(UIElement element, Size availableSize)
at System.Windows.UIElement.Measure(Size availableSize)
at System.Windows.Controls.ScrollViewer.MeasureOverride(Size constraint)
at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight)
at MS.Internal.XcpImports.MeasureOverrideNative(IntPtr element, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight)
at MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement element, Size availableSize)
at System.Windows.FrameworkElement.MeasureOverride(Size availableSize)
at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight)
at MS.Internal.XcpImports.MeasureOverrideNative(IntPtr element, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight)
at MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement element, Size availableSize)
at System.Windows.FrameworkElement.MeasureOverride(Size availableSize)
at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight)
at MS.Internal.XcpImports.MeasureOverrideNative(IntPtr element, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight)
at MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement element, Size availableSize)
at System.Windows.FrameworkElement.MeasureOverride(Size availableSize)
at Microsoft.Phone.Controls.PivotItem.MeasureOverride(Size availableSize)
at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Double inWidth, Double inHeight, Double& outWidth, Double& outHeight)
any ideas? Thanks
Ok I found the bug.
You forgot a targetype in generic.xaml, and SDK 7.1 doesn’t like it
So to fix it, open generic.xaml, go to line 58 and modify:
by
Happy coding:)
strange my post has been cut!
So go to line 58 and modify:
ControlTemplate
by
ControlTemplate TargetType=”Button”
Hi, Many thanks for that. I will update the code.
Hi Colin,
This is a great control, thank you for sharing. Just wanted to let you know that I’ve used your code to create a slightly different version of the control – I needed a slightly different “flavor”! Here’s the link to the post and the code:
http://priyarules.posterous.com/categorized-list-selector-for-windows-phone-7
cheers,
Priya
Colin,
Great article, fabulous series. Very useful, thanks for the effort.
I think that I have found a small issue with your Jumplist that came up when I was implementing tombstoning. When programatically setting the SelectedItem property, the property is set but the item in the list is not highlighted.
To see this in action with some test code, add the following method to your DemoPageOne class:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var selectedItem = (from i in list.ItemsSource as List select i)
.OrderBy(i => i.Surname)
.FirstOrDefault();
list.SelectedItem = selectedItem;
}
Unless I am missing something, the alphabetically first item (usually with a surname of “Aker”) in the list should be highlighted, but is not. Attempting to select the “Aker” item by touch or a mouse click does not highlight it, until another item is selected first, changing the SelectedItem reference, then it highlights.
It appears that the dependency property SelectedItem SetValue method does not call the OnSelectedItemPropertyChanged event unless the new SelectedItem is different from the old SelectedItem.
Can you suggest a fix?
Thanks.
Thank for letting me know, and for providing a test-case (that really helps!), I’ll take a look shortly.
Hi and thank you for you JumpList : very beautiful and useful !
I contact you because I have a problem with your module and the latest Mango Beta (Beta 2 Refresh) :
1 – I select an item from a jumplist to push a new page (NavigationService.Navigate)
2 – I go back to my jumplist
3 – My list content disappears…
First I thought it was because of my list size, but I just tried with a small list of 50 items et the problem is still there.
I know Mango is still in beta, but as it looks like this build is nearly in RTM so I think the problem will be there in release.
Thank you for you response.
Thanks for letting me know – I’ll test this issue shortly!
Can you please check that the data bound to the list that disappears are :
1 Properties
2 declared as public
Thanks for your answers.
Yes : datas of my jumplist are public properties of my model.
Hey Scott great stuff, I have to ask though if you plan to update the jumplist to match how it works in Mango, where each category button is locked to the top of the listbox?
Hi Danny, I am not sure what you mean about the Mango JumpList, can you point to an example?
Hi,
I think Danny talks about category title which stays on top of the list like the first letter in Contact app in Mango.
Yeah this would be cool, I might even dump the LongListSelector in favour of your JumpList, I actually notice the sticky-ness of the group header isn’t in the latest LLS control, unless I’m missing something.
This feature is a must!
I would like it too.
Great control!
Have you tried it binding to a property as well as setting the ItemSource?
John
Yes, this should work just fine!
Hi Sir,
Very nice control! Works like a dream in the emulator
I am having serious perf issues on an actual phone though. I have a list about 200 long and the only thing contained in the items control datatemplate is a button with text content. It slows down to a standstill and makes it almost unusable. Is there any way for me to speed up performance?
I am looking forward to the day when MS releases their control that displays the contact list in the people hub. SO SMOOOOOOOOTH
What aspect of the control slows down? This is certainly due to the underlying performance of Silverlight on WP7, however if you give me something specific i might be able to help.
Hey, just found this and its a breath of fresh air after fiddling with the longlistselector. But (of course there’s a but), it starts getting pokey to load with around 200 items, and I need it to be able to load 500 in a reasonable amount of time. Can you give me any general performance guidelines – what is it that determines load times, the complexity of the itemtemplate? Something else?
Thanks, and great work!
Hi Mike,
Glad you like it! I think expecting the list to load quickly with 500 items in a big ask. The phone hardware just isn’t that fast. The complexity of your ItemTemplate is critical, the visual tree construction and rendering is a big bottleneck on the phone.
One trick I use to make the phone more responsive is a DeferredLoadContentControl:
http://www.scottlogic.co.uk/blog/colin/2011/01/windows-phone-7-deferredloadcontentcontrol/
This control will render a loading indicator before the required UI is actually rendered. This means that complex page layouts do not affect initial page load times making the phone feel much more responsive.
Regards, Colin E.
Hi,
Thanks for creating such a nice control. I love this control as we have total control over everything from looks to animation.
But, I’m stuck on one thing. If i select an item and go to another page such as details for the selected item, then after coming back i can’t select the same item again,as it is still selected.I tried making the SelectedItem=null, but that didn’t help me. Please throw some light on where i’m going wrong.
Thanks.
Hi,
Glad you like it! I can confirm that setting SelectedItem=null does work, I just double-checked. Are you sure that this code is actually being executed in your view? When you navigate to a view via the back-stack (i.e. back-button keypress) the view constructor is not invoked. You should add the logic into your override of the OnNavigatedTo method:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
JumpListControl.SelectedItem = null;
}
Regards, Colin E.
Thanks, it works
Hi,
Again i’m stuck with the control.
The problem is that whenever i press the last item displayed in the category view(when the resultant group is not visible), the app crashes with the follwing log…
System.NullReferenceException occurred
Message=NullReferenceException
StackTrace:
at System.Windows.DependencyPropertyChangedWeakListener.Disconnect()
at System.Windows.DependencyPropertyChangedWeakListener.SourcePropertyChanged(DependencyObject c, DependencyProperty dp)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyProperty dp)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyProperty dp)
at System.Windows.DependencyObject.RaisePropertyChangeNotifications(DependencyProperty dp, Object newValue, Object oldValue)
at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet, Boolean isSetByStyle, Boolean isSetByBuiltInStyle, PropertyInvalidationReason reason)
at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet)
at System.Windows.Controls.ScrollViewer.set_ScrollableHeight(Double value)
at System.Windows.Controls.ScrollViewer.InvalidateScrollInfo()
at System.Windows.Controls.VirtualizingStackPanel.OnScrollChange()
at System.Windows.Controls.VirtualizingStackPanel.SetAndVerifyScrollingData(Size viewport, Size extent, Vector offset)
at System.Windows.Controls.VirtualizingStackPanel.UpdateLogicalScrollData(Size stackDesiredSize, Size constraint, Double logicalVisibleSpace, Size extent, Int32 lastViewport, Boolean isHorizontal)
at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint)
at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight)
at MS.Internal.XcpImports.MeasureOverrideNative(IntPtr element, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight)
at MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement element, Size availableSize)
at System.Windows.FrameworkElement.MeasureOverride(Size availableSize)
at System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget, Single inWidth, Single inHeight, Single& outWidth, Single& outHeight)
I’m not getting why this is happening.Please help…
Got it figured.
The jump list was getting out of the screen, beacuse of which it was crashing.
Just decreased the height and solved the crash.
Hi Colin
Excellent piece of work which I am using during my first steps with WP7 development.
I do, however, have a bit of an issue with the category buttons. In your example above, you populate the buttons with a month name, and the button stretches across the screen. I have tried this, but the button remains the same small size (I see ‘Ja’ for January) positioned to the left of the screen.
I have tried setting widths in the template but to no avail. How do I achieve what you show in your image?
Hi Sean,
Glad you like it! Take a look at the example projects, example #5 selection. This sets the category button style to specify a fixed width the spans the width of the phone screen:
[l:JumpList.CategoryButtonStyle]
[Style TargetType="Button"]
[Setter Property="Width" Value="420"/]
[Setter Property="Margin" Value="10"/]
[Setter Property="Padding" Value="8"/]
[/Style]
[/l:JumpList.CategoryButtonStyle]
Regards, Colin E.
Thanks for your prompt reply, I now have it as I want it
Fantastic work Colin, as usual
I’ve noticed one problem on my device: oftentimes, while scrolling through the list an item will get selected, even though I don’t “tap” it. I’m guessing it’s because you subscribe to the LeftMouseButtonUp event and when it’s raised set the SelectedItem?…
Interesting – I have used this control myself on a number of applications but have not observed that problem. I am not sure what to suggest!
Hi Colin,
Nice control !
I have been looking for a control that displays a long list of items that is easy to search and accepts multiple item selection but so far nowhere to find.
You think it is possible to make this jump list accept multiple item selection ?
Or do I use a checkbox in my template ?
I have tried using the checkbox with your control and it works. It didn’t work with the LongListSelector , the checked items disapeared after clicking a group item.
Kind Regards
Thomas
Hi Thomas, thanks for trying this and reporting back … glad to hear it works
Ignore that last comment. This is a problem with the toolkit contextmenu control causing the behaviour I’m seeing.
Thanks for getting back to me with that one Faz, I was going to have a look into this issue later this week.
Hi Colin
great control. I’m pulling out LongListSelector as we speak!
One small issue I’ve just found is that item selection is triggering on mouseup which has the effect of triggerring even while initiating a scroll. I haven’t looked into a fix yet but wanted to mention it in case this has already been resolved…
regards
[...] A Windows Phone 7 Jump List Control (Colin Eberhardt) [...]
You may not want to call it a “Jump List” since there is already a control in the toolkit for this (LongListSelector)…but more importantly, a Windows 7 JumpList is very different this and I suspect others will be drawn here to think of something like the Windows 7 JumpList
Hi Shawn, some good points, I hadn’t thought about Windows 7 confusion, I quite often search for WP7 info on Google and accidentally end up on Windows 7 pages! However, there is already a precedent for calling this a jump list, with two other blogs mentioning this control by the same name here and here.
I think LongListSelector is a terrible name! I hadn’t actually spotted that I was developing a control that was similar to one provided by the toolkit because of its non-descriptive name.
I will stick to “Jump List” for now, but will look out for Win7 users ending up here by mistake. Thanke for your feedback.
Hi Colin
Wow what a great control!
I just had to download the code to test the control myself.
Is it possible that the Jumplistcontrol project or dll is missing in the zip file?
I would really like to test your great control?
Thanks for checking!
Regards from Switzerland!
I have double checked – it is all there! The solution should contain two projects, one which is the jump list class library, the other which is the demo phone app.
[...] A Windows Phone 7 Jump List Control [...]
If items are added and removed dynamically from the source items collection will the groupings be handled automatically? For example, I have a long list of medical conditions and when the users selects one of those conditions, it should be removed from the long list as its already been selected. Say it was the only condition that began with the letter ‘x’, would that group label be disabled now?
Thanks in advance, I look forward to using this control either way, the animation is a great plus.
Hi, Good point, I have just updated the code so that it should handle changes in the bound collection correctly. However, the list takes a little while to build, on my phone it is ~400ms, (the phone hardware is nowhere near as powerful as your desktop PCs!) so your idea of removing items might not be practical. How about adding a checkbox to your ItemTemplate and allowing users to multi-select?
Very nice work. Well done sir.
[...] A Windows Phone 7 Jump List Control – Colin Eberhardt shares the implementation of a Jump List Control for the Windows Phone 7 platform, with a post which looks at the implementation and API offered by the control, videos of it in operation, and some examples along with the all important sourcecode so you can make use of the control. [...]
Hi Colin, nice job! Just one issue though, when I run the app WP7JumpList (on emulator or on a device) go to the first list (#1 Small list – 50 items), and click any of the letter items, the app crashes with:
XamlParseException occurred
AG_E_PARSER_BAD_TYPE [Line: 1 Position: 173]
It wouldn’t show me any source code in VS.
Furthermore, I’m getting compilation warnings that “Microsoft.Phone.Controls.Toolkit” could not be found, and several others due to that fact. I did try referencing Microsoft.Phone in both projects, but the app still crashes after this. Might you have any ideas as to why this would be happening? Thanks!
BTW, it seems to be happening in other lists too.
Hi Zack,
To run the code you need to install the Windows Phone 7 Toolkit as well. You can find that here:
http://silverlight.codeplex.com/releases/view/55034
I hope that fixes your issue.
You’re a genius.
That most definitely did fix my issue, thank you very much!
[...] ScottLogic [...]
Interesting work…
I always wanted to be one of those jedi that can build a complex (and work-able) user control in wpf/sl.
Btw, how this control compare with LongListSelector from the toolkit? I haven’t used the latter extensively, would you sum up the differences?
Don’t worry young Skywalker, you will be a Jedi one day!
Regarding the LongListSelector, frustratingly I found out about that control when I was almost done with mine! I did take a very close look at the LongListSelector to see how it compared (to see whether it was worth publishing my control!)
My JumpList control is quite a bit more user-friendly, with the LongListSelector you have to structure / group the data yourself, as described in this blog post. Also, my control is more ‘sexy’, LongListSelector does not have animated effects for the tiles, there is a blog post that describes adding animations to the LongListSelector, but it does not work on a real phone
… the animations are jumpy and stutter!
The LongListSelector does however have a slight advantage in initial render speed, this is because it implements its own approach to virtualization from the ground-up, whereas my JumpList relies on ItemControl + VirtualizingStackPanel.
Hope that helps, Colin E.
A Windows Phone 7 Jump List Control | Colin Eberhardt’s Adventures in WPF…
Thank you for submitting this cool story – Trackback from DotNetShoutout…