Caliburn.Micro contextual view woes or: XAML is not a purely declarative language

TLDR:
When using Caliburn.Micro in ViewModel first approach, and binding contextual content inside a view to same model (initial ViewModel), make sure to set View.Context before setting View.Model.

The long version:
This is not a criticism of Caliburn. It is really an excellent framework to speed up development, and make WPF a little less verbose for you. It did cost me quite a bit of time to get used to it and to understand it’s concepts. For same reason it’s easy to shoot yourself in the foot and find what the problem is about.

My foot wound was caused by this setup:

<ContentControl cal:View.Model="{Binding}" cal:View.Context="{Binding State}"></ContentControl>

View.Model and View.Context dependency properties provided by Caliburn.Micro. They provide us a way to host content inside a ContentControl, bind it to model provided by View.Model and select a view control depending on value of View.Context. There is seemingly nothing wrong with code above. At least for me, because I look at WPF as a declarative language. However, after running the application I get an exception:

TargetInvocationException wrapped around InvalidOperationException, stating:

“Logical tree depth exceeded while traversing the tree. This could indicate a cycle in the tree.”

at System.Windows.FrameworkElement.FindResourceInTree(FrameworkElement feStart, FrameworkContentElement fceStart, DependencyProperty dp, Object resourceKey, Object unlinkedParent, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, DependencyObject boundaryElement, InheritanceBehavior&amp; inheritanceBehavior, Object&amp; source)
at System.Windows.FrameworkElement.FindResourceInternal(FrameworkElement fe, FrameworkContentElement fce, DependencyProperty dp, Object resourceKey, Object unlinkedParent, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, DependencyObject boundaryElement, Boolean isImplicitStyleLookup, Object&amp; source)
at System.Windows.FrameworkElement.FindImplicitStyleResource(FrameworkElement fe, Object resourceKey, Object&amp; source)
at System.Windows.FrameworkElement.GetRawValue(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry&amp; entry)
at System.Windows.FrameworkElement.EvaluateBaseValueCore(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry&amp; newEntry)
at System.Windows.DependencyObject.EvaluateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry newEntry, OperationType operationType)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry&amp; newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue)
at System.Windows.FrameworkElement.UpdateStyleProperty()
at System.Windows.TreeWalkHelper.InvalidateOnTreeChange(FrameworkElement fe, FrameworkContentElement fce, DependencyObject parent, Boolean isAddOperation)
at System.Windows.FrameworkElement.ChangeLogicalParent(DependencyObject newParent)
at System.Windows.FrameworkElement.AddLogicalChild(Object child)
at System.Windows.Controls.ContentControl.OnContentChanged(Object oldContent, Object newContent)
at MahApps.Metro.Controls.TransitioningContentControl.OnContentChanged(Object oldContent, Object newContent)
at System.Windows.Controls.ContentControl.OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry&amp; newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at System.Windows.Controls.ContentControl.set_Content(Object value)

Since in my mind WPF was a advanced, nicer, smarter, better HTML, I first went after the problem in my ViewModels and code. Little did I know, problem was in the one line from beginning of this post. Order of Caliburns dependency properties was to blame. Looking more carefully, I noticed that ContentControl was getting filled with same user control which hosted it. It turns out that, though bindings give impression of declarative coding they are dependant of each other. Since View.Model was set first, Caliburn started looking for appropriate View for the model provided. Since View.Context was configured later, it defaulted to main view control. Correct declaration would be following:

<ContentControl cal:View.Context="{Binding State}" cal:View.Model="{Binding}"></ContentControl>