Category: Workarounds


If you’re using WPF, you probably encountered this obscure message of "Cannot find governing FrameworkElement or FrameworkContentElement for target element.", and found that your binding doesn’t work.

This message means that the binding engine could not locate the object of which to bind to.
This usually happens when the data context hierarchy chain is broken by a non-FrameworkElement object. Interestingly enough, this chain breaking also makes the search by ElementName broken.

For example, place a FrameworkElement inside a binding’s ConverterParameter property, and try to bind one of the element’s properties. VS will write in its output window the error message above.
You can place the element like this:
<Button.Content>
    <Binding Converter="{StaticResource someConverter}">
        <Binding.ConverterParameter>
            <!–Here is the binding that shouldn’t work: –>
            <FrameworkElement DataContext="{Binding ElementName=myElement, Path=Content}"/>
        </Binding.ConverterParameter>
    </Binding>
</Button.Content>

You can overcome this problem by using the x:Reference markup extension (or its improved version I wrote about in one of my previous posts). You can a name to the element you want to bind to, and then let the binding engine find it by using the Source property, like this:

{Binding Source={x:Reference myElement}, Path=Width}

How can you name your target element? You can simply use the x:Name directive, or the more elegant "Name" property, which is mapped to the x:Name directive by FrameworkElement with the RuntimeNamePropertyAttribute attribute.

x:Reference

For my first post, I would like to talk a little about XAML’s x:Reference markup extension.

Those who have some experience with XML serialization must remember the pain it caused to any sane person, driving him to insanity.

I remember myself few years ago trying to serialize a pair of classes which one was referencing the other, and transporting them through WCF with XML serialization.

XML didn’t give you a way (at least not an easy one) to handle what was called a “circular reference” (or cyclic reference), in which two objects referencing one another.

 

Along came XAML.

As some of you already know, XAML started as part of the WPF technology, but it was long ago when the guys at Microsoft realized it could be used to almost everything else. That’s why the XAML classes were migrated to their own assembly in .Net 4 (System.XAML).

XAML handles the “circular reference” problem quite nicely: You can take one element and assign it a name with the x:Name attribute (notice the that the namespace that is assigned to the x prefix isn’t related to WPF whatsoever), and take the other element and reference the first element with the x:Reference markup extension.

 

Here’s an example:

<Root x:Name=”rootParent”>

<Root.Child>

<Node Parent=”{x:Reference rootParent}”/>

</Root.Child>

</Root>

 

Here we have a parent of type Root, which in its Child property we have an object of type Node.

The child’s Parent property is referencing the root with the x:Reference markup extension.

 

Of course, the x:Reference markup extension could be used in WPF as well.
There are many cases when one control needs to reference another one by its name.
One way to do this is to use binding with the ElementName property set.
This way, in my opinion, is not very good because it’s forcing us to create a binding and it will have an impact on the performance. We could improve it a little bit by using the OneTime mode, but still I think the x:Reference is more proper an elegant.

There is one problem, though: As for the time of writing, WPF’s designer can’t handle the x:Reference markup extension. x:Reference is trying to locate the IXamlNameResolver  service, which doesn’t exist in design mode. This is causing the designer to be completely disabled, while displaying the message “Service provider is missing the INameResolver service.”.

There is, however, a simple solution for this problem.
As I was writing in this bug‘s workaround list at Microsoft’s Connect, we could extend the System.Windows.Markup.Reference class and override the ProvideValue method to return null if the control is is design mode, or (if you’re using this outside WPF) return null if the IXamlNameResolver service doesn’t exist, although if you’re using it for WPF exclusively, the first approach is preferred..

 

[ContentProperty(“Name”)]
public class Reference : System.Windows.Markup.Reference
{
public Reference()
: base()
{ }

public Reference(string name)
: base(name)
{ }

public override object ProvideValue(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
{
throw new ArgumentNullException(“serviceProvider”);
}

IProvideValueTarget valueTargetProvider = serviceProvider.GetService(typeof
IProvideValueTarget)) as IProvideValueTarget;

if (valueTargetProvider != null)
{
DependencyObject targetObject = valueTargetProvider.TargetObject as DependencyObject;

if (targetObject != null && DesignerProperties.GetIsInDesignMode(targetObject))
{
return null;
}
}

return base.ProvideValue(serviceProvider);
}
}