问题
I have been tasked with a new project. I am familiar with WPF and mvvm and have completed a few in production projects utilizing it.
This latest request is simple – but requires sharing an incoming datasource (that is refreshed every 30 seconds) between two views. Here are a few of the ways I have thought of achieving this:
1) Create one shared view model between the two views. I don’t really like this option – while they do use the same data source, what the two views do with the data is quite different.
2) Create two view models where one of them is the “parent” view model and one is the child. The child view model registers for a message from the parent. The parent view model sends that message. While this one would be the easiest to get up and running – I feel like there would be a lot of code revolving around the state of the application (was it just loaded? Is it already loaded and this is a data refresh?).
Ideally, what I would like is some sort of broadcast pattern, where the data is retrieved and broadcast – each viewmodel is created and then grabs the broadcasted message (via some type of messenger). Then on subsequent updates, the messenger lets the viewmodels know an update is coming.
I’ve looked at the mediator pattern (using messaging) but this doesn’t quite meet what I need. I don’t want to create the viewmodels in order to register for a message.
I am aware that there probably isn’t some “silver bullet” solution. Just looking for ideas on the best way to approach this.
回答1:
Use Inversion Of Control (IOC) and the Service Locator pattern to create a shared data service they both talk too. I notice your mvvm-light tag; I know a default Mvvm-light project uses a ViewModelLocator class and SimpleIOC so you can register a data service like below.
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<IDataService, DataService>();
}
}
An interface is used so we can swap out the DataService at will and even have a different one for design time. So you will create an interface that defines methods you will use and just make sure your DataService implements them. It is in your DataService implementation you will use the shared context / source.
public class DataService: IDataService
{
//USE SAME SOURCE (example EF)
private SharedSourceEntities context;
(blah blah)...
}
After you can inject it into both view models either in the constructor or calling the service locator.
Dependency Injection:
public class ViewModelOne: ViewModelBase
{
private readonly IDataService dataService;
public ViewModelOne(IDataService dataService)
{
this.dataService = dataService;
}
}
public class ViewModelTwo: ViewModelBase
{
private readonly IDataService dataService;
public ViewModelTwo(IDataService dataService)
{
this.dataService = dataService;
}
}
Service location:
SimpleIoc.Default.GetInstance<IDataService>();
来源:https://stackoverflow.com/questions/19962926/wpf-mvvm-shared-data-source