MVVM is quite a shift from the Windows Forms and ASP.net paradigms I've used for years. One thing I find confusing is setting up the pages by assigning ViewModels to pages and controls. These notes are more for my personal use, but you are welcome to read if it helps you.
Method1:
In a resource file or within the page xaml, we define a DataTemplate that specifies that a ViewModel ( named TestContactViewModel) will be displayed using a View (named TestContactView).
<DataTemplate DataType="{x:Type vm:TestContactViewModel}">
<vw:TestContactView />
</DataTemplate>
Now when we bind a 'TestContactViewModel', the software knows to use a 'TestContactView' to display that ViewModel.
In the same page xaml, we have a Tab Control, and you can see here that on the 3rd tab we bind the 'TestContactViewModel'. The DataTemplate above makes sure that it will be displayed with the desired View.
<Grid>
<TabControl Margin="20">
<TabItem Header="_Home">
</TabItem>
<TabItem Header="_Vendor">
</TabItem>
<TabItem Header="_Clients" Content="{Binding Path=TestContactViewModel}" >
</TabItem>
...
Method 2:
In this example, a Collection<T> or ReadOnlyCollection<T> is bound as the content of a control. This is different because a ViewModel was not bound as the Content. But this 'Commands' collection is actually a collection of ViewModels.
<HeaderedContentControl
Content="{Binding Path=Commands}"
ContentTemplate="{StaticResource CommandsTemplate}"
Header="Menu" Style="{StaticResource MainHCCStyle}" />
The 'Commands' this code in the ViewModel tied to the above View:
public ReadOnlyCollection<CommandViewModel> Commands{
get{...}
}
To keep this simple just know that a CommandViewModels have 2 properties: DisplayName (string) and Command(RelayCommand).
There is no CommandView. Instead, the control above said to use a ContentTemplate named CommandsTemplate. In the xaml of the page displaying the Control bound to 'Commands', there is this DataTemplate to show how to display the Commands:
<DataTemplate x:Key="CommandsTemplate">
<ItemsControl IsTabStop="False" ItemsSource="{Binding}" Margin="6,2">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Margin="2,6">
<Hyperlink Command="{Binding Path=Command}">
<TextBlock Text="{Binding Path=DisplayName}" />
</Hyperlink>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
Method 3:
Now we're going to combine methods 1 and 2 and have a Collection of ViewModels that will be displayed according to DataTemplate, like Method 2, however these ViewModels have Views that dictate how to display each ViewModel in the collection.
<HeaderedContentControl
Content="{Binding Path=Workspaces}"
ContentTemplate="{StaticResource WorkspacesTemplate}"
Header="Workspaces" Style="{StaticResource MainHCCStyle}" />
The path Workspaces is an Observable collection of 'WorkspaceViewModels'.
public ObservableCollection<WorkspaceViewModel> Workspaces{
get{ ...}
}
The DataTemplate that was specified to shows these Workspaces:
<DataTemplate x:Key="WorkspacesTemplate">
<TabControl
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource ClosableTabItemTemplate}" Margin="4" />
That took care of some important details but didn't tell how to display a Workspace.
There are 2 classes types that derive from 'WorkspaceViewModels': AllContactsViewModel, and ContactViewModel.
These data templates in the same xaml file tell the page which view to use to display these WorkspaceViewModels depending on which type they are:
<DataTemplate DataType="{x:Type vm:AllContactsViewModel}">
<vw:AllContactsView />
</DataTemplate>
And
<DataTemplate DataType="{x:Type vm:ContactViewModel}">
<vw:ContactView />
</DataTemplate>
There is more than one way to get your ViewModel assigned to be displayed. You can hard code a ViewModel as the Content of a control. Make sure that there is a DataTemplate that specifies either the info from the ViewModel to show, or tells the View to use to display that ViewModel. Another option is to bind a Collection to the Content of a control. If the Collection contains ViewModels, then they will be displayed according to the DataTemplate that either tells which View to use for that ViewModel or tells specifically how to display the ViewModel without the use of a View.
Theres a start on how ViewModels are bound and displayed with Views or DataTemplates.