This project is read-only.

ViewModel state and navigation

Oct 21, 2010 at 2:27 PM

Good morning Rishi,

Again thanks for the very cool library and samples. Ive read the documentation and some things are still a little unclear. How can I know when I navigate away from a container to a different place that the OnSaveState will be called on my viewmodel? Reason I ask is I have some views( actually the Viewmodel pointed to by the view) that I want to keep their state, so when the user navigates back that they see the view in the state they left it in. Can you lend a little more help here? It seems to me unclear when OnSaveState is called. Again what I want is to be able to navigate away from something and then come back to it showing the state it was left in.

thanks!

Justin

Oct 22, 2010 at 10:19 PM

Hi,

If your ViewModel implements NavigationViewModelBase, you will have a 3 methods to deal with:

1.  protected override void OnIntialize(ParametersCollection state)

Which will initialize your ViewModel with the given state (if the state is null, then the ViewModel is restoring)

2. protected override void OnRestoreState(ParametersCollection state)

This will be called, when your ViewModel is restored, given back the collection, than you passed in the following method.

3. protected override ParametersCollection OnSaveState() 

This is called, when your ViewModel is navigated from page (or other reasons) where you need to return collection. Now, you can stuff in there anything that you need to be able to use this in ( OnIntialize / OnRestoreState) to be able to recover the initial look.

 

Oct 23, 2010 at 12:42 PM

Hi guys,

I'll just add to the above answers, the SaveState functionality comes from and interface called ISupportNavigationState - which looks like:

 

    public interface ISupportNavigationState
    {
        void RestoreState(ParametersCollection state);
        ParametersCollection SaveState();
    }

 

And it works as described above, however I'll point out that:

1. You don't need to use the NavigationViewModelBase class, you can implement this interface yourself
2. You could alternatively implement this in your View, and it would just as well - not that I advocate that, but it's an option
3. And importantly even if you implement this interface, the navigation container must also support its use - some containers don't e.g. NavigationContentControl. Navigation by itself only requires the container to implement INavigationHandler interface, anything beyond that is the container's own call. 

Secondly, one other companion interface that most containers support is ISupportNavigationLifecycle, and it looks like:

 

    public interface ISupportNavigationLifecycle
    {
        string Title { get; }

        void Closing(Action<bool> confirmCallback);
        void Initialize(ParametersCollection requestParameters);
    }

As you can tell, it supports an initialize - which gets all the passed-in (and parsed) parameters. To correct SonicFlare, this is always called even whilst restoring, though null doesn't necessarily indicate that the state is being restored. Normally, the closing is called when a navigation-request comes in, and it expects your reply (it asynchronously waits for it). And lastly, the Title property can be used to provide a title for the content in the navigation container. Like with the state related interface, the use of lifecycle interface is also optional, you can also provide your own implementation in the View or ViewModel as you choose. Furthermore, the container must support the use of ISupportNavigationLifecycle - which like before is not mandatory.

Hope this helps,
Rishi 

 

Oct 24, 2010 at 5:48 AM

Thanks for all the great responses! I think I didnt make it clear one thing that isnt clear to me though which is what forces my OnSaveState to be called? Its not called every time i navigate away from this one particular viewmodel which im talking about? Where or what is the criteria for navigating away that forces OnSaveState to be called?

Oct 24, 2010 at 2:24 PM

@ftballguy45 well, if the navigation container supports stateful navigation (like the BrowsingContainer or StatefulContainer etc) then it should be called every time - except when you refresh. 

Cheers, 
Rishi 

Oct 24, 2010 at 10:34 PM

Rishi im using a StatefulContainer as my navigation container yet OnSaveState is not called when i go other places, leaving this container?

Oct 24, 2010 at 10:59 PM
Edited Oct 26, 2010 at 4:28 AM

I figured out what is going on - kind of. Due to the nesting of viewmodels/containers, the outer container didnt have a backing viewmodel, it was just a plain usercontrol that contained the viewmodel in question. So i guess the question now is, how do we save and restore state of nested viewmodel/containers? OnSaveState is never called on the nested one, only on the outer container (now that ive put an actual viewmodel behind it, not just a plain usercontrol).

Furthermore I would like to let the framework handle this, but I dont know why its not picking up when I navigate away from the nested container, (it calls OnSaveState on the outer, but not the inner)

Oct 26, 2010 at 11:19 AM

Excellent question - one that I've been thinking about about how to handle, especially with WP7. Now, the idea that I have is to enable some sort of parent-hood for containers, so that child navigation-containers can attach to the parent container to enable cascaded management of state. However, I've not come up with any API as such, but if you have any suggestions/ideas pls share.

Cheers,
Rishi