In this blog post we will see how to create a subclass of DataSourceProvider which loads the text in a resource file, so that we may bind to it.
There are two very powerful ways to load an external data source in XAML, ObjectDataProvider and XmlDataProvider. The former allows you to create an object via a parameterized constructor, invoke a method on an object, or invoke a static method – and then bind against whatever data it provides. The latter allows you to load an XML file into an XmlDocument and bind against it. Both of these classes derive from the DataSourceProvider base class. WPF’s binding system has special knowledge of DataSourceProvider, and implicitly binds to its Data property.
We can create our own DataSourceProvider to perform tasks other than those listed above. In this demo we will create a subclass which loads the text in a resource file. That class will then be used to allow a TextBox to bind to the contents of a file, without needing to write a line of code.
Suppose that we are creating an application which must allow the user to enter and save a weekly status report. One requirement of ours is that when the user creates a new status report they should be given some default text which makes it easier for them to write their report. Here is a screenshot of a new status report in our app:
The text seen in the TextBox above is a status report “template.” That template text is data, and data should generally be stored outside of the UI declaration. In other words, we do not want to write that status report template in a XAML file, or in the code-behind. It would be better if we could store it in a resource file, which is baked into our application’s assembly. It would be even better if we had a simple and reusable means of loading the status report template directly into the TextBox, without needing to write code to load the status report text and put it in the TextBox. The rest of this post demonstrates one way to achieve that goal.
First we create a text file in our project and put the status report template in it. Here is StatusReportTemplate.txt:
Next we need to create the DataSourceProvider subclass which loads that text out of the file and exposes it. That class is seen below:
Now that we have our custom data source provider, let’s see how to bind a TextBox’s Text property to it:
The Text binding has three settings applied to it, as discussed below.
Its Mode is set to ‘OneTime’ so that once the template text has been loaded, the binding system knows that it will never need to update the binding again.
The Path property is set to “.”, meaning that we are binding directly to the value exposed by the ResourceTextProvider’s Data property. If we were returning a complex type, we would specify the property name on the returned object to bind to. Binding to “.” simply means to bind against the data object itself (in this case, bind to the string which contains the status report template).
The Binding’s Source is set to an instance of the custom data source provider. The provider’s ResourceFile property is set to the name of the text file which contains the status report template.
That’s all there is to it. Now that the ResourceTextProvider class exists, it could be reused in many situations to provide the text of a resource file.
Download the demo project here: Custom DataSourceProvider (demo project) Be sure to change the file extension from .DOC to .ZIP and then decompress it.