Binding as a Resource

Kylo Ren picture Kylo Ren · Apr 28, 2016 · Viewed 8.7k times · Source

Can I define a Binding as a Resource and then reuse it with different Controls properties?

Example:

Binding:

<Window.Resources>        
    <Binding x:Key="MyBinding" Path="MyProperty" Mode="TwoWay" />
</Window.Resources>

Reuse in XAML:

<TextBox Text="{StaticResource MyBinding}" />

After declaring Binding as above I got the error:

"The name 'InitializeComponent' does not exist in the current context"

Is there any way to reuse the same Binding in different contexts?

Answer

Grx70 picture Grx70 · May 1, 2016

Direct answer to your question is "yes, you can define a binding as a resource". The problem here is how do you then make any use of it? One possibility is to create an extension class which would pull the binding from the resources and apply it:

public class BindingResourceExtension : StaticResourceExtension
{
    public BindingResourceExtension() : base() { }

    public BindingResourceExtension(object resourceKey) : base(resourceKey) { }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var binding = base.ProvideValue(serviceProvider) as BindingBase;
        if (binding != null)
            return binding.ProvideValue(serviceProvider);
        else
            return null; //or throw an exception
    }
}

Usage example:

<Window.Resources>
    <ResourceDictionary>
        <Binding x:Key="MyBinding" Path="MyProperty" Mode="TwoWay" />
    </ResourceDictionary>
</Window.Resources>

(...)

<TextBox Text="{ns:BindingResource MyBinding}" />

Can this solution be used in MultiBinding?

Yes, it can:

<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="First: {0}, Second: {1}">
            <Binding Path="SomeProperty" />
            <ns:BindingResource ResourceKey="MyBinding" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

There is however one drawback to this - although everything will work in run-time, the XAML Designer will complain that BindingResourceExtension is not of proper type to be put in the MultiBinding.Bindings collection. But, thankfully, there is a quick solution - simply use StaticResourceExtension instead! So this, while being functionally equivalent in run-time, will be accepted by the designer:

<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="First: {0}, Second: {1}">
            <Binding Path="SomeProperty" />
            <StaticResource ResourceKey="MyBinding" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>