WPF Binding: When do I need to use ObjectDataProvider?
- Transfer
There are many ways to create an object that will be used as data source for binding. Many people create an object in code and assign this object to the Window's DataContext property. This is generally a good way. You may have noticed that I added the source object to the Resource Dictionary of the Window class in most of my posts, and this worked pretty well. However, we do have an ObjectDataProvider class in data binding, which can also be used to create your source object in XAML. In this post, I will try to explain the differences between adding a source object directly to resources and using ObjectDataProvider. I hope I will provide you with guidance on how to evaluate your task and choose the best solution.
As I describe these possibilities, we will create a small program that will allow people to indicate their weight on Earth and find out how much they will weigh on Jupiter.
When we add the source object directly to resources, the data binding engine calls the default constructor for the type of this object. An object added to the resource dictionary uses a key defined through x: Key. Here is a sample code for this approach:
Alternatively, you can add an object of the ObjectDataProvider class to resources and use it as a source for binding. The ObjectDataProvider class is a wrapper for your source object that provides some additional functionality. Next, I'll talk about the following notable features of ObjectDataProvider:
When we add the source object directly to resources, WPF always calls the default constructor for this type. It may happen that you do not have control over the source object, and the class you add does not have a default constructor. For example, this is a class from a third-party library and it is declared as sealed. In this situation, you can create an instance of the class in XAML by using ObjectDataProvider in the following way:
This markup creates an instance of the MySource class by calling its constructor and passing it the string “Jupiter” as a parameter. At the same time, an object of the ObjectDataProvider class is also created, which will wrap an object of the MySource class.
MySource has a public property called “Planet” that provides an object of the Planet class whose name matches the string passed to the constructor. In our case, this is “Jupiter”. I want the program to have a Label that communicates with the Name property of the planet. Binding on subproperties can be done in WPF using “dot notation”. In general, it looks like this: Path = Property.SubProperty. You can see this in the following code:
You could look at this definition of binding and think that it does not make sense. It looks as if we are associated with the Name sub-property of the Planet property of the ObjectDataProvider class. But I mentioned above that MySource has a Planet property, while ObjectDataProvider does not. The reason this code works is because the binding engine accesses the ObjectDataProvider in a special way when the Path property of the source object is wrapped (i.e. wrapped). Note that this special handling can also be applied when linking to an XmlDataProvider or CollectionViewSource.
MySource has a method that takes as an argument the weight of a person on Earth and calculates the weight of that person on the planet that was passed to the constructor. I want to pass some weight value to a method in XAML and contact its result. This can be done using ObjectDataProvider:
Notice that instead of setting the ObjectType property, this time I set the ObjectInstance property. This allows us to reuse the instance of the MySource class that we created in the previous ObjectDataProvider. I also set the MethodName property and passed the parameter to this method using the MethodParameters property. Displaying the result returned from the method is as simple as creating a binding with this second ObjectDataProvider:
This is a good start, but I would like to allow users to enter their own weight in the TextBox, and so that after that Label shows a new value. However, the problem is that I cannot put the Binding description in the MethodParameters property because this property is not a DependencyProperty. In fact, ObjectDataProvider is also not a DependencyObject. As you recall, the goal of Binding should be a Dependency property, although the source can be anything. Fortunately, a way out exists when you want to associate a CLR property with a Dependency property: you can swap the source and target by placing your binding in the Dependency property and setting the Mode Binding property to TwoWay or OneWayToSource. This code shows how to create a TextBox that changes the argument that was passed to the WeightOnPlanet method:
In this situation, I don’t need to do anything so that the binding is Two-Way, because I create a binding with the Text property of the object of the TextBox class; it [binding] is already the Two-Way by default. By default, the bindings will be One-Way in most Dependency properties and Two-Way in those properties where we expect the data to be changed by the user. This default behavior can be overridden by changing the Mode property of Binding.
As I said above, when we create a binding on an ObjectDataProvider, the binding engine automatically looks at the source that is wrapping, and not at the ObjectDataProvider itself. In this situation, this presents some problem for us, because we want to contact the MethodParameters property of the ObjectDataProvider. To change the standard behavior, we must set the BindsDirectlyToSource property to true.
The MethodParameters property is an IList, and in our situation we want to bind to the first element of the list, since the WeightOnPlanet method takes only one parameter. We can do this using an indexer, just as we would in a C # code.
I set the UpdateSourceTrigger property to PropertyChanged, so when the method is called, we get a new value whenever the user types something in the TextBox. Other possible values of the UpdateSourceTrigger property are “Explicit” (we must explicitly call the UpdateSource () method on the binding) and “LostFocus” (the source will be updated when the control loses focus), which is the default.
If we were binding to a property of type double, the binding engine would try to automatically convert the Text TextBox's property to type double. However, due to the fact that we are attached to the method, we need to write our own converter. Without it, binding will try to call the WeightOnPlanet method, which takes a string as a parameter, which will lead to an error, because no such method exists. If we look at the Output window in Visual Studio, we will see a debugging message saying that we could not find a method that accepts the parameters that we pass. Here is the code for this converter:
Some of you may be a little puzzled by this converter: should it be StringToDouble or DoubleToString? The Convert method is called when data is being transferred from the source (double) to the target (string), and the ConvertBack method is called when the transfer is in the opposite direction. And so, we need a DoubleToString converter, and not some other.
And what happens if the user enters an incorrect weight value? He can enter a negative number, or a string containing not only digits, or he can enter nothing at all. And, if the situation is this, I do not want to let the binding begin to transfer data to the source. I want to create my own logic, which will not only prevent binding from transmitting data, but also warn the user that the value entered by him is incorrect. This can be done using the Validation function in data binding. I wrote a ValidationRule that validates the values and added it to the property in the following way:
WeightValidationRule is a descendant of ValidationRule and overrides the Validate method in which I described the logic I need:
Now, entering the wrong value causes a red border to appear around the TextBox. However, I want to notify the user of the message that is contained in the ValidationResult. Moreover, I would like a tooltip to appear with an error message when the user does something wrong. This can all be done in XAML, using styles and triggers:
Validation.HasError is an attached Dependency property that becomes true whenever at least one ValidationRule returns an error. Validation.Errors is also a nested Dependency property that contains a list of errors for a particular element. In this case, we know that a TextBox can have only one error (since it has only one rule), which means we can safely associate ToolTip with the first error in this list. “{RelativeSource Self}” simply means that the source of our binding is the TextBox itself. Note that parentheses are used in the description of the Path property — they must be used whenever we bind to a nested Dependency property. In Russian, “Path = (Validation.Errors) [0] .ErrorContent” means that we are looking for the attached property Validation.
If you try to enter something other than a number in the range from 0 to 1000 in the TextBox, you should see a tooltip with an error message.
I wrote an example (which is included in the SDK) that shows some other aspects of validation. There is much more to say about this feature, but I will leave a more detailed explanation for subsequent posts.
You may need it when you need to replace the current source of all your bindings with some other object. If in the resource dictionary you have an object that is used as a source during the binding, there is no way to replace this object with some other object and cause the updating of all the bindings. Removing this object from the resource dictionary and adding a new one with the same x: Key will not cause the bindings to be notified about this.
If this is your case, you can decide to use ObjectDataProvider. If you change the ObjectType property, all bindings to this ObjectDataProvider will be notified that the source object has been updated and the data needs to be updated.
Notice that if you assign the DataContext property of an element that is higher in the element tree, your source object is programmatic, assigning another object will also cause an update of all bindings.
ObjectDataProvider has a property called IsAsynchronous, which allows you to control whether the data will be loaded in the same stream as your program, or in another. By default, for ObjectDataProvider this property is set to false, and for XmlDataProvider it is true.
I plan to discuss this in more detail in one of my future posts, so be prepared.
You can use the source code of this example to write a WPF program that allows users to select a planet, enter their weight and find out their weight on the selected planet. In fact, it is very simple.

