Navigation in Windows Phone with complex parameter type using Caliburn.Micro

Hi guys,

Today I’ll describe the way we do navigation on Windows Phone using Caliburn.Micro for one particular case – when we need to pass instance of complex type.

For those who doesn’t know what complex type is, this could be some class which has properties/fields combined of primitive or other complex types:

    public class Customer
        public string FirstName { get; set; }

        public int Age { get; set; }

        public IEnumerable<Order> Orders { get; set; } 

    public class Order
        public int Quantity { get; set; }

The issue with Windows Phone navigation (even when you use Caliburn.Micro) is that it allows to pass primitive types only:

                .WithParam(model => model.Date, DateTime.Now)

This is because Windows Phone navigation system uses Uri approach to pass parameters (e.g. CustomersOrders.xaml?Date=25/07/2014)

Fortunately, I’ve found solution to pass complex properties by implementing extension method for Caliburn.Micro INavigationService:

    public static class NavigationServiceExtensions
        public static void Navigate<TNavigationTarget, TArgument>(this INavigationService navigationService, TArgument parameter) 
            where TNavigationTarget : class, IHaveComplexPropertyOfType<TArgument> where TArgument : class
            NavigatedEventHandler eventHandler = null;
            eventHandler = (sender, args) =>
                FrameworkElement view;
                TNavigationTarget target;
                if ((view = args.Content as FrameworkElement) == null ||
                    (target = view.DataContext as TNavigationTarget) == null) return;


                navigationService.Navigated -= eventHandler;

            navigationService.Navigated += eventHandler;

Here I subscribe to Navigated event and use Init method of IHaveComplexPropertyOfType to pass complex parameter. This interface looks has the following member:

    public interface IHaveComplexPropertyOfType<T>
        void Init(T propertyValue);

I’m not sure whether there are other implementations for this scenario available, but this is the way we do navigation and I hope this can help you as well.