【问题标题】:How to handle multiple ViewModels with MVVM Light ViewModelLocator如何使用 MVVM Light ViewModelLocator 处理多个 ViewModel
【发布时间】:2015-11-03 14:23:14
【问题描述】:

使用 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 视图中访问 ViewModel:

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

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

【问题讨论】:

  • 注销是什么意思。您是要清除 Messenger 实例还是调用 iDispose / iCleanup。请说明您要完成的任务。 viewmodel 定位器有助于注册 VM 并协助进行依赖注入。
  • @JKing 谢谢。请检查我编辑的帖子。

标签: c# wpf mvvm mvvm-light


【解决方案1】:

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

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

如果您“关闭”您的视图/窗口/用户控件,则视图模型仍然存在。这可能是一个好处,因为它允许您保持 VM 的“状态”,以便在您再次打开视图时保留数据等。您必须想办法刷新您拥有的任何记录集。

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

SimpleIoc.Default.Unregister(AdministratorViewModel);

但是,如果您这样做,则必须先注册它才能再次使用它。那么你为什么要这样做,是为了清理内存吗?大多数 VM 都是单例的,并且在应用程序的整个生命周期中都存在它们是正常的。

您关于 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

【讨论】:

  • 非常感谢!我现在明白了,是的,我的应用程序有点乱。感谢您的宝贵时间和出色的回答。注册
猜你喜欢
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 2014-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多