This project has moved. For the latest updates, please go here.

Shared and NonShared ViewModel simultanously

Mar 28, 2011 at 7:36 PM
Edited Mar 28, 2011 at 7:42 PM

Hi,

For the current application we're designing/building, we need a construct that allows us:

- Share state between two views. (SharedViewModel, no issue with Jounce)

- Have each view separately have access to view specific state (NonSharedViewModel also currently possible)

 

But I'm afraid the combination (i.e. having a shared viewmodel and a non shared viewmodel at the same time) is currently not possible?

 

uml image of the wish

 

We probably have to resort to publishing 'sync' events between the nonshared view models?

 

Thanks for any insight.

Coordinator
Mar 28, 2011 at 7:41 PM

Shouldn't be a problem.

Just expose the model as shared, like this:

public class SharedViewModel : BaseViewModel
{
    public string SharedProperty { get; set; } //and INPC yada yada
}

public class NonSharedViewModel : BaseViewModel, IPartImportsSatisfiedNotification 
{
    // option 1 - just put Shared in the binding path
    public SharedViewModel Shared { get; set; } 

    // option 2 - pass through 
    private SharedViewModel _shared; 

    public string SharedProperty 
    {
         get { return _shared.SharedProperty; }
         set { 
                 _shared.SharedProperty = value; 
                 RaisePropertyChanged(()=>SharedProperty);
         }
     }

   public void OnImportsSatisfied()
   {
        _shared = Router.ResolveViewModel<SharedViewModel>();
        // or use Shared if you go with the first option
   }
    
}

Then you can simply resolve it. Don't route the shared view model, only route the non-shared one, but all of the non-shared instances will share the same shared one. I left out the exports/etc. but you should get the gist.

Mar 28, 2011 at 7:45 PM

Wow! That was quick, and I think that will do it!

Thanks a million!

Mar 28, 2011 at 9:24 PM
Edited Mar 28, 2011 at 9:26 PM

That almost works!

I must be overlooking something, but with the following construct, the views will find the 'wrong' view-model.

In this c# project you will see that both leftlensview and rightlensview are not routed to their nonshared viewmodels.

What am I missing?

(edit: the association to the sharedviewmodel comes from the nonshared viewmodels, not from the view. mistake in picture, not in project)

Coordinator
Mar 28, 2011 at 10:20 PM

For Jounce to work, Jounce has to spin up the view. In your example, you let XAML spin up the view and then try to export it. That won't work.

A better example would be to keep your lens view. Then, just do two derived views i.e. LeftView : LensUCView and rightview, and export those.

In the Wizard View Model, expose a LeftViewModel and a RightViewModel. In the view for the main wizard, use a contentcontrol with the JounceViewConverter and it will see the view models and spin up the correct view - just bind it to the view model properties. If you want them non-shared in the sense of each view having it's own version of the same view model, you can use the getnonsharedview and pass in the non-shared view model as needed.

Mar 29, 2011 at 12:18 PM
Edited Mar 29, 2011 at 1:50 PM

Ok, I already suspected that firing those views from XAML would be the cause of things not working as expected.

*EDIT*

I found a solution: Now I use Regions to get the WizardForm into the shell.

The wizard form viewmodel exposes the left and right lens view-models and like you said the viewconverter spins up the views.

Neat. Now we continue :)

*EDIT 2*

For those interested in what the solution looks like:

vs2010 solution