Phone 7 Back Button and the ListPicker control
Dec
4
Written by:
12/4/2010 1:55 PM
I had disappeared once again for far too long; however the time has been well spent. I have been heads down coding apps for Phone7 and learning the nuances of the platform. I have also learned much about the certification process in which your apps must go through before making it to the marketplace. I hope to share a few tips & tricks with you from what I have learned in this and upcoming articles.
This post will focus on the requirement stated in the certification documentation regarding back button navigation when menus or dialog boxes are present on the current page. Over the last few days I have had two separate apps fail certification due to an oversight in this area. I decided I would post what I have learned and hopefully help prevent others from encountering the same issues when they submit their apps.
While developing my first Phone 7 app I was stumped momentarily at the absence of a ComboBox in the phone controls. I use this control so often in Silverlight that I had to wonder what I would do without it. I quickly found that we are supposed to use a ListPicker control from the control toolkit in place of the traditional ComboBox. Great! So off I went dropping them into my app and chugging along ignorant to what this meant in regards to navigation through the app. I wasn’t until recently that I was pointed to the section of the certification requirements document that says:
“If the current page displays a context menu or a dialog, the pressing of the Back button
must close the menu or dialog and cancel the backward navigation to the previous page.”
– Windows Phone 7 Application Certification Requirements.pdf Section 5.2.4
* Link to the document as of 12/04/10: direct link to the PDF file
Apparently, this includes ListPicker controls that are in the expanded mode (waiting for a selection to be made). This caused me to rework some pieces of apps I was currently developing. Then I decided instead of writing the same code in each page code-behind, I would just write a behavior I could drop on each ListPicker to handle the back button press event.
The main piece of code that takes care of the issue is simple and only takes a few lines of code:
private void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
{
if (this.AssociatedObject.ListPickerMode == ListPickerMode.Expanded)
{
this.AssociatedObject.ListPickerMode = ListPickerMode.Normal;
e.Cancel = true;
}
}
First check to see if the ListPicker is expanded and if so set it back to the normal mode and cancel the navigation by setting the Cancel property of the event args to true. That’s is all there is too it. So simple it is easy to forget and cause your app to fail certification. Now that I have packaged this logic into a behavior, I just have to remember to drop it on my ListPicker controls that will not use the FullMode. For more information on the ListPicker check out the toolkit page on CodePlex: http://silverlight.codeplex.com/
To make it easy, here is the code for the in its entirety behavior:
public class CancelBackButtonListPickerBehavior : Behavior<ListPicker>
{
private PhoneApplicationPage _page;
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded);
}
void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
_page = FindParentOfType<PhoneApplicationPage>(this.AssociatedObject);
_page.BackKeyPress += new EventHandler<System.ComponentModel.CancelEventArgs>(page_BackKeyPress);
}
protected override void OnDetaching()
{
base.OnDetaching();
_page.BackKeyPress -= new EventHandler<System.ComponentModel.CancelEventArgs>(page_BackKeyPress);
this.AssociatedObject.Loaded -= new RoutedEventHandler(AssociatedObject_Loaded);
}
void page_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
{
if (this.AssociatedObject.ListPickerMode == ListPickerMode.Expanded)
{
this.AssociatedObject.ListPickerMode = ListPickerMode.Normal;
e.Cancel = true;
}
}
public static T FindParentOfType<T>(FrameworkElement element)
{
var parent = VisualTreeHelper.GetParent(element) as FrameworkElement;
while (parent != null)
{
if (parent is T)
return (T)(object)parent;
parent = VisualTreeHelper.GetParent(parent) as FrameworkElement;
}
return default(T);
}
}
I hope this helps!
3 comment(s) so far...
Re: Phone 7 Back Button and the ListPicker control
I'm glad you're blogging about WP7. Can't wait to see more :)
By Michael Washington on
12/8/2010 8:25 AM
|
Re: Phone 7 Back Button and the ListPicker control
Good to know. Quite helpful to have tips like this because it allows the phones to be more accessible and useful.
By David on
3/28/2011 3:12 PM
|
Re: Phone 7 Back Button and the ListPicker control
Thanks David, I couldn't agree more! Also, I hope that it may save us Devs a bit of frustration if we do not have to resubmit our apps multiple times. ;)
By Ian T. Lackey on
3/28/2011 3:13 PM
|