title: Hosting ViewModels in ContentControl in WPF
body: <p>I have a traditional form layout with a menu bar at the top and status bar at the bottom. When the user selects a menu item, the space in-between (the form's entire remaining client area) gets replaced with a user control - think of an SDI app that can host multiple types of documents.</p>
  
  <p>If you know of a better way to go about this, please chime in. For now, I'm trying to get it to work in a very simplified version with a ContentControl, but I cannot get it to update the screen when its DataContext is set.</p>
  
  <p>Here's the very simple code for ViewModelA. ViewModelB is identical, except for the Bs.</p>
  
  <pre><code>namespace Dynamic_ContentControl
  {
      public class ViewModelA: ViewModelBase
      {
          public ViewModelA()
          {
              DisplayName = "This is A";
          }
      }
  }
  </code></pre>
  
  <p>The main window is very simple. It basically declares a property to hold the view model of the hosted control and exposes two commands to assign view models A or B.</p>
  
  <pre><code>namespace Dynamic_ContentControl
  {
      public class MainViewModel: ViewModelBase
      {
          private ViewModelBase clientContent = null;
  
          public ICommand ShowA { get; private set; }
          public ICommand ShowB { get; private set; }
          public ViewModelBase ClientContent {
              get
              {
                  return clientContent;
              }
              private set
              {
                  clientContent = value;
                  OnPropertyChanged("ClientContent");
              }
          }
          public MainViewModel()
          {
              ShowA = new RelayCommand((obj) =&gt;
              {
                  ClientContent = new ViewModelA();
              });
              ShowB = new RelayCommand((obj) =&gt;
              {
                  ClientContent = new ViewModelB();
              });
          }
      }
  }
  </code></pre>
  
  <p>Finally, the XAML declares a ContentControl and sets its ContentTemplate to a DataTemplate called ClientAreaTemplate, whose ContentPresenter points to another DataTemplate, named TextBlockLayout:</p>
  
  <pre><code>&lt;Window x:Class="Dynamic_ContentControl.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:vm="clr-namespace:Dynamic_ContentControl"
          Title="MainWindow" Height="350" Width="525"&gt;
      &lt;Window.DataContext&gt;
          &lt;vm:MainViewModel /&gt;
      &lt;/Window.DataContext&gt;
      &lt;Window.Resources&gt;
          &lt;DataTemplate x:Key="TextBlockLayout"&gt;
              &lt;TextBlock Text="{Binding Path=DisplayName}" /&gt;
          &lt;/DataTemplate&gt;
          &lt;DataTemplate x:Key="ButtonLayout"&gt;
              &lt;Button Content="{Binding Path=DisplayName}" /&gt;
          &lt;/DataTemplate&gt;
          &lt;DataTemplate x:Key="CheckBoxLayout"&gt;
              &lt;CheckBox Content="{Binding Path=DisplayName}" /&gt;
          &lt;/DataTemplate&gt;
          &lt;DataTemplate x:Key="ClientAreaTemplate"&gt;
              &lt;ContentPresenter x:Name="ContentArea" ContentTemplate="{StaticResource ResourceKey=TextBlockLayout}"/&gt;
              &lt;DataTemplate.Triggers&gt;
                  &lt;DataTrigger Binding="{Binding Path=DataContext}"
                               Value="{x:Type vm:ViewModelB}"&gt;
                      &lt;Setter TargetName="ContentArea"
                              Property="ContentTemplate"
                              Value="{StaticResource ResourceKey=ButtonLayout}" /&gt;
                  &lt;/DataTrigger&gt;
                  &lt;DataTrigger Binding="{Binding Path=DataContext}"
                               Value="{x:Type vm:ViewModelB}"&gt;
                      &lt;Setter TargetName="ContentArea"
                              Property="ContentTemplate"
                              Value="{StaticResource ResourceKey=CheckBoxLayout}" /&gt;
                  &lt;/DataTrigger&gt;
              &lt;/DataTemplate.Triggers&gt;
          &lt;/DataTemplate&gt;
      &lt;/Window.Resources&gt;
      &lt;Grid&gt;
          &lt;Button Content="Show A"
                  Command="{Binding Path=ShowA}"
                  HorizontalAlignment="Left"
                  Margin="10,10,0,0"
                  VerticalAlignment="Top"
                  Width="75" /&gt;
          &lt;Button Content="Show B"
                  Command="{Binding ShowB}"
                  HorizontalAlignment="Left"
                  Margin="90,10,0,0"
                  VerticalAlignment="Top"
                  Width="75" /&gt;
          &lt;Label Content="{Binding Path=ClientContent.DisplayName}"
                 HorizontalAlignment="Left"
                 Margin="170,8,0,0"
                 VerticalAlignment="Top" /&gt;
          &lt;ContentControl DataContext="{Binding Path=ClientContent}"
                          Content="{Binding}"
                          ContentTemplate="{StaticResource ResourceKey=ClientAreaTemplate}"
                          HorizontalAlignment="Left"
                          Margin="10,37,0,0"
                          VerticalAlignment="Top"
                          Height="198"
                          Width="211" /&gt;
  
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p><strong><code>Expected behaviour</code></strong></p>
  
  <p>When the screen opens, I want TextBoxLayout to display. If the user then clicks on one of the two buttons, it should load either a ButtonLayout or CheckBoxLayout, depending on the actual runtime type of the view model that is assigned.</p>
  
  <p><strong><code>Actual behaviour</code></strong></p>
  
  <p>The screen opens with the TextBoxLayout loaded, but it never changes to another type as I click the buttons.</p>
  
  <p>I think the problem is the way the DataTrigger tries to compare with the type, but there are no binding messages at all the Output window.</p>