Windows Phone 8 - MessageMediator

Topics: Feature requests, Questions
Aug 11, 2013 at 11:29 PM
Hi,

I'd like to use the Mediator with Catel.

Simple Example - I have a MainView with MainViewModel and a DetailsView with DetailsViewModel. I'd like to send a string from the MainViewModel to the DetailsViewModel, when I'm executing a command. The command sends the message and navigates to the DetailsView.xaml.
Problem is, the DetailsViewModel (I think) doesn't exist yet and so there's nothing arriving :(

How can I either tell Catel to create all the ViewModels at the beginning or even better, create the DetailsViewModel when I'm navigating to the DetailsView and then send the message, so the DetailsViewModel can receive it.

It thought that [InterestedIn(typeof(MainViewModel))] is helping with that, but I think I didn't understand it completely :s

Thank you so much for your great Framework... I really enjoyed going the first steps with it!
Fabian


P.S.: A ZXing.Net Service could also be a very very nice idea ;) Barcodes are conquering the world right now :)
Coordinator
Aug 12, 2013 at 8:02 AM
The MessageMediator can only be used on "live" objects. If there is no instance of an object, it cannot receive messages. I am not sure what you are trying to achieve, but instantiating all view models at startup is a bad idea IMHO. However, if you really want to do this, you can implement your own version of IViewModelFactory. Then you can create the view models at startup of your app and return the existing instances when Catel asks the IViewModelFactory to return the right instance. However I think it is important to known that moving data around is better via services or models.

The XZing.net service is a good idea, but we will not implement it in Catel itself. We try to keep the assemblies as small as possible. It shouldn't be too hard to implement services yourself (in the end, just class + interface + registration in servicelocator).
Aug 12, 2013 at 3:15 PM
To pass information between Views, the Windows Phone suggests using passing parameters via URI Query String. e.g. /Views/DetailsView.xaml?PersonId=1234
How would you do it with Catel?

Thanks a lot for your time! :)
Coordinator
Aug 12, 2013 at 3:32 PM
You can use the NavigationService for this.
Aug 12, 2013 at 3:34 PM
Thanks
In the Documentation about the NavigationService https://catelproject.atlassian.net/wiki/display/CTL/NavigationService there is only the MessageService showing. But I think I'll figure it out ;)
Coordinator
Aug 12, 2013 at 3:35 PM
Yeah, that's an issue, will look into that later. Should have navigationservice info ;-)
Aug 12, 2013 at 11:30 PM
Edited Aug 12, 2013 at 11:30 PM
so how do i catch the dictonary i gave the INavigationService via
nav.Navigate("Views/MessageView.xaml", new Dictionary<string, object>
            {
                {"InventoryNumber", InventoryNumber},
                {"SerialNumber", Computer.SerialNumber}
            });
Aug 12, 2013 at 11:50 PM
i also tryed
var dict = new Dictionary<string, string>
            {
                {"InventoryNumber", InventoryNumber},
                {"SerialNumber", Computer.SerialNumber}
            };
            UpdateNavigationContext(dict);

            var nav = GetService<INavigationService>();
            nav.Navigate("/Views/MessageView.xaml");
and then on the MessageViewModel
public MessageViewModel()
        {
            string inventoryNumber;
            NavigationContext.TryGetValue("InventoryNumber", out inventoryNumber);
            InventoryNumber = inventoryNumber;
        }
doesn't work :(
Coordinator
Aug 13, 2013 at 7:04 AM
To navigate away:
            var parameters = new Dictionary<string, object>();
            parameters.Add("ShoppingListIndex", ShoppingLists.IndexOf(SelectedShoppingList));

            var navigationService = GetService<INavigationService>();
            navigationService.Navigate<ShoppingListViewModel>(parameters);
To read navigation parameters:
    protected override void OnNavigationCompleted()
    {
        if (NavigationContext.ContainsKey("ShoppingListIndex"))
        {
            int.TryParse(NavigationContext["ShoppingListIndex"], out _shoppingListIndex);
        }
Coordinator
Aug 13, 2013 at 7:43 AM
Aug 13, 2013 at 9:19 AM
Wow Nice! Thank you.

MainViewModel
var dict = new Dictionary<string, object>
            {
                {"InventoryNumber", InventoryNumber},
                {"SerialNumber", Computer.SerialNumber}
            };
var nav = GetService<INavigationService>();
            nav.Navigate<DetailsViewModel>(dict);
DetailsViewModel
protected override void OnNavigationCompleted()
        {
            base.OnNavigationCompleted();

            if (NavigationContext.ContainsKey("InventoryNumber"))
            {
                string inventoryNumber;
                NavigationContext.TryGetValue("InventoryNumber", out inventoryNumber);
                InventoryNumber = inventoryNumber;
            }
            if (NavigationContext.ContainsKey("SerialNumber"))
            {
                string serialNumber;
                NavigationContext.TryGetValue("SerialNumber", out serialNumber);
                SerialNumber = serialNumber;
            }
        }