Persisting Navigation and Handling state values

Topics: MVVM library
Feb 18, 2013 at 9:56 AM
I found the framework really promising and i like it very much, But still i am having some doubts regarding
  1. Persisting Navigation : How i can persist my Views after coming from terminate state,ie Navigate from A->B . Terminate the App. again launch restore the page from where we navigate.
  2. Handling state values : How we will handle page states by using this architecture.
Feb 18, 2013 at 1:04 PM
I am also having the same issue. How we can persist navigation and and state values during termination? Is there any method available in your project? Give me an update? I just start developing an app using your application.
Feb 18, 2013 at 1:10 PM
Please update this feature. Along with How i can attach SimpleIOC container along with VM Creation. I think the area where you are creating viewmodels are seems to be pretty ordinary. If youadd some more restructuring toward navigation and pulling VM, the structure will be great in all seance. Anyways thanks for the effort made.
Coordinator
Feb 18, 2013 at 3:41 PM
Edited Feb 19, 2013 at 2:28 AM
Good question. I'm sorry I've modified the headline to make it more constructive.

I hope this could be helpful:
  • Save your view model state in IPageModel.OnNavigating implementation and in Application.Suspending event handler. See also NavigationState.GetNavigationState/SetNavigationState methods.
  • You can load your view model state at several points:
    • PageModel.OnNavigated,
    • during the RootModel initialization,
    • during the RootModel creation in App class,
    • you can also make RootModel properties lazy and load view state there.
For completely dynamic cases you can implement ICustomPropertyProvider in e.g. RootModel. So you will be able to provide a dynamic set of views at runtime.
We do not have a dependency injection support out-of-the-box yet. But I do not see any problems here.

I really appreciate your feedback.
Feb 19, 2013 at 10:33 AM
Edited Feb 19, 2013 at 12:59 PM
I some how reached persisting Navigation. But got stuck with state handling.


this is how i persist the Navigation
  saving...

    private async void OnSuspending(object sender, SuspendingEventArgs e)
    {
        var deferral = e.SuspendingOperation.GetDeferral();
        var navigationState = RootModel .NavigationState.GetNavigationState();
        await navigationState.SerializeAsXml("NavigationStack");
        deferral.Complete();
    }

    Restoring.....

        RootModel = new RootModel ();

        var frame = new Frame { DataContext = RootModel };
        ElementBinder.SetWrapper(frame, RootModel .NavigationState);
        Window.Current.Content = frame;
        Window.Current.Activate();
        RootModel .NavigateToMainView();

        if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
        {
            var res = await XmlSerialization.LoadFromXmlFile<string>("NavigationStack");
            RootModel .NavigationState.SetNavigationState(res);
        }
I am not sure about the convention and quality of code, You please verify and update your comment. But the state handling still seems to be a hard nut to crack. Can you please help me to implement the same with the help of some code samples.
Coordinator
Feb 19, 2013 at 3:26 PM
Try this:
public class MyPageModel : PageModel
{
        private bool _isStateLoaded;

        public override async void OnNavigated()
        {
            base.OnNavigated();

            await LoadState();

            Application.Current.Suspending += OnSuspending;
        }

        public override void OnNavigating(ref bool cancel)
        {
            base.OnNavigating(ref cancel);

            if (!cancel)
            {
                Application.Current.Suspending -= OnSuspending;
                SaveState().ContinueWith(task =>
                {
                    if(task.Exception != null)
                        Debug.WriteLine(task.Exception);
                });
            }
        }

        private async void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();
            await SaveState();
            deferral.Complete();
        }

        private async Task SaveState()
        {
            // Save your state here.
        }

        private async Task LoadState()
        {
            if(_isStateLoaded)
                return;
            
            // Load your state here.

            _isStateLoaded = true;
        }
}
Feb 22, 2013 at 5:55 AM
@Stez : The method you following is not completely right. If you follow this method you will get your view persisted. But after coming from the terminated state you will not get any page state events get fired on your implementation. So if you need to load any web request or db hit you cannot make the call.

@mglukhankov : The implementation you mentioned above seems to be pretty ordinary. If you make the change inside of pagemodel / viewmodel (base claas). We can make use of the page events for all the views. Also state handling can handled based on the current active frame. But as per you suggestion we need to register suspending events in all views so the code is duplicating and we need to write the state handling code (serialization / deserialization) method in all pages. I don't think it would be a better method to suggest.

About dynamic class creation:

If you are creating all the objects for viewmodel in the Bootstrap class (say in your RootModel) what is the advantage, In my point of view if you create an on demand view model creation that would be more wired for your project template. Otherwise why can't you make your viewmodel static.
Feb 22, 2013 at 1:22 PM
@rkshnair : Yes you are right, now only i noticed the issue. How i can fix this issue in my application. I also noticed your suggestions, Now i feel really afraid? Do i face any issue while using this template. Now my 50% of development is completed. Is it possible to migrate my project to any other framework without affecting my structure. Can you please suggest some UI design architectures that is stable for design. I am really new to this field and i am confused with mvvm. The issue is that my client is sticking with MVVM structure. Otherwise i opt writing code behind.
Coordinator
Feb 22, 2013 at 1:55 PM
Edited Feb 22, 2013 at 5:50 PM
I've implemented a fix.
You can download the recommended download (1.0.0.5) and change the reference to the assembly.
NuGet package and VS project template will be updated soon.
Developer
Feb 22, 2013 at 4:57 PM
I've updated NuGet package
Coordinator
Feb 24, 2013 at 3:42 PM
@rkshnair : You do not have to duplicate a code. There are plenty of programming techniques to avoid a code duplication. But this is a good feature to have. We probably will address this in next releases.
About dynamic class creation: of course you can make your view models static (they are already static in the template), but you asked about SimpleIOC container and I provided you with some choices.