Sharing one ViewModel between different instances of the same View

Sep 16, 2010 at 10:29 AM
Edited Sep 16, 2010 at 10:37 AM

Hi.

I am trying to figure out what is the best way to get CM to bind views and models so that different instances of the same view is binded to the same instance of a view model

For example:

DetailsView(instance1) <--> DetailsViewModel(instance1)

DetailsView(instance2) <--> DetailsViewModel(instance1)

This might come in handy where a screen has to be duplicated in parts of the application.

I tried to fool around with the context idea, and it could be made to work but the hack is ugly. I would basically have to specify 2 view contexts that are copies of each other OR create the view I want duplicated and embed that view in another view.(That way you don't have code duplication) Then you would have to somehow know when to use the one context and when to use the other.

This seems all wrong to me.

What is the proper way of achieving this?

Sep 16, 2010 at 11:32 AM
Edited Sep 16, 2010 at 11:43 AM

Or, to rephrase the question.

Why does the ViewLocator first try to retrieve a cached view of the Viewmodel by using the IViewAware interface?

I cannot see why you would ever want this functionality. If the ViewModel was already bound to a view, why would you bind the ViewModel to the same view again?

If I take that caching call out of CM behaves like I expect it too, however this renders the IViewAware interface unusable as it only supports one view per model. 

Does this indicate a design flaw in my program?

Sep 16, 2010 at 1:05 PM
Edited Sep 16, 2010 at 1:09 PM

The default implementation of ViewLocator.LocateForModelType uses Context as a suffix to compose the view type name, but this convention could be changed.
You can use two different string as Context value, then simply tweak ViewLocator.LocateForModelType delegate to return whatever view you need for each context.

Doing so, you can leave the caching in place. BTW, the view is cached into the ViewModel mainly for these reasons:

  • it helps to speed up the binding in scenarios involving switch between a number of child VM, with just one of them visible at once (for example a scenario similar to the VS code panel);
  • it keeps the view state live even if the VM is not currently active in a Conductor (and thus not bound into any hosting element); if the view was disposed and recreated, only the view properties bound to VM's properties were guaranteed to be restored.
Coordinator
Sep 16, 2010 at 1:58 PM

I assume you are inheriting from Screen. If you aren't actually using Screen's capabilities, you can just inherit from PropertyChangedBase and no Views will be cached. If you want to continue using Screen, but turn off caching. You can override the AttachView and GetView methods and replace them with your own implementations....which do nothing.

Sep 16, 2010 at 2:51 PM

@marco: I see, thanks for that. Once you start digging into those things it becomes difficult to understand what is going on.

@EE:Makes sense, I will just overried IViewAware. It's so obvious, donno why I did not think of this before. Thanks.