Here you can find the project for Visual Studio with the code that was used in the article.
As I describe these possibilities, we will create a small program that will allow people to indicate their weight on Earth and find out how much they will weigh on Jupiter.
When we add the source object directly to resources, the data binding engine calls the default constructor for the type of this object. An object added to the resource dictionary uses a key defined through x: Key. Here is a sample code for this approach:
-
- (…)
* This source code was highlighted with Source Code Highlighter.
Alternatively, you can add an object of the ObjectDataProvider class to resources and use it as a source for binding. The ObjectDataProvider class is a wrapper for your source object that provides some additional functionality. Next, I'll talk about the following notable features of ObjectDataProvider:
- Passing parameters to the constructor;
- Binding to a method (which can take parameters);
- Replacing the source object;
- Asynchronous creation of a source object.
Passing parameters to the constructor
When we add the source object directly to resources, WPF always calls the default constructor for this type. It may happen that you do not have control over the source object, and the class you add does not have a default constructor. For example, this is a class from a third-party library and it is declared as sealed. In this situation, you can create an instance of the class in XAML by using ObjectDataProvider in the following way:
-
-
Jupiter -
* This source code was highlighted with Source Code Highlighter.
This markup creates an instance of the MySource class by calling its constructor and passing it the string “Jupiter” as a parameter. At the same time, an object of the ObjectDataProvider class is also created, which will wrap an object of the MySource class.
MySource has a public property called “Planet” that provides an object of the Planet class whose name matches the string passed to the constructor. In our case, this is “Jupiter”. I want the program to have a Label that communicates with the Name property of the planet. Binding on subproperties can be done in WPF using “dot notation”. In general, it looks like this: Path = Property.SubProperty. You can see this in the following code:
* This source code was highlighted with Source Code Highlighter.
You could look at this definition of binding and think that it does not make sense. It looks as if we are associated with the Name sub-property of the Planet property of the ObjectDataProvider class. But I mentioned above that MySource has a Planet property, while ObjectDataProvider does not. The reason this code works is because the binding engine accesses the ObjectDataProvider in a special way when the Path property of the source object is wrapped (i.e. wrapped). Note that this special handling can also be applied when linking to an XmlDataProvider or CollectionViewSource.
Method binding
MySource has a method that takes as an argument the weight of a person on Earth and calculates the weight of that person on the planet that was passed to the constructor. I want to pass some weight value to a method in XAML and contact its result. This can be done using ObjectDataProvider:
-
-
95 -
* This source code was highlighted with Source Code Highlighter.
Notice that instead of setting the ObjectType property, this time I set the ObjectInstance property. This allows us to reuse the instance of the MySource class that we created in the previous ObjectDataProvider. I also set the MethodName property and passed the parameter to this method using the MethodParameters property. Displaying the result returned from the method is as simple as creating a binding with this second ObjectDataProvider:
* This source code was highlighted with Source Code Highlighter.
This is a good start, but I would like to allow users to enter their own weight in the TextBox, and so that after that Label shows a new value. However, the problem is that I cannot put the Binding description in the MethodParameters property because this property is not a DependencyProperty. In fact, ObjectDataProvider is also not a DependencyObject. As you recall, the goal of Binding should be a Dependency property, although the source can be anything. Fortunately, a way out exists when you want to associate a CLR property with a Dependency property: you can swap the source and target by placing your binding in the Dependency property and setting the Mode Binding property to TwoWay or OneWayToSource. This code shows how to create a TextBox that changes the argument that was passed to the WeightOnPlanet method:
- (…)
-
- (…)
-
- (…)
-
-
-
- (…)
-
-
* This source code was highlighted with Source Code Highlighter.
In this situation, I don’t need to do anything so that the binding is Two-Way, because I create a binding with the Text property of the object of the TextBox class; it [binding] is already the Two-Way by default. By default, the bindings will be One-Way in most Dependency properties and Two-Way in those properties where we expect the data to be changed by the user. This default behavior can be overridden by changing the Mode property of Binding.
As I said above, when we create a binding on an ObjectDataProvider, the binding engine automatically looks at the source that is wrapping, and not at the ObjectDataProvider itself. In this situation, this presents some problem for us, because we want to contact the MethodParameters property of the ObjectDataProvider. To change the standard behavior, we must set the BindsDirectlyToSource property to true.
The MethodParameters property is an IList, and in our situation we want to bind to the first element of the list, since the WeightOnPlanet method takes only one parameter. We can do this using an indexer, just as we would in a C # code.
I set the UpdateSourceTrigger property to PropertyChanged, so when the method is called, we get a new value whenever the user types something in the TextBox. Other possible values of the UpdateSourceTrigger property are “Explicit” (we must explicitly call the UpdateSource () method on the binding) and “LostFocus” (the source will be updated when the control loses focus), which is the default.
If we were binding to a property of type double, the binding engine would try to automatically convert the Text TextBox's property to type double. However, due to the fact that we are attached to the method, we need to write our own converter. Without it, binding will try to call the WeightOnPlanet method, which takes a string as a parameter, which will lead to an error, because no such method exists. If we look at the Output window in Visual Studio, we will see a debugging message saying that we could not find a method that accepts the parameters that we pass. Here is the code for this converter:
- public class DoubleToString : IValueConverter
- {
- public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
- {
- if (value != null)
- {
- return value.ToString();
- }
- return null;
- }
-
- public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
- {
- string strValue = value as string;
- if (strValue != null)
- {
- double result;
- bool converted = Double.TryParse(strValue, out result);
- if (converted)
- {
- return result;
- }
- }
- return null;
- }
- }
* This source code was highlighted with Source Code Highlighter.
Some of you may be a little puzzled by this converter: should it be StringToDouble or DoubleToString? The Convert method is called when data is being transferred from the source (double) to the target (string), and the ConvertBack method is called when the transfer is in the opposite direction. And so, we need a DoubleToString converter, and not some other.
And what happens if the user enters an incorrect weight value? He can enter a negative number, or a string containing not only digits, or he can enter nothing at all. And, if the situation is this, I do not want to let the binding begin to transfer data to the source. I want to create my own logic, which will not only prevent binding from transmitting data, but also warn the user that the value entered by him is incorrect. This can be done using the Validation function in data binding. I wrote a ValidationRule that validates the values and added it to the property in the following way:
-
-
-
* This source code was highlighted with Source Code Highlighter.
WeightValidationRule is a descendant of ValidationRule and overrides the Validate method in which I described the logic I need:
- public class WeightValidationRule : ValidationRule
- {
- public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
- {
- // Value is not a string
- string strValue = value as string;
- if (strValue == null)
- {
- // not going to happen
- return new ValidationResult(false, “Invalid Weight - Value is not a string”);
- }
-
- // Value can not be converted to double
- double result;
- bool converted = Double.TryParse(strValue, out result);
- if (!converted)
- {
- return new ValidationResult(false, “Invalid Weight - Please type a valid number”);
- }
-
- // Value is not between 0 and 1000
- if ((result < 0) || (result > 1000))
- {
- return new ValidationResult(false, “Invalid Weight - You’re either too light or too heavy”);
- }
-
- return ValidationResult.ValidResult;
- }
- }
* This source code was highlighted with Source Code Highlighter.
Now, entering the wrong value causes a red border to appear around the TextBox. However, I want to notify the user of the message that is contained in the ValidationResult. Moreover, I would like a tooltip to appear with an error message when the user does something wrong. This can all be done in XAML, using styles and triggers:
- Value=”{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}”/>
* This source code was highlighted with Source Code Highlighter.
Validation.HasError is an attached Dependency property that becomes true whenever at least one ValidationRule returns an error. Validation.Errors is also a nested Dependency property that contains a list of errors for a particular element. In this case, we know that a TextBox can have only one error (since it has only one rule), which means we can safely associate ToolTip with the first error in this list. “{RelativeSource Self}” simply means that the source of our binding is the TextBox itself. Note that parentheses are used in the description of the Path property — they must be used whenever we bind to a nested Dependency property. In Russian, “Path = (Validation.Errors) [0] .ErrorContent” means that we are looking for the attached property Validation.
If you try to enter something other than a number in the range from 0 to 1000 in the TextBox, you should see a tooltip with an error message.
I wrote an example (which is included in the SDK) that shows some other aspects of validation. There is much more to say about this feature, but I will leave a more detailed explanation for subsequent posts.
Replacing a source object
You may need it when you need to replace the current source of all your bindings with some other object. If in the resource dictionary you have an object that is used as a source during the binding, there is no way to replace this object with some other object and cause the updating of all the bindings. Removing this object from the resource dictionary and adding a new one with the same x: Key will not cause the bindings to be notified about this.
If this is your case, you can decide to use ObjectDataProvider. If you change the ObjectType property, all bindings to this ObjectDataProvider will be notified that the source object has been updated and the data needs to be updated.
Notice that if you assign the DataContext property of an element that is higher in the element tree, your source object is programmatic, assigning another object will also cause an update of all bindings.
Asynchronous creation of a source object
ObjectDataProvider has a property called IsAsynchronous, which allows you to control whether the data will be loaded in the same stream as your program, or in another. By default, for ObjectDataProvider this property is set to false, and for XmlDataProvider it is true.
I plan to discuss this in more detail in one of my future posts, so be prepared.
You can use the source code of this example to write a WPF program that allows users to select a planet, enter their weight and find out their weight on the selected planet. In fact, it is very simple.

Here you can find the project for Visual Studio with the code that was used in the article.