如何在不使用WPF / MVVM中的依赖项解析器的情况下初始化嵌套的View(和ViewModel)

时间:2013-10-21 10:08:36

标签: wpf mvvm

我正在设计遵循MVVM模式的WPF应用程序。在一个UserControl中(实际上这种情况多次发生),因为它非常复杂,包括例如TabControl,我想将它们分成几个子UserControl 。例如,在“主”视图中,我们称之为MainUC,我有TabControl,其中有两个TabItem。由于TabItem实际上都包含许多UI元素,因此我设计了两个UserControl,SubUCA和SubUCB,因此MainUC的XAML如下所示:

<TabControl Name="mainUC" Grid.Row="0" >   
    <TabItem Header="Sub UC A" Name="SubUC1">
        <local:SubUCA />
    </TabItem>
    <TabItem Header="Sub UC B" Name="SubUC2">
        <local:SubUCB />
    </TabItem>
</TabControl > 

但现在我的问题是:我应该如何安排这些UserControl的ViewModel?我目前使用的一种方法是只有一个ViewModel类(称为MainUC_VM),并且MainUC的DataContext设置为此类实例(注意我没有使用依赖注入,所以我只创建一个实例在MainUC的代码隐藏中)。但是就这样,MainUC_VM类会变得非常复杂,就像MainUC一样。所以我也想把ViewModel分成几个类。例如,在MainUC_VM类中,我可以拥有这样的属性

public SubUCA_VM SubVM1 { get; set; }
public SubUCB_VM SubVM2 { get; set; }

但是,由于我没有使用依赖注入(因为我们的团队还没决定使用它),我如何才能使SubVM1和SubVM2分别成为SubUC1和SubUC2的DataContext?我无法在SubUCA和SubUCB的代码隐藏中实例化一个,因为它们与MainUC_VM中的属性成员不同。

我能想到的一些方法是:1)使SubUCA_VM和SubUCB_VM类单例化(这类似于依赖注入的相同行为,例如默认使用MEF),或2)使用EvengAggregator通知实例化对象。但在我看来,无论哪种方式似乎都会增加不必要的复杂性。为了使用MVVM,这是否意味着依赖注入几乎是必须的?有没有办法在不使用DI的情况下实现它?

1 个答案:

答案 0 :(得分:4)

您可以使用隐式数据模板将数据(VM)链接到视图。首先,在MainUC可用的资源字典中定义数据模板。这可以是用户控件本身,也可以是应用程序资源。这些数据模板指示WPF在需要呈现某种类型的数据时使用哪些控件。

<UserControl.Resources>
    <DataTemplate TargetType="{x:Type local:SubUCA_VM}">
       <local:SubUCA />
    </DataTemplate>
    <DataTemplate TargetType="{x:Type local:SubUCB_VM}">
       <local:SubUCB />
    </DataTemplate>
</UserControl.Resources>

然后将选项卡的内容绑定到子VM:

<TabControl Name="mainUC" Grid.Row="0" >   
    <TabItem Header="Sub UC A" Content="{Binding SubVM1}" />
    <TabItem Header="Sub UC B" Content="{Binding SubVM2}" />
</TabControl>

或者,您可以在主VM中拥有子VM的列表。每个子VM都应具有Title属性,因此选项卡控件可以将其用于标头。这样主VM可以动态构建UI。您仍然需要上面定义的数据模板。

<TabControl ItemsSource="{Binding Children}" DisplayMemberPath="Title" />