Posts tagged ‘WP7’

Navigating to the Current Page on WP7

Sometimes you want to be able to “reset” the page you’re on. For example, the page is a form with a bunch of data that gets filled out. When the user clicks save, you prompt them and ask if they want to add another. If so, then you need to reset the page back to it’s original state. This sounds easy enough to do straight from code, but resetting everything isn’t always as easy as it sounds.

I’ve found that navigating to the current page works the best. Then the page runs as new, and everything gets setup properly without any extra code.

By default, you can’t navigate to the same page; it just doesn’t do anything. The trick here is to make the URI unique.

var uri = new Uri( string.Format( "{0}?unique={1}", "SamePage.xaml, Guid.NewGuid() ), UriKind.RelativeOrAbsolute );
RemoveBackEntry = true;
NavigationService.Navigate( uri );
view raw Example1.cs hosted with ❤ by GitHub

You may also have noticed the line ‘RemoveBackEntry = true;’. When navigating back to yourself, you don’t want the page to keep getting added to the back stack. You can see how to remove the back entry in my previous post Navigating with MVVM on WP7.

Navigation with MVVM on WP7

One thing that isn’t very straight forward when using MVVM on WP7 is how to navigate around. Many articles I’ve seen have said to use a messaging (pub/sub) system like the EventAggregator in Prism. I personally found this to not work the greatest. Plus, you want to be able to use the NavigationContext to grab things from the URL. The approach I came up with is pretty simple in my opinion and works just like it does if you’re using code-behind.

The view model base class will be setup just like a code-behind file so we can access the NavigationService, NavigationContext, and the navigation events.

using System.Windows.Navigation;
using Microsoft.Practices.Prism.ViewModel;
namespace RememberIt.WP7.App.ViewModels
{
public abstract class ViewModelBase : NotificationObject
{
protected bool RemoveBackEntry { get; set; }
public NavigationService NavigationService { get; set; }
public NavigationContext NavigationContext { get; set; }
public virtual void OnNavigatedTo( NavigationEventArgs e ) {}
public virtual void OnNavigatingFrom( NavigatingCancelEventArgs e ) {}
public virtual void OnNavigatedFrom( NavigationEventArgs e )
{
if( RemoveBackEntry )
{
RemoveBackEntry = false;
NavigationService.RemoveBackEntry();
}
}
}
}
view raw Example2.cs hosted with ❤ by GitHub

For this to work, you’ll need a PageBase class every view will inherit from. I’m sure there is a slick way to hook into every page without doing this, but I haven’t taken the time to figure it out yet.

using Microsoft.Phone.Controls;
using RememberIt.WP7.App.ViewModels;
namespace RememberIt.WP7.App.Views
{
public class PageBase : PhoneApplicationPage
{
protected PageBase()
{
Loaded += PageBaseLoaded;
}
private void PageBaseLoaded( object sender, System.Windows.RoutedEventArgs e )
{
var viewModel = DataContext as ViewModelBase;
if( viewModel != null )
{
viewModel.NavigationService = NavigationService;
}
}
protected override void OnNavigatedTo( System.Windows.Navigation.NavigationEventArgs e )
{
base.OnNavigatedTo( e );
var viewModel = DataContext as ViewModelBase;
if( viewModel != null )
{
viewModel.NavigationContext = NavigationContext;
viewModel.OnNavigatedTo( e );
}
}
protected override void OnNavigatingFrom( System.Windows.Navigation.NavigatingCancelEventArgs e )
{
base.OnNavigatingFrom( e );
var viewModel = DataContext as ViewModelBase;
if( viewModel != null )
{
viewModel.NavigationContext = NavigationContext;
viewModel.OnNavigatingFrom( e );
}
}
protected override void OnNavigatedFrom( System.Windows.Navigation.NavigationEventArgs e )
{
base.OnNavigatedFrom( e );
var viewModel = DataContext as ViewModelBase;
if( viewModel != null )
{
viewModel.NavigationContext = NavigationContext;
viewModel.OnNavigatedFrom( e );
}
}
}
}
view raw PageBase.cs hosted with ❤ by GitHub

So, when the page loads the NavigationService is set to the view model. When any of the navigation events occur, they are also called on the view model while setting the NavigationContext.