Infosys Microsoft Alliance and Solutions blog

« Why is the concept of a list so important in SharePoint | Main | MS Software Factories... »

WPF - Updating XmlDataProvider when source XML changes

Some days back i had answered a question on the WPF Forum on how to ensure that when the base XML file changes, the XmlDataProvider is udpated and hence the bound control on the UI.

The key is to set a watch on the particular XML file for changes and then update the provider appropriately. See details here. This solution works fine, but I didn't particularly like my initial code that I wrote since the FileSystemWatcher was set externally. It would be better if this could be self contained within the XmlDataProvider itself.  

I hence decided to write my own XmlDataProvider for this purpose. Well, not write entirely, but obviously extend the existing provider. Following is the class that I wrote for this purpose. Since all I am really interested in is to get the FileSystemWatcher setup, I modify the Source property implementation and on the file change event, I force a refresh on the provider.

    public class MyXmlDataProvider : XmlDataProvider

    {

        public new Uri Source

        {

            get { return base.Source; }

            set

            {

                base.Source = value;

 

                FileSystemWatcher watcher = new FileSystemWatcher();

                //set the path of the XML file appropriately as per your requirements

                watcher.Path = AppDomain.CurrentDomain.BaseDirectory;

 

                //name of the file i am watching

                watcher.Filter = value.OriginalString;

 

                //watch for file changed events so that we can refresh the data provider

                watcher.Changed += new FileSystemEventHandler(file_Changed);

 

                //finally, don't forget to enable watching, else the events won't fire           

                watcher.EnableRaisingEvents = true;

            }

        }

 

        void file_Changed(object sender, FileSystemEventArgs e)

        {

            base.Refresh();

        }

    }

This is all that is required. Using this in XAML is pretty straightfoward and following is a sample XAML.

<Window x:Class="TestWPFApp.XmlRefreshTest"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   xmlns:local="clr-namespace:TestWPFApp" 

   Title="XmlRefreshTest" Height="300" Width="300">

    <Window.Resources>

        <local:MyXmlDataProvider x:Key="xmlFromFile" Source="PersonXml.xml" XPath="persons/person" />

    </Window.Resources>

    <Grid>

        <ListView ItemsSource="{Binding Source={StaticResource xmlFromFile}}" x:Name="list" >

            <ListView.View>

                <GridView>

                    <GridViewColumn Header="FirstName" DisplayMemberBinding="{Binding XPath=@firstname}" />

                    <GridViewColumn Header="LastName" DisplayMemberBinding="{Binding XPath=@lastname}" />

                    <GridViewColumn Header="Age" DisplayMemberBinding="{Binding XPath=@age}" />

                </GridView>

            </ListView.View>

        </ListView>

    </Grid>

</Window>

For my testing, I used the following Xml file. Note that I had marked the Xml as Content and Copy if newer in its properties to ensure that the Xml file is available in the output directory.

<?xml version="1.0" encoding="utf-8" ?>

<persons xmlns="">

    <person firstname="Atul" lastname="Gupta" age="35" />

    <person firstname="Sidharth" lastname="Ghag" age="30" />

    <person firstname="Virendra" lastname="Wadekar" age="30" />

</persons>

Comments are welcome !

Comments

Your code works well but I have to deal with a dataprovider source not declared in the XAML code. I declare the source coding like this: mldDP.source = new URI (".../..."); And thus the listView is not update anymore... Have you got an idea?

Yohann, can you provide more details on your issue and possibly a sample code to reproduce the problem?

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Please key in the two words you see in the box to validate your identity as an authentic user and reduce spam.

Subscribe to this blog's feed

Follow us on

Blogger Profiles

Infosys on Twitter