views:

248

answers:

3

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?

+3  A: 

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.

Heinzi
+2  A: 

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);
Daniel Earwicker
A: 

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.

Dr. WPF