Suspending and resuming in childcontrols

Oct 24, 2013 at 8:39 AM
Hello Blaine and Damian,

I'm using several independent usercontrols within a mainpage and instantiate the VMs via
ViewModelLocator.AutoWireViewModel="True".
At least I have now strong dependencies between the mainpage and the childcontrols and it's VMs. This is nice according SoC.

But now I have the problem how to persist the state of the childcontrol while supsending, because the child control aren't part of the navigationframe, so that NavigateFromCurrentViewModel isn't called for the childVMs.

I don't want to call additional method within the mainpage/mainVM to avaoid dependencies to the childVMs.

The workaround is now to use a DataRepository like in your Hello World example.

But maybe you have an idea how I can use also properties with the RestorableState Attribute within ChildVMs which are instantiated by AutoWireViewModel.

Thanks
Editor
Oct 24, 2013 at 7:02 PM
Hi,

I think that in the AdventureWorks Shopper Reference Implementation there is a similar scenario to the one you are describing in the CheckouHubPage, which is composed of three other controls (each one with its own view model:) BillingAddress, ShippingAddress and PaymentMethod controls.

I believe it might be useful to check the approach used there as a starting point.

Thanks,

Damian Cherubini
http://blogs.southworks.net/dcherubini
Nov 4, 2013 at 10:03 AM
Hi Damian,

I haven't be notified that you have answered ;-)
Thank you for your answer.

I know the reference implementation very well.
The CheckoutHubPage has dependencies (via DataContext) to BillingAdress, ShippingAddress and PaymentMethod.
But if BillingAdress, ShippingAdress and PaymentMethod would be independent controls it wouldn't make sence to connect them in the 'parent' CheckoutHubPage.

The implementation of the AutoWireViewModel which is based on the Convention Over Configuration principle is in the PrismRT implementain only working for the 'main' pages not the controls. While the instantiation is working well, the persisting of the state doesn't.

At least the controls which are instantiated via AutoWireViewModel = true are similar to the regions of Prism 4 which is a really nice feature.
I've now implemented a workaround:
In the independent controls (for example independent hubsections on the HubPage) I’ve implemented a behavior (introduced again in Win 8.1):
    <Interactivity:Interaction.Behaviors>
        <Core:EventTriggerBehavior EventName="Unloaded">
            <helper1:InvokeCommand Command="{Binding UnloadCommand}" />
        </Core:EventTriggerBehavior>
    </Interactivity:Interaction.Behaviors>
When the control is unloaded the persisting functions are called and a clean up is done.

Btw. during the clean up the EventAggregator subscriptions has to be unsubsribed because there is still a bug in EventAggregator:
If you instantiate a control not via Singleton (ex ContainerControlledLifetimeManager) event subscription will always be done again and again.
But this is a very old memory problem of the EventAggregator which has never been fixed.

But thanks again. I'm still a fan of your team.
Editor
Nov 4, 2013 at 6:46 PM
Hi,

Thanks for sharing your workaround with the community as it might be useful for others pursuing the same scenario as you. The approach you used is interesting as it can be reused in any child control without requiring to couple it with its parent container.

As for the bug regarding the EventAggregator, there doesn't seem to be any work item describing it in the Issues section of this project. It could be useful if you could create one with your findings so that we can analyze it in further detail.

Thanks again,

Damian Cherubini
http://blogs.southworks.net/dcherubini
Nov 6, 2013 at 6:34 AM
Edited Nov 6, 2013 at 7:00 AM
Hi Damian,

an additonal remark:
The Loaded behavior
        <interactivity:Interaction.Behaviors>
              <core:EventTriggerBehavior EventName="Loaded">
                    <helper:InvokeCommand Command="{Binding LoadedCommand}" />
             </core:EventTriggerBehavior>
        </interactivity:Interaction.Behaviors>
is often also needed:
When you instantiate VMs via AutoWireViewModel you use the OnNavigationTo Event within the VM to do some setup like loading data etc.
But I've realized that often the View(control) is not loaded as fast as the ViewModel.
I've needed some days to find this problem, because View and ViewModel are instantiated synchron and sometimes the View is faster and sometimes the ViewModel. If the ViewModel is faster than you have a problem.
So the OnNavigationTo Event within the VM is called even if the View isn't still loaded. So the binding of properties loaded in the OnNavigationTo Event cannot work.

The workaroud is also here to use the Loaded behavior in the VM to do all setup loading/binding stuff.

Btw. I hope I will release my app which I've still mentioned in this forum 3 months ago
I'm just developing an application with Prism for Windows 8. Maybe it would make sense to develop still only for Windows 8.1.
(It's a kind of Lightswitch for Windows store apps, a model driven tool to develop and export VS Solutions based on MVVM Frameworks like Prism.)
within November. It's now a Win 8.1 app where I've implemented all these things and use HubSections like the old prism regions.

Update:
P.S: I've added an Issue
Coordinator
Dec 10, 2013 at 11:03 PM
Hello judgy,

Thanks for your detailed research. I haven't run into the situation where the View loads faster than the ViewModel. Usually my ViewModels' OnNavigatedTo methods are async and do work to load the data that populates the ViewModel. By the time the data is loaded and the INPC/INCC events fire, my Views are ready to receive the events.

Regarding communicating to child user controls, I like your method of using the user control's Loaded and Unloaded events to invoke commands exposed by the user control's ViewModel. The only potential problem I see is that the Unloaded event may happen considerably later than you would expect the page's OnNavigatedFrom to occur.

Please keep us updated on the status of your app.

Thanks again,
-Francis Cheung