3

My BusyIndi​​catorは、DomainDataSourceがデータを取得するときに正常に機能します。しかし、コードでIsBusyをtrueに設定すると、コントロールは表示されません。IsBusy = trueに設定した後でSilverlight BusyIndi​​catorが表示されないのはなぜですか?

私はSilverlight 4とツールキットBusyIndi​​catorを使用しています。 XAMLでは、BusyIndi​​cator.IsBusyプロパティを、私のDomainDataSourceコントロールのIsBusyプロパティにバインドしました。 BusyIndi​​catorコントロールは、メイングリッド(LayoutRoot)とすべての子コントロールをラップします。

<toolkit:BusyIndicator IsBusy="{Binding ElementName=labSampleDomainDataSource, Path=IsBusy}" Name="busyIndicator1"> 
<Grid x:Name="LayoutRoot"> 

</Grid> 
</toolkit:BusyIndicator> 

問題は、busyIndi​​cator1 = trueを設定したときにBusyIndi​​catorが表示されないことです。ボタンのクリックイベント。私が間違って何をしているのか?

+1

バインディングを削除するとどうなりますか? – herzmeister

+0

バインディングを削除するとBusyIndi​​catorが表示されません。しかし、UIの操作は、ボタンのクリックイベントが終了するまでロックされている/無効になっているようです。また、私がIsBusy = falseをコメントアウトすると気づいた。 (IsBusy = true;のままにしておくと)、Clickイベントコードが終了した後にBusyIndi​​catorが表示されます。もちろん、BIも消えず、私のプログラムは役に立たない。なぜこのように振る舞っているのか分かりません。 – DeveloperDan

+1

レイアウトの問題と思われます。 BusyIndi​​catorはSilverlightアプリケーションのルートにありますか?または、XAML全体を投稿できますか? – herzmeister

答えて

7

UIはUIスレッドで非常に自然に更新されます。ボタンのクリックなどのイベントは、UIスレッドでも実行されます。

場合によっては、プロパティの変更やメソッド呼び出しによってコントロールがUIスレッドにディスパッチされることがあります。つまり、呼び出されるメソッドは、UIスレッドが実行可能になるまで(実際にキューに入れられているものが実行されるまで)実際には発生しません。 IsBusyがこのカテゴリに該当します。

あなたのコードがUIスレッドで終了した場合にのみ、UIはそのUIを更新する機会を得ます。 UIスレッドで長時間実行してはいけません。あなたのケースでは、あなた自身の入札を行うためにスレッドを結びつけ、この作業を完了させるために使用できるこの1つのスレッドがUIに残ったままにしておきます。

代わりにBackgroundWorkerクラスを使用して、別のスレッドで実行されるDoWorkイベントの重い作業をすべて行う必要があります。

myButton_Click(object sender, RoutedEventArgs e) 
{ 
    isbusyindicator1.IsBusy = true; 
    var bw = new BackgroundWorker(); 
    bw.DoWork += (s, args) => 
    { 
     //Stuff that takes some time 
    }; 
    bw.RunWorkerCompleted += (s, args) => 
    { 
     isbusyindicator1.IsBusy = false; 
    }; 
    bw.RunWorkerAsync(); 
} 

このクリックイベントは非常に迅速に完了し、実際の作業がバックグラウンドスレッドで行われている間にUIスレッドを使用してUIを更新できるようになります。完了するとIsBusyはクリアされます。

+0

ありがとう!優れた説明 - 私は答えとしてマークしました。しかし、BackgroundWorkerでは時間のかかる作業が許されているかどうかに関して新たな疑問が生じます。私は((IEditableCollectionView)DomainDataSource.DataView).AddNewを呼び出して、返されたEFエンティティにデフォルト値を設定しようとしています。何らかの理由で、私はBackgroundWorker.DoWorkプロセスにそのコードを置くと何も起こりません。おそらく、私は、DomainDataSourceの新しいレコードを事前に設定するより良い方法を学ぶ必要があります。その間、私はthis.Cursor = Cursorsで私のbutton_clickを開始することができることを発見しました。これで終了してください.Cursor = Cursors.Arrow。 – DeveloperDan

+0

@DeveloperDan:賢明な答えのためにそこに変数が多すぎます。バランスをとっておくためには、2つの基本原則があります。重い計算とブロック操作をUIスレッドから外し、UIスレッド自体でUI自体を変更する必要があります。このDomainData、View、EFのすべてに入ると、意図したパターンで使用していないと毛がかってしまいます。 – AnthonyWJones

関連する問題