I was trying out the November CTP of the WinFX bits today, and came across a little gotcha with threading and updating UI elements from code behind. I thought I'd create a basic Xaml application and wire up a clock that updates every second and bind it to a TextBlock control.
After first of all trying to initialise the timer just after InitializeComponent (this fails by the way - the <Page> element has a "Loaded" attribute which fires when the element is "laid out, rendered and ready for interaction." instead) - I created a XamlLoaded method, added a reference to System.Timers, created a new Timer() in the same way as in good old .NET WinForms.
Sadly, when running the application I was presented with the following:
System.InvalidOperationException: The calling thread may not access this object because the object is owned by a different thread.
at System.Windows.Threading.Dispatcher.VerifyAccess()
at System.Windows.Threading.DispatcherObject.VerifyAccess()
at System.Windows.Media.VisualOperations.GetChildren(Visual reference)
at System.Windows.Controls.UIElementCollection.Insert(Int32 index, UIElement element)
The cause is that regular timers run in a different thread to the main app, and hence you need to use a DispatcherTimer instead.
working example:
using System.Windows.Threading;
[...]
void XamlLoaded(object sender, RoutedEventArgs e)
{
DispatcherTimer dt = new DispatcherTimer();
dt.Tick += new EventHandler(UpdateClock);
dt.Interval = new TimeSpan(0,0,1); //interval = every second
dt.Start();
}
void UpdateClock(object sender, EventArgs e)
{
CurrentTime.Text = DateTime.Now.ToLongTimeString();
}