如何使用MVVM Light ViewModelLocator处理多个ViewModel

本文关键字:ViewModel 处理 ViewModelLocator 何使用 MVVM Light | 更新日期: 2023-09-27 18:20:26

使用MVVMLight ViewModelLocator时,如何在应用程序中注册和注销多个ViewModel?

问题是,我希望能够告诉应用程序哪个ViewModel应该注册,哪个应该注销。我的应用程序中有14个ViewModel(其中很少有像SessionViewModel那样在后台工作,它确定所有视图的当前会话状态)

编辑

我的ViewModelLocator:的一部分

public New()
{
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
    SimpleIoc.Default.Register<AdministratorViewModel>();
    SimpleIoc.Default.Register<CallViewModel>();
    SimpleIoc.Default.Register<EmployeeViewModel>();
    SimpleIoc.Default.Register<LoginViewModel>();
    SimpleIoc.Default.Register<MessengerViewModel>();
    SimpleIoc.Default.Register<QualityViewModel>();
}

为了能够从我使用过的XAML中的视图访问ViewModels:

DataContext="{Binding Source={StaticResource Locator}}"

LoginViewModel应可用于所有视图。举个例子:Employee View将只使用CallViewModelEmployeeViewModelMessengerViewModel,所以我不需要Employee ViewAdministratorViewModelQualityViewModel。那么,如何为员工视图仅注册所需的ViewModel?

如何使用MVVM Light ViewModelLocator处理多个ViewModel

我认为您需要花一些时间来明确规划您的应用程序目标。

这些寄存器函数是在视图模型定位器构建/应用程序加载期间调用的。在创建资源之前,它们不会消耗资源——当视图绑定到视图模型时就会发生这种情况。因此,其他未"开放"的视图模型还不存在。

如果"关闭"视图/窗口/用户控件,则视图模型仍然存在。这可能是一个好处,因为它允许您保留VM的"状态",这样当您再次打开视图时,数据等就会被保留。你必须想办法刷新你所有的记录集。

您可以使用视图模型的注销功能,它将从缓存中删除:

SimpleIoc.Default.Unregister(AdministratorViewModel);

但如果你这样做,你必须先注册它,然后才能再次使用。那么,你为什么要这样做,是为了清理记忆吗?大多数虚拟机都是单体的,在应用程序的整个生命周期中都存在它们是正常的。

您关于LoginViewModle应可用于所有视图的声明引发了警报。视图模型应该包含"工作单元",虚拟机不应该真正与其他虚拟机通信(但也有一些例外——因此mvvmLight中的信使函数)。您是否考虑过使用服务来保存每个视图模型所需的功能/业务逻辑。SImpleIOC的依赖项注入就是为了实现这一点。我有一个UserService,可以让用户登录并跟踪用户的设置和权限。然后,这个服务被注入到每个需要它的VM的构造函数中。例如:

public interface IUserService
{
    employee LoggedEmployee { get; set; }
    List<int> UserRoles { get; set; }
    bool LoggedIn { get; set; }
    void UpdatePassword(int idEmployee, string password);
    ...
}
Public Class UserService :  IUserService
{
    Public void UpdatePassword(int idEmployee, String password) {   }
        }

您定义了一个服务,然后实现它(这允许进行测试),但随后您可以将它注入到WM构造函数中:

Public Class AdministratorViewModel
{
    Private IUserService _UserService;
    Public New(IUserService UserService)
    {
        Try {
            _UserService = UserService;
        } catch (Exception ex) {
        }
    }
}

因为这个用户服务是一个单例,所以注入它的所有视图模型都可以访问它的函数和数据,这就保持了应用程序关注点的分离。

希望这能帮助你确保你正朝着正确的方向前进

JK