在我的UWP应用程序中,我使用MVVM Light及其ViewModelLocator来获取ViewModels。
我的ViewModelLocator看起来是这样的,我将guid传递给GetInstance以获得唯一的VM。
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MyViewModel>();
}
public MyViewModel MyVM => ServiceLocator.Current.GetInstance<MyViewModel>(Guid.NewGuid().ToString());
}
我有一个用户控件,它需要有唯一的VM,因为我可以在我的应用程序中有多个这个用户控件的实例。以下是我如何获得ViewModel:
<UserControl x:Class="My.App.Controls"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding Path=MyVM, Source={StaticResource ViewModelLocator}}">
...
</UserControl>
这是获得唯一VM的正确方法吗?或者,即使我的用户控件不再使用,虚拟机仍然被缓存,没有被处理?
更新
所以看起来我的代码工作正常,我每次都会得到唯一的MyVM实例。
现在的问题是,注销/处置视图模型的正确方法是什么。
我可以用SimpleIoc.Default.Unregister(guid)
来实现,但在我目前的实现中,将Guid(用于创建VM)传递到我的用户控件不是很直接,所以我可以注销VM。
总的来说,如果我只是在ViewModelLocator中创建一个没有SimpleIoc的VM运行时,除了失去依赖注入之外,还有其他缺点吗?
public class ViewModelLocator
{
public MyViewModel MyVM => new MyViewModel();
}
我认为某些视图(窗口)必须使用UserControl。
控制该视图的ViewModel可以为UserControl生成所需的ViewModel。您可以将UserControl绑定到此"SubViewModel"属性,然后按照自己的意愿处理它们。
您可以向视图模型添加一个额外的属性,并在视图中调用一个自定义的移除方法来处理视图模型。
视图模型的修改getter如下所示:
public MyViewModel MyVM
{
get
{
String id = Guid.NewGuid().ToString();
var instance = SimpleIoc.Default.GetInstance<MyViewModel>(id);
instance.ID = id;
return instance;
}
}
处理视图模型定位器的方法如下所示:
public static void UnregisterMyVM(String id)
{
SimpleIoc.Default.Unregister<MyViewModel>(id);
}
在你看来,你必须监听关闭事件,并在那里调用注销方法:
public MyView()
{
InitializeComponent();
this.Closed += ((sender, arguments) =>
{
var viewModel = ((MyViewModel)this.DataContext);
viewModel.Dispose();
ViewModelLocator.UnregisterSourceCodeViewer(viewModel.ID);
this.DataContext = null;
});
}