I'm trying to write a WPF application that will update a set of text boxes and labels at run time using threads but the problem is that when ever a thread tries to update the text boxes and labels I get the following error: "The calling thread cannot access this object because a different thread owns it." Is it possible to update the control at run time?
Yes, but you have to update the UI elements in the UI thread using Dispatcher.Invoke.
Example in C#: Instead of
myTextBox.Text = myText;
use
Dispatcher.Invoke(new Action(() => myTextBox.Text = myText));
VB.NET (before version 4) does not support anonymous methods, so you'll have to workaround it with an anonymous function:
Dispatcher.Invoke(Function() UpdateMyTextBox(myText))
...
Function UpdateMyTextBox(ByVal text As String) As Object
myTextBox.Text = text
Return Nothing
End Function
Alternatively, you can start your background threads using the BackgroundWorker class, which support updates in the UI through the ProgressChanged
and RunWorkerCompleted
events: Both events are raised in the UI thread automatically. An example for using BackgroundWorker can be found here: SO question 1754827.
Controls in WPF have a Dispatcher
property on which you can call Invoke
, passing a delegate with the code you'd like to execute in the context of the GUI thread.
myCheckBox.Dispatcher.Invoke(DispatcherPriority.Normal,
() => myCheckBox.IsChecked = true);
For a thorough explanation of the WPF threading model, including how the Dispatcher works, jump to minute 17 in this video from the Hiking Mount Avalon workshop at Mix09.