【问题标题】:Correct way of getting unique ViewModels from MVVM Light ViewModelLocator从 MVVM Light ViewModelLocator 获取唯一 ViewModel 的正确方法
【发布时间】:2016-09-08 05:50:09
【问题描述】:

在我的 UWP 应用中,我使用 MVVM Light 及其 ViewModelLocator 来获取 ViewModel。

我的 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 的正确方法吗?或者,即使不再使用我的用户控件,VM 是否仍处于缓存状态,未释放?

更新

看来我的代码工作正常,我每次都得到唯一的 MyVM 实例。

现在的问题是,取消注册/处置视图模型的正确方法是什么。

我可以使用 SimpleIoc.Default.Unregister(guid) 做到这一点,但在我当前的实现中,将 Guid(用于创建 VM)提供给我的用户控件并不是很直接,因此我可以取消注册 VM。

总体而言,如果我只是在没有 SimpleIoc 的情况下创建我的 VM 运行时 im ViewModelLocator,除了失去依赖注入之外还有其他缺点吗?

    public class ViewModelLocator
    {
        public MyViewModel MyVM => new MyViewModel();
    }

【问题讨论】:

  • 听起来您应该使用数据绑定而不是 ViewModelLocator。
  • 你能举一些简单的例子吗?
  • stackoverflow.com/questions/9362332/… 。请注意答案中的#4。如果您想清理 IOC 容器中的视图模型,请在符合您要求的情况下取消注册 OnNavigatedFrom。
  • 使用唯一的 VM 是否意味着每个 usercontrol 实例都有不同的实例?如果是这样,你写的方式是对的。
  • 更新了原始问题。所以基本上问题不在于如何正确注销虚拟机。

标签: c# mvvm win-universal-app viewmodel mvvm-light


【解决方案1】:

我假设某些视图(窗口)必须使用您的 UserControl。

控制该 View 的 ViewModel 可以为 UserControl 生成所需的 ViewModel。您可以将 UserControl 绑定到此“SubViewModel”属性,然后按照您的意愿处理它们。

【讨论】:

    【解决方案2】:

    您可以向您的视图模型添加一个附加属性,并在处理您的视图模型的视图中调用自定义删除方法。

    视图模型的修改后的 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;
            });
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-21
      • 2014-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-03
      相关资源
      最近更新 更多