我有一个带有左右停靠面板的WPF表单。左侧面板有一些用户输入,我根据这些输入创建并在右侧停靠面板中启动不同的用户控件。我们正在使用MMVM框架。目前,我们正在从表单的View Model创建和启动用户控件。我不确定这是否正确,因为它似乎违反了VM的MVVM规则不应该访问View。那是对的吗?有没有我可以使用的替代设计(我想我也不能在代码隐藏中写任何东西,对吗?)。
答案 0 :(得分:1)
不,您不应该在ViewModel中拥有任何View特定代码。如果纯粹是UI(没有业务逻辑),那么可以具有代码隐藏功能。
MVVM WPF Apps With The Model-View-ViewModel Design Pattern上的MSDN上有一篇很棒的文章。我建议你在使用MVVM模式编写任何WPF应用程序之前阅读本文。
对于您的特定情况,我会在右侧面板中设置ContentControl
,并将ViewModel
分开以支持不同的UserControl
,然后将DataTemplates
定义为为任何给定的UserControl
显示正确的ViewModel
。
未经测试的伪代码:
<强>的DataTemplates 强>
<DataTemplate DataType="{x:Type local:ViewModel1}">
<local:UserControl1 />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModel2}">
<local:UserControl2 />
</DataTemplate>
您可以在Window.Resources
部分或ResourceDictionary
中定义这些内容,并在Window.Resources
<强> ContentControl中强>
<ContentControl Content="{Binding CurrentContent}" />
在支持MainWindow的当前ViewModel中,您将拥有一个名为CurrentContent
的属性,当您将其设置为正确的ViewModel实例时,屏幕上将显示相应的View/UserControl
TabControl
<强>更新强>
您将在ViewModel而不是CurrentContent中拥有ContentControl
而不是ObservableCollection
并拥有ContentItems
属性(假设它被命名为TabControl
)。在TabItems
添加/删除项目时,ObservableCollection
会添加/删除 <TabControl ItemsSrouce="{Binding ContentItems}" />
。
<TabControl ItemsSource="{Binding Tabs}"
SelectedItem="{Binding SelectedTab}"
Margin="5"
Visibility="{Binding HasTabs, Converter={StaticResource VisibilityConverter}}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}"
Grid.Column="0"
TextTrimming="CharacterEllipsis"
ToolTip="{Binding Header}"
FontWeight="Bold"
TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
我正在从我的一个项目中粘贴示例TabControl代码。
{{1}}
希望有意义