0

我正在使用 MEF 和名为MEFedMVVM的第三方库编写 WPF 应用程序。

我正在尝试创建一个设计,其中父视图模型具有一组子视图模型,并且我希望使用视图模型优先的方法,因为这将视图保持在视图模型之外,从而使代码保持更多视图模型-中心化且更可单元测试。

我已经阅读了这个讨论和关于使用 DataTemplate 作为视图的讨论,以及 Reed Copsy, Jr 的建议即使用通用视图来查看模型映射资源。但是,我正在努力实现一些有效的东西。

我的父视图很简单:

<UserControl x:Class="MyParentView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:meffed="clr-namespace:MEFedMVVM.ViewModelLocator;assembly=MEFedMVVM.WPF"
             meffed:ViewModelLocator.ViewModel="MyParentViewModel" />

父视图模型派生自实现IContextAware的基本类型:

[ExportViewModel("MyParentViewModel")]
public class MyParentViewModel : ViewModelBase
{
    [ImportingConstructor]
    public MyParentViewModel()
    {
        var myChildVM = ServiceLocator.Current.GetInstance<MyChildViewModel>());
    }
}

这是子视图模型:

[Export(typeof(MyChildViewModel))]
[ExportViewModel("MyChildViewModel", true)]
public class MyChildViewModel : ViewModelBase
{
}

而这有对应的看法:

<UserControl x:Class="MyChildView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:meffed="clr-namespace:MEFedMVVM.ViewModelLocator;assembly=MEFedMVVM.WPF"
             meffed:ViewModelLocator.ViewModel="MyChildViewModel" />

最初,我认为在 MyChildViewModel 的 ExportViewModel 属性上指定第二个布尔参数将使一切工作使用视图模型优先的方法,因为我的视图和视图模型在视图的 XAML 代码中被 MEFed 在一起。但是,事实证明并非如此,当我在MyParentViewModel构造函数中实例化MyChildViewModel对象时,实际上传递给IContextAware.InjectContext()的是MyParentView对象。不是我期待和希望的MyChildView对象。显然,我需要添加一些东西来将它们连接在一起。谁能提供一个如何做到这一点的例子?

谢谢!

4

1 回答 1

4

当您真的想首先使用视图模型时,您应该这样做:

[ExportViewModel("MyParentViewModel")]
public class MyParentViewModel : ViewModelBase
{
    // Create property for your child vm
    public MyChildViewModel Child {get; private set}

    // If you do MEF use constructor injection instead of servicelocator
    [ImportingConstructor]
    public MyParentViewModel(MyChildViewModel child)
    {
        this.Child = child;
    }
 }

然后为您的 childvm 定义一个数据模板

 <DataTemplate DataType="{x:Type local:MyChildViewModel}">
     <view:MyChildViewUserControl />
 </DataTemplate>

在您的 MainView 中,您知道要在哪里显示子数据,否则您将不需要子属性;)所以只需将 ContentControl 放在子数据应该去的位置并绑定到您的属性。

例如

<TabControl>
   <TabItem Header="MyChildData">
      <ContentControl Content="{Binding Child}" />
   </TabItem>
</TabControl>

PS:代码是在没有 IDE 的情况下编写的,所以可能会出错 :)

于 2012-04-30T05:58:40.240 回答