[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);
}
}
这里有两个问题:
答案 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的对象。