24

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?

6
  • See here: stackoverflow.com/q/9227081/1136211 Commented Apr 28, 2016 at 10:46
  • @Clemens it's gives some methods but of no use for me. I can't conclude any significant info Commented Apr 28, 2016 at 11:04
  • You can apply Binding only to a DP of DO. Commented May 1, 2016 at 6:40
  • 4
    Technically interesting but what is the point (use case?) in reusing a binding as a resource? Isn't the property-name itself not sufficient for referencing the source property? Also you are kind of predefining the binding mode which might not be suited for the binding target at all. Commented May 4, 2016 at 22:06
  • 2
    @Wouter it's kind of benefit when a large no of DataTemplate has to be created for ItemsControl. And you know every template is essentially gonna bound to same properties. So if we can achieve Binding as a resource some amount of re usability can be achieved. see this stackoverflow.com/questions/36716010/… Commented May 5, 2016 at 5:14

2 Answers 2

19
+50

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> 
Sign up to request clarification or add additional context in comments.

7 Comments

great solution, i wanted solution exactly like this...... but I'm still not clear about how is this working? class name is BindingResourceExtension but in text property you have defined BindingResource?
When using extension classes in XAML you can omit the "Extension" suffix - it's a feature of XAML parser. Similar principle lets you omit the "Attribute" suffix when using attribute classes. That of course is true as long as it doesn't introduce any ambiguity. Note the StaticResourceExtension class from which we derive - it's the same class that is used as {StaticResource (...)} in XAML.
That's because XAML parser misinterprets your intentions - it is designed to "think" that you're trying to bind the Window.Resources property using the specified binding rather than add the binding to the dictionary.
can this be used in a multibinding? I can't figure out the syntax. (I want one of the inner bindings of the multibinding to be reused)
Got error with VS2015 A 'Binding' cannot be set on the 'Value' property of type 'DictionaryEntry'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
|
4

Here are two ways to not do exactly what you want:

1. Using a custom markup extension

Skipped all nullchecks etc. to keep it short.

using System; using System.Windows; using System.Windows.Data; using System.Windows.Markup; public class BindingDefinition { public PropertyPath Path { get; set; } public BindingMode Mode { get; set; } } [MarkupExtensionReturnType(typeof(BindingExpression))] public class ApplyBindingDefinition : MarkupExtension { public BindingDefinition Definition { get; set; } public override object ProvideValue(IServiceProvider serviceProvider) { var binding = new Binding { Path = this.Definition.Path, Mode = this.Definition.Mode }; return binding.ProvideValue(serviceProvider); } } 

<Window.Resources> <local:BindingDefinition x:Key="MyProperty" Mode="TwoWay" Path="MyProperty" /> </Window.Resources> <TextBox> <TextBox.Text> <!-- using element style here as the parser chokes on parsing nested markupextensions --> <local:ApplyBindingDefinition Definition="{StaticResource MyProperty}" /> </TextBox.Text> </TextBox> 

2. Making the PropertyPath a resource

May or may not be enough for your needs.

<Window.Resources> <PropertyPath x:Key="MyPropertyPath">MyProperty</PropertyPath> </Window.Resources> ... <TextBox Text="{Binding Path={StaticResource MyPropertyPath}}" /> 

4 Comments

I'm looking for somewhat same solution... if this is possible for whole binding...that way I want to achieve max re usability (for binding syntax) for some dynamically generated controls of different kinds....
@Kylo Updated the answer.
Designer complains after second build but the designer is broken in countless ways.
it's a good solution, however the lines of code that I am trying to avoid is still there...It's would be much better solution if I could define the ApplyBindingDefinition in resources and then just reuse it. I hope above make sense, but thanks anyways.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.