title: When is x:Reference in WPF resolved and why does XAML element order affect it?
body: <p>x:Reference can not be resolved after I re-arrange elements in XAML.</p>
  
  <p>Here I present a working code. Just move the DataGrid element so it comes after the button element and the bindings for the MenuItem in ContextMenu and MultiBinding in Button.IsEnabled become broken. In Button.IsEnabled only MultiBinding is broken. It can be replaced with commented block and x:Reference works in that single binding.</p>
  
  <p>Both throw XamlParseException. </p>
  
  <ul>
  <li>MenuItem gives System.Xaml.XamlObjectWriterException and message talks about unresolved reference.</li>
  <li>MultiBinding gives System.Collections.Generic.KeyNotFoundException as inner exception.</li>
  </ul>
  
  <p>So when is that x:Reference actually resolved and why does only some bindings break when referenced element comes after the element that references it?</p>
  
  <p>Here is my XAML:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;Window x:Class="WpfApplication1.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:xxx="clr-namespace:WpfApplication1"
          Title="MainWindow" SizeToContent="WidthAndHeight"&gt;
      &lt;Window.Resources&gt;
          &lt;xxx:BoolToVisibleConverter x:Key="boolToVisibleConv"&gt;&lt;/xxx:BoolToVisibleConverter&gt;
          &lt;xxx:NullToFalseConverter x:Key="nullToFalseConv"&gt;&lt;/xxx:NullToFalseConverter&gt;
          &lt;xxx:NullsOrToFalseConverter x:Key="nullsOrToFalseConv"&gt;&lt;/xxx:NullsOrToFalseConverter&gt;
          &lt;ContextMenu x:Key="MyMenu"&gt;
              &lt;MenuItem 
                  Header="Menuitem enabled when row selected" 
                  IsEnabled="{Binding 
                      Path=SelectedItem, 
                      Source={x:Reference dataGridElement}, 
                      Converter={StaticResource nullToFalseConv}}" /&gt;
          &lt;/ContextMenu&gt;
      &lt;/Window.Resources&gt;
      &lt;StackPanel&gt;
          &lt;DataGrid 
              Name="dataGridElement" 
              IsReadOnly="True" /&gt;
          &lt;Button 
              Content="Button" 
              ContextMenu="{StaticResource MyMenu}" 
              Visibility="{Binding 
                  Path=IsReadOnly, 
                  Source={x:Reference dataGridElement},
                  Converter={StaticResource boolToVisibleConv}}"&gt;
              &lt;Button.IsEnabled&gt;
                  &lt;!--&lt;Binding 
                      Path="SelectedItem" 
                      Source="{x:Reference dataGridElement}" 
                      Converter="{StaticResource nullToFalseConv}"/&gt;--&gt;
                  &lt;MultiBinding 
                      Converter="{StaticResource nullsOrToFalseConv}"&gt;
                      &lt;Binding 
                          Path="SelectedItem" 
                          Source="{x:Reference dataGridElement}"/&gt;
                      &lt;Binding 
                          Path="SelectedItem" 
                          Source="{x:Reference dataGridElement}"/&gt;
                  &lt;/MultiBinding&gt;
              &lt;/Button.IsEnabled&gt;
          &lt;/Button&gt;
      &lt;/StackPanel&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p>Here is my Code behind (without usings):</p>
  
  <pre class="lang-cs prettyprint-override"><code>namespace WpfApplication1
  {
      /// &lt;summary&gt;
      /// Interaction logic for MainWindow.xaml
      /// &lt;/summary&gt;
      public partial class MainWindow : Window
      {
          public MainWindow()
          {
              InitializeComponent();
          }
      }
      public class BoolToVisibleConverter : IValueConverter
      {
          public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
              if (value == null || (bool)value == false)
                  return System.Windows.Visibility.Hidden;
              else
                  return System.Windows.Visibility.Visible;
          }
  
          public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
              throw new NotImplementedException();
          }
      }
      public class NullsOrToFalseConverter : IMultiValueConverter
      {
          public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
              foreach (object val in value)
              {
                  if (val == null)
                      return false;
              }
              return true;
          }
  
          public object[] ConvertBack(object value, Type[] targetType, object parameter, System.Globalization.CultureInfo culture)
          {
              throw new NotImplementedException();
          }
      }
      public class NullToFalseConverter : IValueConverter
      {
          public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
              return (value != null);
          }
  
          public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
              throw new NotImplementedException();
          }
      }
  }
  </code></pre>