我正在设计遵循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的情况下实现它?
答案 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" />