Data Binding and Threading
I am data binding XML (XmlDataProvider) to the Content Property on a Label. When the XML changes the Label is updated. This works if the Xml is updated on the UI thread(I used DispatchTimer). If I use a worker thread (Thread.Timer), the label content does not update and I do not get any exceptions. I can get things to work if I use Dispatcher.Invoke and update the Xml in the delegate. Is ther a way to update the Xml on a worker thread without having to invoke? I will post my code below.
Steve
<
Window.Resources><
XmlDataProviderSource="..\..\Items.Xml"IsAsynchronous="True"x:Key="ItemsXml"/></
Window.Resources><
Grid><
Grid.ColumnDefinitions><
ColumnDefinition/><
ColumnDefinition/><
ColumnDefinition/></
Grid.ColumnDefinitions><
Grid.RowDefinitions><
RowDefinitionHeight="0.333333333333333*" /><
RowDefinitionHeight="0.298584298584299*" /><
RowDefinitionHeight="0.368082368082368*" /></
Grid.RowDefinitions><
LabelHorizontalAlignment="Center"VerticalAlignment="Center">Value 1</Label><
LabelGrid.Column="1"VerticalContentAlignment="Center"HorizontalAlignment="Center">Value 2</Label><
LabelGrid.Column="2"VerticalContentAlignment="Center"HorizontalAlignment="Center"VerticalAlignment="Center">Value 3</Label><
LabelName="label1"Grid.Row="1"HorizontalAlignment="Center"VerticalContentAlignment="Center"Content="{Binding Source={StaticResource ItemsXml},XPath=Items/Item1}"/><
LabelName="label2"Grid.Column="1"Grid.Row="1"VerticalContentAlignment="Center"HorizontalAlignment="Center"Content="{Binding Source={StaticResource ItemsXml},XPath=Items/Item2}"/><
LabelName="label3"Grid.Column="2"Grid.Row="1"HorizontalAlignment="Center"VerticalContentAlignment="Center"Content="{Binding Source={StaticResource ItemsXml},XPath=Items/Item3}" /><
ButtonGrid.Column="1"Grid.Row="2"Margin="11.6666666666667,31.31,10.6666666666667,34"Name="button1"Click="OnClick">ChangeXml</Button></
Grid></
Window>publicpartialclassWindow1 :Window
{
publicXmlDocument doc;
publicRandom r =newRandom();
//DispatcherTimer timer1;
System.Timers.Timer timer;
delegatevoidUIDelegate();
publicXmlDataProvider dp;
//Use timer for worker thread updates and timer1 for UI thread
//Note: This only works with UI thread updates.
public Window1()
{
InitializeComponent();
doc =newXmlDocument();
doc.Load(@"..\..\Items.Xml");
timer =new System.Timers.Timer(100);
timer.Elapsed +=new System.Timers.ElapsedEventHandler(timer_Elapsed);
timer.Enabled =true;
// timer1 = new DispatcherTimer();
//timer1.Interval = new TimeSpan(10000000);
//timer1.Tick += new EventHandler(timer_Tick);
// timer1.Start();
dp = (XmlDataProvider)this.FindResource("ItemsXml");
dp.Document = doc;
Thread.CurrentThread.Name ="Main Thread";
}
void timer_Tick(object sender,EventArgs e)
{
XmlNode root = doc.DocumentElement;
root["Item1"].InnerText = r.NextDouble().ToString();
root["Item2"].InnerText = r.NextDouble().ToString();
root["Item3"].InnerText = r.NextDouble().ToString();
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
XmlNode root = doc.DocumentElement;
root["Item1"].InnerText = r.NextDouble().ToString();
root["Item2"].InnerText = r.NextDouble().ToString();
root["Item3"].InnerText = r.NextDouble().ToString();
this.Dispatcher.Invoke(DispatcherPriority.Background,newUIDelegate(this.UpdateXml));
}
publicvoid UpdateXml()
{
XmlNode root = doc.DocumentElement;
root["Item1"].InnerText = r.NextDouble().ToString();
root["Item2"].InnerText = r.NextDouble().ToString();
root["Item3"].InnerText = r.NextDouble().ToString();
}
void OnClick(object sender,RoutedEventArgs e)
{
XmlNode root = doc.DocumentElement;
root["Item1"].InnerText = r.NextDouble().ToString();
root["Item2"].InnerText = r.NextDouble().ToString();
root["Item3"].InnerText = r.NextDouble().ToString();
}
}

