Programmatic Access to XmlDataProvider

It’s pretty easy to set up an XmlDataProvider as a resource in your WPF application. This lets you databind controls to XML data islands pretty easily. The following XAML puts an XML data island into my application.

    <Application.Resources>

        <XmlDataProvider x:Key="aboutProvider" XPath="ApplicationInfo">

            <x:XData>

                <ApplicationInfo xmlns="">

                    <Title>About WPF AboutBox[xml]</Title>

                    <Product>Sample WPF AboutBox[xml]</Product>

                    <Company>Microsoft Samples[xml]</Company>

                    <Copyright>Copyright © 2009 - Pedro Silva[xml]</Copyright>

                    <Description>blah, blah, blah

                    </Description>

                    <Version>1.0.0.0[xml]</Version>

                    <Link Uri="https://blogs.msdn.com/pedrosilva">License Terms</Link>

                </ApplicationInfo>

            </x:XData>

        </XmlDataProvider>

    </Application.Resources>

 

This embeds the XML into the application as a resource. It is also possible to reference a loose XML file of the same structure (if you’d prefer)… Using the following syntax:

        <XmlDataProvider x:Key="aboutProvider" XPath="ApplicationInfo" Source="Data.xml">

 

This all works pretty smoothly when binding in XAML because it can be used as a StaticResource or DynamicResource. And, particular properties can be bound by their XPath equivalent. I’ve used this for a couple of quick projects without much trouble, but I ran into an issue when trying to access this XML data island programmatically.

When using the following code, the provider.Document unexpectedly returns null:

    XmlDataProvider provider = App.Current.TryFindResource("aboutProvider") as XmlDataProvider;

    if (provider != null)

    {

        XmlDocument doc = provider.Document;

        ...

    }

This is because the document hasn’t been loaded correctly. And, it’s configured to be loaded asynchronously, which poses a little bit of a problem in this code. There are two work-arounds I found to make this function as expected.

 In XAML, you can set the following properties appropriately so that load happens as expected (notice it’s the only difference from the XAML specified above):

    <XmlDataProvider x:Key="aboutProvider" XPath="ApplicationInfo" IsAsynchronous="False" IsInitialLoadEnabled="True">

 

You can also do it in code, as follows:

    XmlDataProvider provider = App.Current.TryFindResource("aboutProvider") as XmlDataProvider;

    if (provider != null)

    {

        provider.IsInitialLoadEnabled = true;

        provider.IsAsynchronous = false;

        provider.Refresh();

        xmlDoc = provider.Document;

    }

 

In the code that I’m using, I’ve preferred to go with the XAML definition of it, as that seems to work more consistently than setting the properties programmatically.