How do I prevent BamlParseExceptions when binding some object properties?

WPF's data binding facilities are extremely powerful - sometimes when using this power you may experience BamlParseException with an error message stating that the was a problem converting from a Binding object to some other type. A typical error message might look like this:

Error at element 'RuntimePropertyInfo' in markup file 'Window1.xaml' : Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.String'

This problem can be confusing at first because Elements with the same DataContext in your Xaml file may be able to bind to the same piece of data without any problems.

<Window.Resources>
  <XmlDataProvider x:Key="data" XPath="//item">
    <x:XData>
      <items >
        <item val="foo"/><item val="bar" />
      </items>
    </x:XData>
  </XmlDataProvider>
</Window.Resources>
<StackPanel>
  <!-- this works -->
   <TextBlock Text="{Binding
XPath=@val }" />
  <!-- this does not -->
  <TextBlock>
    <Bold Text="{Binding
XPath=@val}"/ >
  </TextBlock>

</StackPanel>

If this is the case it can be indicative of a subtle problem not with the source of the data but with the property you're trying to bind the data to. WPF data binding makes use of the dependency property system built into WPF, and the eventual target of the {Binding} markup extension must be a dependency property. Dependency properties are not the same as CLR properties, which are a syntactic convenience which allows a pair of get and set methods for a member to be treated from a code perspective like a member field. Dependency properties on the other hand are objects of type DependencyProperty. Most of the UI-related properties of controls in WPF eventually call dependency properties internally, so it is easy to forget this rule.

It is not easy to know at a glance if a CLR property does indeed call a dependency property or not. The current WPF documentation does not explicity indicate this. The documentation does list the public fields of an object, which typically includes all the dependency properties as static fields. If the property you're trying to bind to does not have a static DependencyProperty member variable with the name of the CLR property, followed by 'Property' (e.g. TextProperty) then the CLR property is unlikely to be using the dependency property system underneath, and thus is not a suitable target for binding. Using Reflector to look inside the property getter and setter methods it is easy to spot the difference between the two.

CLR Property which calls a DependencyProperty (TextBlock.Text)

public string Text
{
      get
      {
            return (string) base.GetValue(TextBlock.TextProperty);
      }
      set
      {
            base.SetValue(TextBlock.TextProperty, value);
      }
}

CLR Property which does not call a DependencyProperty (Bold.Text), which we cannot bind to.

public string Text
{
      get
      {
            return TextRangeBase.GetTextInternal(base.ContentStart, base.ContentEnd);
      }
      set
      {
            if (value == null)
            {
                  value = string.Empty;
            }
            TextContainer container1 = base.TextContainer;
            container1.BeginChange();
            try
            {
                  TextPointer pointer1 = base.ContentStart;
                  if (!base.IsEmpty)
                  {
                        container1.DeleteContentInternal(pointer1, base.ContentEnd);
                  }
                  Run run1 = Inline.CreateImplicitRun(this);
                  pointer1.InsertTextElement(run1);
                  run1.Text = value;
            }
            finally
            {
                  container1.EndChange();
            }
      }
}


In some cases it is possible to work around this problem - if you are using data binding to keep two things synchronized and the other thing is a dependency property then swapping the source and target of the binding can solve this problem.