I have a WPF window, which contains a Canvas object (name: canvas).
When the user clicks a button, it will load large amount of data, which takes long time.
So, I dont want the UI be freezed and create a background thread.
Thread thread = new Thread(new ThreadStart(BuildGraph));
thread.SetApartmentState(ApartmentState.STA);\
thread.IsBackground = true;
thread.Start();
Within this BuildGraph function, I load data, create some shapes, and put these shapes into canvas. The thread has to be STA in order to create those shapes.
I use dispatcher to update textBox, progressbar. All of them are fine.
String txt = (String)Dispatcher.Invoke(DispatcherPriority.Send, (DispatcherOperationCallback)delegate { return labelStatus.Content; }, null);
I can obtain the label content correctly.
But, the problem is I cannot obtain the canvas Children, which is a UIElementCollection.
So, this operation is not success.
canvasChildren = (UIElementCollection)Dispatcher.Invoke(DispatcherPriority.Send, new obtainChildrenDelegate(obtainChildren));
And this fails too
Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(() => canvas.Children.Add(node)));
What’s wrong here? Why can I obtain the label control, but not the canvas control?
The strange thing is I can directly use canvas.ActualHeight without the Dispatcher’s help.
You cannot modify a UIElement on another thread.
You also cannot create a UIElement on thread A, and assign it to a parent on thread B.
You’ll have to create the element and assign it on the same thread as the parent.
I ran into the same issue, when I had a background thread create a Brush, and then assign the brush to an object on the calling thread.