I have a WPF form with a left and right dock panels. The left panel has some user inputs based on which I create and launch different user controls within the right dock panel. We are using MMVM framework. Currently, we are creating and launching the user controls from the View Model of the form. I am not sure if this is correct as it appears to violate the MVVM rule of VM should not access View. Is that correct? Is there an alternative design that I could use (I guess I cannot write anything in the code-behind also, correct?).
No, You shouldn't be having any View specific code in the ViewModel. You can have code-behind if it is purely UI (no business logic) related.
There is a great article on MSDN on MVVM WPF Apps With The Model-View-ViewModel Design Pattern . I suggest, you read this article before writing any WPF applications using MVVM pattern.
For your specific scenario, I would have ContentControl
in the right hand side panel and have separate ViewModel
s to back different UserControl
s and then have DataTemplates
defined to display the right UserControl
for any given ViewModel
s.
Untested Pseudo Code:
DataTemplates
<DataTemplate DataType="{x:Type local:ViewModel1}">
<local:UserControl1 />
</DataTemplate>
<DataTemplate DataType="{x:Type local:ViewModel2}">
<local:UserControl2 />
</DataTemplate>
You would define those in Window.Resources
section or in a ResourceDictionary
and include that dictionary in Window.Resources
ContentControl
<ContentControl Content="{Binding CurrentContent}" />
In your current ViewModel that is backing the MainWindow, you will have a property called CurrentContent
, and when you set it to the right ViewModel instance, the appropriate and associated View/UserControl
will appear on the screen.
UPDATE
You will have TabControl
instead of a ContentControl
and have an ObservableCollection
property (let's say it is named as ContentItems
) in your ViewModel instead of CurrentContent. TabControl
will add/remove TabItems
as you add/remove items to/from the ObservableCollection
.
<TabControl ItemsSrouce="{Binding ContentItems}" />
I am pasting sample TabControl code from one of my projects.
<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>
Hope that makes sense
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.