ViewModel将其自身注入其子ViewModel是否正确?

时间:2009-06-23 07:39:14

标签: wpf mvvm application-design

我创建了一个MVVM test application,它在运行时读取XML文件以动态创建菜单,并根据用户选择的内容,动态加载该页面的UserControl 。结果是一个不错的MVVM模式,允许您在XML文件中定义每页一个View / ViewModel对。很好。

所以现在我只是为开发人员添加了在一个页面上创建一个转到另一个页面的按钮的功能。我这样做的方法是在MainViewModel中我在ObservableCollection中构建ViewModel的集合,当我构建每个时,我 将MainViewModel本身(this)注入到每个UserControl-ViewModel的构造函数中。这样每个UserControl都包含MainViewModel,以便开发人员可以通过MainViewModel操作应用程序(例如调用SwitchPage(idCode))。

我需要保存的任何全局状态我可以保存在每个UserControl都可以访问的MainViewModel中。

此外,每个UserControl(PageItem)都具有对每个其他UserControls 的完全访问权限,这使我基本上可以从任何UserControl控制应用程序中的任何内容,这是我一直试图在MVVM应用程序很长一段时间。

所以我的问题是:这种ViewModel注入是一种有用的/已知的模式,还是将ViewModel注入其子ViewModel有问题?这似乎是递归的,但似乎工作正常,给我到目前为止我想要的功能。根据我从复合应用程序库架构中学到的东西,这似乎与那里发生的类似,例如在下面的代码中,我可以根据需要将其他应用程序对象注入我的ViewModel中。

public MainViewModel()
{

    PageItems pageItems = PageItems.Create("all");

    foreach (PageItem pageItem in pageItems.Collection)
    {
        string assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
        string viewModelName = assemblyName + ".ViewModels.PageItem" + StringHelpers.ForcePascalNotation(pageItem.IdCode) + "ViewModel";
        var type = Type.GetType(viewModelName);
        var viewModel = Activator.CreateInstance(type, this, pageItem) as ViewModelPageItemBase;
        AllPageItemViewModels.Add(viewModel);
    }

    CurrentPageItemViewModelIndex = 0;
    LoadCurrentPageItemViewModel();
}

1 个答案:

答案 0 :(得分:6)

我不认为这是错误或正确的,而是更多关于你的设计是如何耦合的。我通常从您提到的方法(子VM引用父VM)开始,然后解耦,如果我发现它太笨重。您的第一选择不一定是您的最后选择 - 您可以随着它的发展重构代码。

可能的替代方案是:

  • 子VM引发父侦听的事件(观察者模式)。父母亲非常了解孩子,但孩子不认识父母。
  • 子VM在父级侦听的事件中心上发布事件(中介模式)。无论是孩子还是父母都没有彼此密切关注。他们只知道调解员。