title: WPF Binding Failure: Double Binding Resolution?
body: <p>I have a user control for setting up a serial port. The XAML is this:</p>
  
  <pre><code>&lt;UserControl x:Class="DSS.Communication.UI.ComPortUI"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
           xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
           xmlns:utilUI="clr-namespace:DSS.Util.UI;assembly=DSS.Util"
           xmlns:localUI="clr-namespace:DSS.Communication.UI"
           mc:Ignorable="d" 
           d:DesignHeight="300" d:DesignWidth="300"&gt;
  &lt;UserControl.Resources&gt;
      &lt;utilUI:DebugConverter x:Key="DebugConverter"/&gt;
      &lt;localUI:BoolXIsOpenConverter x:Key="IsOpenConverter"/&gt;
  &lt;/UserControl.Resources&gt;
      &lt;StackPanel&gt;
  
          &lt;StackPanel&gt;
          &lt;TextBlock Text="{Binding StringFormat='ComPortUI.DataContext: {0}',FallbackValue='ComPortUI.DataContext: Null'}"/&gt;
          &lt;TextBlock Text="{Binding StringFormat='ComPortUI.TargetPort: {0}',FallbackValue='ComPortUI.TargetPort: Null',RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl},Path=TargetPort}"/&gt;
          &lt;DockPanel&gt;
                  &lt;utilUI:IndicatorLight DockPanel.Dock="Right" Width="20" CurrentBrush="{Binding IsOpen,Converter={StaticResource IsOpenConverter}}"/&gt;
                  &lt;TextBlock DockPanel.Dock="Right" Text="{Binding PortName.FriendlyName}"/&gt;        
              &lt;/DockPanel&gt;
              &lt;StackPanel Orientation="Horizontal"&gt;
                  &lt;ComboBox x:Name="UI_AvailablePorts_CB" SelectedItem="{Binding PortName, Converter={StaticResource DebugConverter}}" Width="150"&gt;
                      &lt;ComboBox.ItemTemplate&gt;
                          &lt;DataTemplate&gt;
                              &lt;TextBlock Text="{Binding SimpleName}"/&gt;
                          &lt;/DataTemplate&gt;
                      &lt;/ComboBox.ItemTemplate&gt;
                  &lt;/ComboBox&gt;
                  &lt;ComboBox x:Name="UI_Baudrate_CB" SelectedItem="{Binding BaudRate}" Width="150"&gt;
  
                  &lt;/ComboBox&gt;
              &lt;/StackPanel&gt;
              &lt;Button x:Name="UI_RawComs_Btn" Click="UI_RawComs_Btn_Click" IsEnabled="{Binding IsOpen}"&gt;Monitor&lt;/Button&gt;
          &lt;/StackPanel&gt;
  
  &lt;/StackPanel&gt;
  </code></pre>
  
  <p></p>
  
  <p>The importaint bits for the code behind are this:</p>
  
  <pre><code>public IComPort TargetPort
          {
              get { return (IComPort)GetValue(TargetPortProperty); }
              set { SetValue(TargetPortProperty, value); }
          }
          // Using a DependencyProperty as the backing store for TargetPort.  This enables animation, styling, binding, etc...
          public static readonly DependencyProperty TargetPortProperty =
              DependencyProperty.Register("TargetPort", typeof(IComPort), typeof(ComPortUI), new PropertyMetadata(null,TargetPort_Changed));
          public static void TargetPort_Changed(DependencyObject d,DependencyPropertyChangedEventArgs e)
          {
              System.Diagnostics.Debugger.Log(0, "TargetPort_Changed",String.Format("{0}-&gt;{1}\r\n",e.OldValue,e.NewValue==null?"null":e.NewValue));
              ComPortUI ui = (ComPortUI)d;
  </code></pre>
  
  <p>and this:</p>
  
  <pre><code>    public ComPortUI()
      {
  
          _isMonitoring = false;
  
          InitializeComponent();
          foreach (ComPortName cpn in ComPort.AvailablePorts)
              UI_AvailablePorts_CB.Items.Add(cpn);
          foreach (int br in BaudRates)
          {
              UI_Baudrate_CB.Items.Add(br);
          }
  
          Dispatcher.BeginInvoke(new Action(() =&gt;
          {
              System.Diagnostics.Debugger.Log(0, "ComPortUI()", "DataContext Changed\r\n");
              DataContext = TargetPort;
  
  
          }), System.Windows.Threading.DispatcherPriority.ApplicationIdle);
      }
              ui.DataContext = e.NewValue;
          }
  </code></pre>
  
  <p>Now, When I use the control like this:</p>
  
  <p>MainWindow.cs:</p>
  
  <pre><code>public partial class MainWindow : Window {
          public MainWindow() {
              DataContext = new ComPort();
              InitializeComponent();
          }
      }
      public class MainWindowContext {
          public MainWindowContext() {
              Port = new ComPort();
          }
          public ComPort Port {
              get;
              protected set;
          }
      }
  </code></pre>
  
  <p>MainWindow.xaml:</p>
  
  <pre><code>  &lt;Window x:Class="DSSUITest.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:dss.communication.ui="clr-namespace:DSS.Communication.UI;assembly=DSS.Communication"
          xmlns:dss.util.ui="clr-namespace:DSS.Util.UI;assembly=DSS.Util"
          Title="MainWindow" Height="350" Width="525"&gt;
      &lt;StackPanel&gt;
          &lt;dss.communication.ui:ComPortUI TargetPort="{Binding}"/&gt;
      &lt;/StackPanel&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p>Everything works out fine, but when I do this:</p>
  
  <p>MainWindow.cs:</p>
  
  <pre><code>public partial class MainWindow : Window {
              public MainWindow() {
                  DataContext = new MainWindowContext()
                  InitializeComponent();
              }
          }
          public class MainWindowContext {
              public MainWindowContext() {
                  Port = new ComPort();
              }
              public ComPort Port {
                  get;
                  protected set;
              }
          }
  </code></pre>
  
  <p>MainWindow.xaml:</p>
  
  <pre><code>  &lt;Window x:Class="DSSUITest.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:dss.communication.ui="clr-namespace:DSS.Communication.UI;assembly=DSS.Communication"
          xmlns:dss.util.ui="clr-namespace:DSS.Util.UI;assembly=DSS.Util"
          Title="MainWindow" Height="350" Width="525"&gt;
      &lt;StackPanel&gt;
          &lt;dss.communication.ui:ComPortUI TargetPort="{Binding Port}"/&gt;
      &lt;/StackPanel&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p>I get a binding error, specifically:</p>
  
  <pre><code>System.Windows.Data Error: 40 : BindingExpression path error: 'Port' property not found on 'object'      ''ComPort' (HashCode=40105335)'. BindingExpression:Path=Port; DataItem='ComPort' (HashCode=40105335); target element is 'ComPortUI' (Name=''); target property is 'TargetPort' (type 'IComPort')
  </code></pre>
  
  <p>This causes TargetPort, and subsequently DataContext, to become null, which as you might imagine causes some issues. </p>
  
  <p>I've been very confused by this, because the TargetPort property actually get's set twice, the first time correctly (from null to the Binding) and then a second time, when...I don't exactly know what happens. It LOOKS like the binding is being resolved twice on two separate things, First the MainWindowContext, and then on the Port property of the MainWindowContext. What am I missing?</p>