1

Canvasオブジェクト(名前:canvas)を含むWPFウィンドウがあります。

ユーザーがボタンをクリックすると、大量のデータが読み込まれ、時間がかかります。

そのため、UIをフリーズして、バックグラウンドスレッドを作成したくありません。

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

このBuildGraph関数内で、データをロードし、いくつかの図形を作成して、これらの図形をキャンバスに配置します。これらの形状を作成するには、スレッドがSTAである必要があります。

ディスパッチャーを使用してtextBox、progressbarを更新します。それらはすべて大丈夫です。

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

ラベルの内容を正しく取得できます。

しかし、問題は、UIElementCollectionであるキャンバスChildrenを取得できないことです。

したがって、この操作は成功しません。canvasChildren =(UIElementCollection)Dispatcher.Invoke(DispatcherPriority.Send、new getChildrenDelegate(obtainChildren));

そしてこれも失敗します

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

ここで何が問題になっていますか?ラベルコントロールを取得できるのに、キャンバスコントロールを取得できないのはなぜですか?

奇妙なことに、Dispatcherの助けがなくてもcanvas.ActualHeightを直接使用できます。

4

1 に答える 1

1

別のスレッドでUIElementを変更することはできません。

また、スレッドAでUIElementを作成し、それをスレッドBの親に割り当てることもできません。

要素を作成し、親と同じスレッドに割り当てる必要があります。

バックグラウンドスレッドでブラシを作成し、呼び出し元のスレッドのオブジェクトにブラシを割り当てたときに、同じ問題が発生しました。

于 2012-07-13T22:09:06.267 に答える