如何在不破坏MVVM的情况下导入ViewModel?

时间:2011-10-10 13:30:13

标签: c# wpf mvvm prism mef

[Export]
public sealed class MainViewModel : NotificationObject
{
    [Import]
    public ISomeService MyService { get; private set; }

    ...
}

为了将此类作为DataContext注入到我的View中,我必须将其标记为Export,以便MEF在Catalog中创建它的实例。问题是主窗口需要创建其他窗口并传递命令,我不知道如何在不破坏MVVM方法的情况下解决这个问题。

我认为ICommand会在我的MainViewModel上触发一些东西来生成一个新的ViewModel,但在那之后我无法强制从ViewModel强制打开一个新的Window(视图)。另外,我甚至无法从我的MainViewModel真正创建一个新的ViewModel,因为MEF不会真正起作用,对吗?

[Export]
public sealed class MainViewModel : NotificationObject
{
    [Import]
    public ISomeService MyService { get; private set; }

    private ObservableCollection<IOrderViewModel> Orders { get; set; }

    public void OpenOrder(int id)
    {
        //Pseudo-code to ensure that duplicate orders are not opened)

        //Else create/open the new order
        var order = new OrderViewModel(id);

        OpenOrders.Add(order);
    }
}

这里有两个问题:

  1. 由于我“newed”,OrderViewModel服务不会通过MEF自动加载。
  2. 我的ViewModel图层(适当的图层)上的代码如何创建必要的视图作为NEW WINDOW(主窗口的子窗口),然后将这个新的OrderViewModel链接为DataContext?

2 个答案:

答案 0 :(得分:2)

避免'新建'OrderViewModel的方法是使用工厂:

[Export]
public class OrderViewModelFactory
{
    [Import]
    public ISomeDependency ImportedDependency { get; set; }

    public OrderViewModel Create(int id)
    {
        return new OrderViewModel(id, this.ImportedDependency);
    }
}

然后将工厂导入您的MainViewModel作为依赖项,MEF将根据需要填写所有内容。

为了解决实例化窗口的问题,我们创建了一个DialogService来执行以下操作:

[Export]
public class DialogService
{
    public bool? ShowDialog(string regionName, object data = null)
    {
        var window = new Window();
        var presenter = new ContentControl();
        presenter.SetProperty(RegionManager.RegionName, regionName);
        window.Content = presenter;
        if (data != null) window.DataContext = data;
        return window.ShowDialog();
    }
}

答案 1 :(得分:1)

我使用的一种技术是我称之为导航服务。请注意,这与WPF内置的导航框架不同。您的viewmodel可以直接注入实例,也可以使用EventAggregator模式触发导航请求然后由导航服务处理。直接注入导航服务意味着它可以注入其他对象,如ViewModelFactories。无论你如何做,在某些时候你将不得不拥有一个知道如何创建容器正确解析的viewmodel的对象。