从MVVM Light ViewModelLocator获取唯一ViewModel的正确方法

问题描述 投票:1回答:2

在我的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());
    }

我有usercontrol需要有唯一的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仍然被缓存,而不是被丢弃?

UPDATE

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

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

我可以用SimpleIoc.Default.Unregister(guid)来做,但是对于我目前的实现,将Guid(用于创建VM)用于我的用户控件并不是很直接,所以我可以取消注册VM。

总的来说,如果我只使用SimpleIoc创建我的VM运行时ViewModelLocator,除了丢失依赖注入之外还有其他缺点吗?

    public class ViewModelLocator
    {
        public MyViewModel MyVM => new MyViewModel();
    }
c# mvvm win-universal-app viewmodel mvvm-light
2个回答
0
投票

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

控制View的ViewModel可以为UserControl生成所需的ViewModel。你可以将UserControl绑定到这个'SubViewModel'属性,也可以处理它们,但是你希望如此。


0
投票

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

视图模型的修改后的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;
        });
    }
© www.soinside.com 2019 - 2024. All rights reserved.