Fred My Fred My - 20 days ago 5
C# Question

Two ViewModels are using one Model which holds data

I've searched for almost 3 hours and found alot about PRISM and VM data sharing, but I can't get my brain to understand it.

I have the two ViewModels MainViewModel and ListViewModel. The MainViewModel has a dockpanel where I want to have a common menu to add, remove items and close the application for example. There is also a usercontrol in the XAML which is showing the ListView. The ListView contains a few

ObservableCollection<ProjectModel>
.

From the MainVM I want to add more Projects - so to a collection. To access the ListModel, which contains the data, I pass it to the constructor of both ViewModels:

public MainModuleViewModel(ListModel listModel)
{
ListModel = listModel;
InitializeCommands();
}

public ListModuleViewModel(ListModel listModel)
{
ListModel = listModel;
InitializeCommands();
}


But it seems that during initializaiton to different objects of ListModel are created.

So my question is: What do I have to do, to work just on the one object of ListModel, which I'm passing to the constructors?

Answer

You have two options, as always:

  • register the ListModel as singleton (ContainerControlledLifetimeManager in Unity)
  • or register a service as singleton that gives the data to the view model

I'd go with the second one as it's far more flexible - you can use a different ListModel instance elsewhere with different content, you can make the service to give each view model its own instance (though with the same content) or you can make it give each view model the same instance and so on...

public interface IDatasource
{
    ListModel Data { get; }
}

internal class StephensService : IDatasource
{
    ListModel Data { get; } = new ListModel(); // or however you plan to procure the data
}

// ... bootstrapper / module initialization ...

Container.RegisterType<IDatasource, StephensService>( new ContainerControllerLifetimeManager() );

// ...

internal class ListModuleViewModel
{
    public ListModuleViewModel( IDatasource datasource )
    {
         var heresMyData = datasource.Data;
    }
}

Depending on your needs, the service can implement INotifyPropertyChanged or the ListModel can be an ObservableCollection...