I realized a WPF Control Library to use as an Addin in MS Office 2007.
The WPF-Class is instantiated by the host and creates a toolbar with some buttons in MS Office. By clicking a button the WPF window should appear. The problem is that I always receive the following error: "The calling thread must be STA, because many UI components require this." My main function is marked as [STAThread].
It seems that the button_Click event runs in an other thread than the UI thread.
I tried to use a dispatcher, but that didn't work.
Dispatcher.CurrentDispatcher.Invoke(
System.Windows.Threading.DispatcherPriority.Normal,
new Action(
delegate()
{
wpfform wf = new wpfform();
wf.ShowDialog();
));
I think the module gets a wrong dispatcher, but I don't know exactly.
Next I tried to start the window in an separate STA thread and join the thread, but this didn't work either. As I removed the [STAThread]
Attribute from the main function the window started, but i was unable to access office (because i'm in a separate thread).
Thread workerThread = new Thread(_ShowDialog);
workerThread.SetApartmentState(ApartmentState.STA);
workerThread.Start();
workerThread.Join();
Is it possible to determine the UI thread and create a dispatcher for this thread, or how can I come back to the UI thread?
You can access the current UI thread via Dispatcher. UIThread . You can either use Post or InvokeAsync , if you want to run a job on the UI thread. Use Post when you just want to start a job, but you don't need to wait for the job to be finished and you don't need the result.
WPF supports a single-threaded apartment model that has the following rules: One thread runs in the entire application and owns all the WPF objects. WPF elements have thread affinity, in other words other threads can't interact with each other.
The thread affinity is handled by the Dispatcher class, a prioritized message loop for WPF applications. Typically your WPF projects have a single Dispatcher object (and therefore a single UI thread) that all user interface work is channeled through.
So thread affinity means that the thread, in this case the UI thread that instantiates an object is the only thread that can access its members. So for example, dependency object in WPF has thread affinity.
You will need to use the application UI dispatcher. Try using:
Application.Current.Dispatcher.Invoke(...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With