title: How do I dynamically change ContentTemplate based on bound property?
body: <p>I've been having an issue that has been plaguing me for a while now, but I believe I finally tracked it down.  The symptoms are that my WPF controls will not render correctly when one of my bound properties triggers a <code>DataTrigger</code> that swaps out the <code>ContentTemplate</code>. Stack trace:</p>
  
  <pre><code>  System.ArgumentNullException: Value cannot be null.
    Parameter name: d
       at MS.Internal.Data.ElementObjectRef.GetObject(DependencyObject d, ObjectRefArgs args)
       at MS.Internal.Data.ObjectRef.GetDataObject(DependencyObject d, ObjectRefArgs args)
       at System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.VerifySourceReference(Boolean lastChance)
       at MS.Internal.Data.DataBindEngine.Task.Run(Boolean lastChance)
       at MS.Internal.Data.DataBindEngine.Run(Object arg)
       at MS.Internal.Data.DataBindEngine.OnLayoutUpdated(Object sender, EventArgs e)
       at System.Windows.ContextLayoutManager.fireLayoutUpdateEvent()
       at System.Windows.ContextLayoutManager.UpdateLayout()
       at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
       at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
       at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
       at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
       at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
  </code></pre>
  
  <p>Debugger doesn't help at all since it just breaks on <code>application.Run()</code>.  Here's what I'm doing in terms of the actual xaml:</p>
  
  <pre><code>  &lt;CollectionViewSource x:Key="SomeCollectionView"
                          Source="{Binding StatsByUser}"
                          IsLiveSortingRequested="True"&gt;
        &lt;CollectionViewSource.SortDescriptions&gt;
            &lt;scm:SortDescription PropertyName="Amount" Direction="Descending"/&gt;
            &lt;scm:SortDescription PropertyName="Name" Direction="Ascending"/&gt;
        &lt;/CollectionViewSource.SortDescriptions&gt;
    &lt;/CollectionViewSource&gt;
  
    &lt;ItemsControl Background="Transparent" Width="{StaticResource Width}"
                  ItemsSource="{Binding Source={StaticResource SomeCollectionView}}"&gt;
        &lt;ItemsControl.Resources&gt;
            &lt;DataTemplate x:Key="FullViewTemplate"&gt;
                &lt;Border Style="{StaticResource BorderStyle}"&gt;
                    &lt;controls:FullCustomEntityControl CustomEntityObject="{Binding}"
                                                    Style="{StaticResource PanelStyle}"
                                                    MouseDown="Info_OnMouseDown"/&gt;
                &lt;/Border&gt;
            &lt;/DataTemplate&gt;
            &lt;DataTemplate x:Key="CompactViewTemplate"&gt;
                &lt;Border Style="{StaticResource BorderStyle}"&gt;
                    &lt;controls:CompactCustomEntityControl CustomEntityObject="{Binding}"
                                                       Style="{StaticResource PanelStyle}"
                                                       MouseDown="Info_OnMouseDown"/&gt;
                &lt;/Border&gt;
            &lt;/DataTemplate&gt;
        &lt;/ItemsControl.Resources&gt;
        &lt;ItemsControl.ItemTemplate&gt;
            &lt;DataTemplate&gt;
                &lt;ContentControl Content="{Binding}"&gt;
                    &lt;ContentControl.Style&gt;
                        &lt;Style TargetType="{x:Type ContentControl}"&gt;
                            &lt;Setter Property="ContentTemplate" Value="{StaticResource FullViewTemplate}"/&gt;
                            &lt;Style.Triggers&gt;
                                &lt;DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=c:ShellView}, Path=ViewModel.ShowCompactView}" Value="True"&gt;
                                    &lt;Setter Property="ContentTemplate" Value="{StaticResource CompactViewTemplate}"/&gt;
                                &lt;/DataTrigger&gt;
                            &lt;/Style.Triggers&gt;
                        &lt;/Style&gt;
                    &lt;/ContentControl.Style&gt;
                &lt;/ContentControl&gt;
            &lt;/DataTemplate&gt;
        &lt;/ItemsControl.ItemTemplate&gt;
    &lt;/ItemsControl&gt;
  </code></pre>
  
  <p>Whenever <code>ViewModel.ShowCompactView</code> raises <code>PropertyChanged</code> event and kicks off the <code>DataTrigger</code>, it will switch the <code>ContentTemplate</code>, which then throws this error.  Is there a way to fix this or a better way to architect the <code>ContentTemplate</code> swap that won't result in this?</p>
  
  <p>Edit: Potentially relevant support article <a href="https://support.microsoft.com/en-us/kb/2461678" rel="nofollow noreferrer">https://support.microsoft.com/en-us/kb/2461678</a></p>
  
  <p>Edit2: Example of what happens to the UI: <a href="https://i.stack.imgur.com/5tMGR.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/5tMGR.png" alt="enter image description here"></a>.  You can see the large slots are the <code>FullCustomEntityControl</code> and the small slots are <code>CompactCustomEntityControl</code>.  Leaving them in either mode without changing it does not result in any issues, but having the data trigger change them results in issues like this.  Also, the control used should be consistent, not what seems like to be a split here. By leaving them in either mode, I meant just removing the data trigger and choosing one or the other.</p>
  
  <p>Edit3: A post on a similar issue with someone from Microsoft responding: <a href="https://social.msdn.microsoft.com/Forums/vstudio/en-US/fb4d0f41-bfea-409f-b8ac-e66558984b7a/argumentnullexception-when-displaying-wpf-window?forum=wpf" rel="nofollow noreferrer">https://social.msdn.microsoft.com/Forums/vstudio/en-US/fb4d0f41-bfea-409f-b8ac-e66558984b7a/argumentnullexception-when-displaying-wpf-window?forum=wpf</a></p>
  
  <p>Relevant information: </p>
  
  <blockquote>
    <p>If you're getting an ArgumentNullException with VerifySourceReference on the stack, it is definitely caused by the issue described in Connect 561752.   Even if your app is not using ElementName bindings directly, it may use them indirectly - several built-in controls use ElementName bindings:  ComboBox, ContextMenu, MenuItem, etc.</p>
  </blockquote>