I have a user control of list of Patients which I use in other Views. However when I choose one of the Patients, the selection is propagated to all the views containing an instance of the user control. How can I make each view instantiate a new instance of the user control for each view? I am using c#
问题:
回答1:
Guessing from what you stated, I'd assume that you returning a static instance of you PatientViewModel from you locator. To solve this make sure that when the property is called a new instance of the view model is generated.
Edit: Locator with different instantiation methods
public class ViewModelLocator
{
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
//if (ViewModelBase.IsInDesignModeStatic)
//{
// // Create design time view services and models
// SimpleIoc.Default.Register<IDataService, DesignDataService>();
//}
//else
//{
// // Create run time view services and models
// SimpleIoc.Default.Register<IDataService, DataService>();
//}
SimpleIoc.Default.Register<MainViewModel>();
}
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
public MainViewModel StaticMain
{
get
{
return _staticMain ?? (_staticMain = new MainViewModel());
}
}
private static MainViewModel _staticMain;
public MainViewModel NewMain
{
get
{
return new MainViewModel();
}
}
public MainViewModel NewIocMain
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>(Guid.NewGuid().ToString());
}
}
public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
The
Main
property uses Lauent'sSimpleIoc
container to create an instance. One of the properties of this container is, that it treats every type as singleton. Thus if you use this VM generation method you will share the VM throughout the views.The
StaticMain
property does much the same, but instead of using Laurent's container it holds a static instance of the VM which is also shared between the views.The
NewMain
property creates a new VM upon every call, therefore, the VM is not shared between the views.The
NewIocMain
property also creates a new VM upon every call and the VM is, therefore, not shared between the views. However, theSimpleIoc
container holds a reference to the instance created. It does not release this instance automatically and you have to callSimpleIoc.Default.Unregister(key)
with the key you used for creation (the Guid) to remove the instance from the container once you no longer need it.
Instead of using the SimpleIoc
you obviously can opt to use another IOC Container - such as Unity for example - that allows you greater control how your instances are created and how long they live. Barring this, I'd opt for the NewMain
approach given yor case.