1

我有一个 WPF 窗口,其中包含一个 Canvas 对象(名称:canvas)。

当用户点击一个按钮时,会加载大量数据,耗时较长。

所以,我不希望 UI 被冻结并创建一个后台线程。

Thread thread = new Thread(new ThreadStart(BuildGraph));        
thread.SetApartmentState(ApartmentState.STA);\
thread.IsBackground = true;
thread.Start();

在这个 BuildGraph 函数中,我加载数据,创建一些形状,然后将这些形状放入画布中。线程必须是 STA 才能创建这些形状。

我使用调度程序来更新文本框、进度条。他们都很好。

String txt = (String)Dispatcher.Invoke(DispatcherPriority.Send, (DispatcherOperationCallback)delegate { return labelStatus.Content; }, null);

我可以正确获取标签内容。

但是,问题是我无法获得作为 UIElementCollection 的画布 Children。

所以,这个操作是不成功的。canvasChildren = (UIElementCollection)Dispatcher.Invoke(DispatcherPriority.Send, new gainChildrenDelegate(obtainChildren));

这也失败了

Dispatcher.BeginInvoke(DispatcherPriority.Send, new Action(() => canvas.Children.Add(node)));

这里有什么问题?为什么能得到label控件,却不能得到canvas控件?

奇怪的是我可以在没有 Dispatcher 帮助的情况下直接使用 canvas.ActualHeight。

4

1 回答 1

1

您不能在另一个线程上修改 UIElement。

您也不能在线程 A 上创建 UIElement,并将其分配给线程 B 上的父级。

您必须创建元素并将其分配在与父级相同的线程上。

当我有一个后台线程创建一个画笔,然后将画笔分配给调用线程上的一个对象时,我遇到了同样的问题。

于 2012-07-13T22:09:06.267 回答