Strange behavior of UserControl<T> even with CloseViewModelOnUnloaded set to 'False'

Developer
Dec 26, 2011 at 4:44 PM
Edited Dec 27, 2011 at 12:58 PM

I'm trying to reuse my views (UserControl<T>) with diferent viewmodel implementation.

Assume that I have a couple of readonly viewmodels that arrange or map it's internal person structure (eg: PersonInfo1Data, PersonInfo2Data) to another well known structure (eg: Person).

public abstract class PersonViewModelBase
{
   [Model]
   public Person Person { get ... set ...}

   [ViewModelToModel("Person")]
   public string FirstName { get ... set ...}
}

public PersonInfo1ViewModel : PersonViewModelBase
{
  public PersonInfo1ViewModel(PersonInfo1Data data)
  {
       this.Person = new Person(data.TheFirstName)
  }
}

pubilc PersonInfo2ViewModel : PersonViewModelBase
{
    public PersonInfo2ViewModel(PersonInfo1Data data)
    {
        this.Person = new Person(data.PersonFirstName)
     }
}

public class PersonView :  UserControl<PersonViewModelBase>
{
}

When I display the PersonView, at first, seting it's DataContext with an instance of PersonInfo2ViewModel (for example) works fine, but if the control is unloaded (eg: switch a Tab in a UI with a TabControl with multiples TabItem) then looks like the DataContext is missing or reconstructed or UI controls lose the bound with the ViewModel instance.

Symptom: No data are displayed on the UI controls, after the control is unloaded and reloaded back.  

I set the CloseViewModelOnUnloaded to false but it doesn't work.

Coordinator
Dec 27, 2011 at 7:48 PM

This is not supported. The issue is that based on the view model that belongs to the user control, the view model is created automatically. If the view model is of the right type (which is what you describe), it will not convert any datacontext into a view model because it already is a view model that is supported. However, the second time it needs to construct the viewmodel. This is not possible because PersonViewModelBase is probably abstract (should be) and thus cannot be created.

What I would do in such situations (which occur only very rarely) is to create a base view (PersonViewBase), and then create a separate view per view model type (why create separate view models, but not separate views, aren't view models the logic for a specific view?). It might not be the nicest solution, but if you want the nice stuff of automatic view model creation, you have no other choice.