Windows Phone 7: Navigating After A Picture/Camera Task

UPDATE: There are a number of other possible solutions in the comments.

While working on a Windows Phone 7 project I came up against a problem in which the project would crash after we took a picture, giving us the error:

NavigationService.Navigate(new Uri(“/OurView/NextView.xaml”, UriKind.Relative));

The scenario we wanted went something like this: We wanted the user to tap a button and launch the camera task. This would close (tombstone) the application until the camera task was complete (the user took a picture and returned to the app). Upon completion, the application is re-initiated and the camera task hands the application an image stream that we can use to determine the bar code number. We then navigate to a screen that will show all the information about the product the user just scanned.

The problem with this way of doing things is that when we tried to navigate to a new page in our camera.Completed event handler (helpfully titled camera_Completed), we got a NullReferenceException on our NavigationService.

“How could this be?” I asked myself and the Internet. The NavigationService was there when we left. How could it not be there when we got back? The Internet had no helpful answers. Stupid Internet.

As it turns out, the NavigationService doesn’t actually show up in a page until the page UI is fully loaded (or so I have been told). That means that we simply can’t navigate directly from the camera.Completed event because the UI isn’t loaded.

Most other Windows Phone 7 programs with camera tasks we looked at had some additional user input after the task was completed that users would then interact with to handle navigation. We didn’t want that. Once the user took a picture, we wanted them to start getting results without any additional interactions.

Here is our solution for navigating after the camera task (which will also work for navigating after any task):

First, add a property to the page that can determine if the application was initiated after the task.

bool comingFromCamera = false;

Make sure you set this to true in your camera.Completed event handler:

void camera_Completed(object sender, PhotoResult e)
{
this.comingFromCamera = true;
}

Add an event handler for the page loading event  in the page constructor:

public MainPage()
{
InitializeComponent();
// Whatever other stuff you need in here
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}

In the MainPage_Loaded event handler, check to see if the page was initialized after the camera task or initialized normally. If it was initialized after the task, navigate to your heart’s content.

private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
if(this.comingFromCamera)
NavigationService.Navigate(new Uri(“/OurView/NextView.xaml”), UriKind.Relative));
}

And that should work. Let me know in the comments if you’re having additional difficulties.

6 thoughts on “Windows Phone 7: Navigating After A Picture/Camera Task

  1. Hey Matthias,

    I didn’t try but… Did you try using Dispatcher.BeginInvoke to delay your navigation until after all the instructions on the UI thread have been processed? This will add the instruction to the queue, but it will be executed with a delay. Combined with a lambda expression and closure, this would probably be the simplest syntax. Alternatively, you may want to save the stream and do the navigation in the Loaded event…

    Cheers,
    Laurent

  2. You can wire up the chooser’s completed event in one of two places – The page constructor, or the page loaded event handler. If you move wiring up of the completed event to the page loaded event handler, you should have access to the NavigationService, and shouldn’t need the delay processing logic.

  3. Derek,

    I actually tried that and it gave me the same NullReferenceException on my NavigationService. When I dig into the error, it tells me that it can’t find the application RootFrame.

    Which is really freaking weird and possibly a bug in the system. But that’s the coding reality I’m living with right now. Can’t let that slow me down! 🙂

  4. Hi Matthias,
    In the WP7 app I’m working on at the moment I do navigation in the CameraCaptureTask and PhotoChooserTask Completed event handlers by using the following code and haven’t had the problems that you describe (YMMV):

    (Application.Current.RootVisual as INavigate).Navigate(target);

    Derek.

Comments are closed.