Refreshing the Data in Data Bound Controls in WPF


Received this question:

 

I need to bind some objects to an XML file – and refresh the binding whenever the XML source changes. By default my application (c# .exe) reads the source values romthe XML once at start-up, and doesn’t notice subsequent changes.

I didn’t see an easy way to do this in Markup but with two lines of code you can call the refresh on the XMLDataProvider:

 

 

private void Button1click(object sender, RoutedEventArgs e)

{

XmlDataProvider DataProv = (XmlDataProvider)this.Window.FindResource(“QuestionsDS”);
DataProv.Refresh();
//this.LayoutRoot.DataContext = DataProv;

}

 

And the markup is:

 

 

<Window

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

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

xmlns:d=”http://schemas.microsoft.com/expression/blend/2006″ xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006″ mc:Ignorable=”d”

x:Class=”UntitledProject18.Window1″

x:Name=”Window”

Title=”Window1″

Width=”640″ Height=”480″>

<Window.Resources>

<XmlDataProvider x:Name=”Chuck” x:Key=”QuestionsDS” d:IsDataSource=”True” Source=”C:\teched\XMLFile1.xml”/>

</Window.Resources>

<Grid x:Name=”LayoutRoot”>

<ListBox Margin=”144,93,280,151″ ItemsSource=”{Binding Mode=Default, Source={StaticResource QuestionsDS}, XPath=/Questions/Question/@Wrong_answer2}”/>

<Button HorizontalAlignment=”Left” Margin=”88,23,0,0″ VerticalAlignment=”Top” Width=”154″ Height=”57″ Content=”Button” x:Name=”Button1″ Click=”Button1click”/>

</Grid>

</Window>


Comments (6)

  1. The person got back to me and they wanted this automated – so this code in a timer looks like:

      private void Window_load(object sender, RoutedEventArgs e)

           {

               System.Timers.Timer timer = new System.Timers.Timer();

               timer.Interval = 1000; // 1 second updates

               timer.Elapsed += timer_Elapsed;

               timer.Start();

           }

           void timer_Elapsed(object sender, EventArgs e)

           {

               XmlDataProvider DataProv = (XmlDataProvider)this.Window.FindResource("QuestionsDS");

               DataProv.Refresh();

               //this.LayoutRoot.DataContext = DataProv;

           }

  2. shanemo says:

    "The Person"! I guess I should be flattered. Shane

  3. Joseph pointed out a better way would be to use the the FileSystemWatcher class

    Code below:

    System.IO.FileSystemWatcher watcher = null;

           private void Window_load(object sender, RoutedEventArgs e)

           {

               watcher = new System.IO.FileSystemWatcher("c:\teched", "*.xml");

               watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite

                   | NotifyFilters.FileName | NotifyFilters.DirectoryName;

               // Add event handlers

               watcher.Changed += new FileSystemEventHandler(File_OnChanged);

               // Begin watching for XML file

               watcher.EnableRaisingEvents = true;

           }

           public void File_OnChanged(object source, FileSystemEventArgs e)

           {

               XmlDataProvider DataProv = (XmlDataProvider)this.Window.FindResource("QuestionsDS");

               DataProv.Refresh();

           }

  4. And as Andrew Parsons pointed out the VB code to do this:

      Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click

           Dim da As XmlDataProvider

           da = DirectCast(LayoutRoot.FindResource("QuestionsDS"), XmlDataProvider)

           da.Refresh()

       End Sub

  5. I am playing with the code for my Teched Hands on labs to dynamically rebind controls at run time and

  6. I am playing with the code for my Teched Hands on labs to dynamically rebind controls at run time and