title: WPF Custom Control Picking Up Parent Window's DataContext
body: <p>I have a ViewModel</p>
  
  <pre><code> public class ViewModel:ViewModelObject
  {
      public ViewModel()
      {
          ProjectionDataElementList = new ObservableCollection&lt;ProjectionDataElement&gt;();
      }
  
      public ObservableCollection&lt;ProjectionDataElement&gt; ProjectionDataElementList { get; set; }
  
      private ProjectionDataElement _currentSelectedProjectionDataElement;
  
      public ProjectionDataElement CurrentSelectedProjectionDataElement
      {
          get 
          { 
              return _currentSelectedProjectionDataElement; 
          }
          set 
          { 
              _currentSelectedProjectionDataElement = value;
              OnPropertyChanged("CurrentSelectedProjectionDataElement");
          }
      }
  
  }
  </code></pre>
  
  <p>A control called ProjectorDisplayControl</p>
  
  <pre><code>&lt;UserControl x:Class="Fast_Project.ProjectorDisplayControl"
           ..................&gt;
  &lt;Viewbox&gt;
      &lt;StackPanel&gt;
          &lt;TextBlock Text="{Binding Path=TextBody}"/&gt;
      &lt;/StackPanel&gt;
  &lt;/Viewbox&gt;
  </code></pre>
  
  <p></p>
  
  <pre><code>    public partial class ProjectorDisplayControl : UserControl
  {
  
      public ProjectorDisplayControl()
      {
          InitializeComponent();
      }
  
      public static readonly DependencyProperty ProjectedDataProperty = DependencyProperty.Register("ProjectedData", typeof(ProjectionDataElement), typeof(ProjectorDisplayControl),
              new PropertyMetadata(new PropertyChangedCallback((objectInstance, arguments) =&gt;
              {
                  ProjectorDisplayControl projectorDisplayControl = (ProjectorDisplayControl)objectInstance;
                  projectorDisplayControl._projectedData = (ProjectionDataElement)arguments.NewValue;
              })));
  
      public ProjectionDataElement ProjectedData
      {
          get
          {
              return (ProjectionDataElement)GetValue(ProjectedDataProperty);
          }
          set
          {
              SetValue(ProjectedDataProperty, value);
          }
      }
  
  
      private ProjectionDataElement _projectedData
      {
          get
          {
              return this.DataContext as ProjectionDataElement;
          }
          set
          {
              this.DataContext = value;
          }
      }
  }
  </code></pre>
  
  <p>That control is used in two places.</p>
  
  <p>First place is in a ListBox where it works great:</p>
  
  <pre><code>&lt;ListBox Grid.Column="0" ItemsSource="{Binding Path=ProjectionDataElementList}" Name="projectedDataListBox" 
               SelectedItem="{Binding Path=CurrentSelectedProjectionDataElement, UpdateSourceTrigger=PropertyChanged}"&gt;
          &lt;ListBox.ItemTemplate&gt;
              &lt;DataTemplate&gt;
                  &lt;StackPanel&gt;
                      &lt;Border BorderThickness="1" BorderBrush="Black"&gt;
                          &lt;controls:ProjectorDisplayControl x:Name="_projectorDisplay" ProjectedData="{Binding}"/&gt;
                      &lt;/Border&gt;
                  &lt;/StackPanel&gt;
              &lt;/DataTemplate&gt;
          &lt;/ListBox.ItemTemplate&gt;
      &lt;/ListBox&gt;
  </code></pre>
  
  <p>Second place is on top of a form where I set the form's DataContext with a ViewModel object. To make the ProjectorDisplayControl consume the CurrentSelectedProjectionDataElement in the ViewModel I would expect to have to do this:</p>
  
  <pre><code>&lt;Window x:Class="Fast_Project.DisplayWindow"
      ................&gt;
  &lt;Viewbox&gt;
      &lt;StackPanel&gt;
          &lt;controls:ProjectorDisplayControl x:Name="_projectorDisplay" ProjectedData="{Binding CurrentSelectedProjectionDataElement}"/&gt;
      &lt;/StackPanel&gt;
  &lt;/Viewbox&gt;
  </code></pre>
  
  <p></p>
  
  <p>That code gives me two binding errors:</p>
  
  <blockquote>
    <p>System.Windows.Data Error: 40 :
     BindingExpression path error:
     'TextBody' property not found on 'object' ''ViewModel' (HashCode=2512406)'.
     BindingExpression:Path=TextBody;
     DataItem='ViewModel' (HashCode=2512406);
     target element is 'TextBlock' (Name='');
     target property is 'Text' (type 'String')</p>
    
    <p>System.Windows.Data Error: 40 :
     BindingExpression path error:
     'CurrentSelectedProjectionDataElement' property not found on 'object' ''ProjectionDataElement' (HashCode=37561097)'.
     BindingExpression:Path=CurrentSelectedProjectionDataElement;
     DataItem='ProjectionDataElement' (HashCode=37561097);
     target element is 'ProjectorDisplayControl' (Name='_projectorDisplay');
     target property is 'ProjectedData' (type 'ProjectionDataElement')</p>
  </blockquote>
  
  <p>When I watch the setter of the private property _projectedData on ProjectorDisplayControl which sets the DataContext I first see it get set with a valid value and then set to null.</p>
  
  <p>In the DisplayWindow that holds the single ProjectorDisplayControl I can remove the binding to the CurrentSelectedProjectionDataElement and then I only get the first binding error message:</p>
  
  <pre><code>&lt;Viewbox&gt;
      &lt;StackPanel&gt;
          &lt;controls:ProjectorDisplayControl x:Name="_projectorDisplay" /&gt;
      &lt;/StackPanel&gt;
  &lt;/Viewbox&gt;
  </code></pre>
  
  <p>The first binding error makes me feel like the ProjectorDisplayControl's DataContext is getting set with a ViewModel object when the DisplayWindow's DataContext is getting set. But from what I've read controls don't share the same data context with their parent window unless you set it so. </p>
  
  <p>I've treating the binding path for the ProjectorDisplayControl.ProjectedData in DisplayWindow like it was a ProjectionDataElement object as the second error message states.</p>
  
  <pre><code>&lt;Viewbox&gt;
      &lt;StackPanel&gt;
          &lt;controls:ProjectorDisplayControl x:Name="_projectorDisplay" ProjectedData="{Binding }"/&gt;
      &lt;/StackPanel&gt;
  &lt;/Viewbox&gt;
  </code></pre>
  
  <p>Then is tells me:</p>
  
  <blockquote>
    <p>Cannot create default converter to perform 'one-way' conversions between types 'Fast_Project.ViewModel' and 'Fast_Project.ProjectionDataElement'</p>
  </blockquote>
  
  <p>Like it really was the ViewModel object like I thought it was in the first place...</p>
  
  <p>Anyways I suspect that the root of my problem lies in the how I see the ProjectorDisplayControl having a DataContext set to the ViewModel object. Anyone see where I messed up?</p>
  
  <p>Thank you all for your help!</p>
  
  <hr>
  
  <p>The solution was:</p>
  
  <hr>
  
  <p>ProjectorDisplayControl</p>
  
  <pre><code>        &lt;StackPanel&gt;
          &lt;TextBlock Text="{Binding Path=ProjectedData.TextBody, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type controls:ProjectorDisplayControl}}}"/&gt;
      &lt;/StackPanel&gt;
  </code></pre>
  
  <p>DisplayWindow</p>
  
  <pre><code>&lt;StackPanel&gt;
          &lt;controls:ProjectorDisplayControl x:Name="_projectorDisplay" ProjectedData="{Binding Path=ViewModel.CurrentSelectedProjectionDataElement, 
              RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type controls:DisplayWindow}}}"/&gt;
      &lt;/StackPanel&gt;
  </code></pre>