ContentControl and ViewModel creation


Reproduction sample for the following discussion:


To see the behavior:
  1. Put breakpoint in constructor of both BarViewModel and FooViewModel
  2. Run the sample
  3. Press the "Show Foo" button, FooViewModel is constructed and FooView is displayed
  4. Press the "Show Bar" button, BarViewModel is constructed, then a FooViewModel is contructed and then BarView is displayed.
Why is a FooViewModel constructed at step 4 and how can it be prevented from happening.

file attachments

Closed Jun 18, 2013 at 12:47 PM by GeertvanHorrik


GeertvanHorrik wrote Apr 15, 2013 at 4:13 PM

I can reproduce the issue. I will look into this. Thanks for this great example.

GeertvanHorrik wrote Apr 15, 2013 at 4:21 PM

Ok, I found the issue. I am not saying you are using Catel in the wrong way, but let's just say you are not using Catel as intended. Let me try to explain what happens in words.

You first go from a null VM instance to an instance. This is ok, everything works as expected. Then you change the VM to a new instance of another type. What happens is that Catel notices the DataContext change. It then checks the VM of the view (which is FooView for example) and checks if the new DataContext fits in that view. It does this by checking:

A) Is it ia FooViewModel => use it
B) Try to construct the FooViewModel using the DataContext injection

Since the FooViewModel does not require any injection (empty constructor), it can create the new vm immediately. Then the FooView gets unloaded and the new view (BarView) kicks in and create it's own VM. But, it can use check A because it is the same viewmodel as the view expects => thus uses it.

GeertvanHorrik wrote Apr 15, 2013 at 4:28 PM

Attached is a customized example which shows how Catel is intended to be used. I hope this gives some insight how to best use Catel.

noeanton wrote Aug 1, 2013 at 2:01 AM

This is pretty good, however it looks like it does not save the state of the content of the viewmodel, say for example I have a User control that has a view model as a datacontext, and I have a grid that displays some content based on some search done by the user. if I use this approach, load another user control, then come back, the grid will be empty and user will probably want to see the state of the View saved somehow. Is there a way that catel saves its properties and bindings somehow?

GeertvanHorrik wrote Aug 1, 2013 at 10:04 AM

No, you will have to take care of persistence yourself. You can also use the CloseViewModelOnUnloaded = false, but then you are in control for correctly closing the view model.