2011-11-14 30 views
7

は:フォース前に再描画の実行時間の長い操作

Private Function Button_OnClick 

    Button.Enabled = False 

    [LONG OPERATION] 

End Function 

長い操作はコントロールを再描画からUIスレッドを防ぐため、その後のボタンは、グレー表示されません。バックグラウンドスレッド/ディスパッチャを起動するのが正しい設計だとわかっていますが、単純な操作ではあまりにも面倒です。

ボタンを無効状態で強制的に再描画するにはどうすればよいですか? Buttonで.UpdateLayout()を試みましたが、効果がありませんでした。私はまた、WinFormsを使用しているときに正常に動作するSystem.Windows.Forms.DoEvents()を試しましたが、何の効果もありませんでした。

答えて

8

次のコードは、探していることを行います。しかし私はそれを使用しませんでした。長時間の操作にはBackgroundWorkerクラスを使用してください。使いやすく安定しています。
ここでコード:

public static void ProcessUITasks() {    
     DispatcherFrame frame = new DispatcherFrame(); 
     Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate(object parameter) { 
      frame.Continue = false; 
      return null; 
     }), null); 
     Dispatcher.PushFrame(frame); 
    } 

HereあなたはBackgroundWorkerのを使用する方法のサンプルがあります。

+0

彼はディスパッチャー/バックグラウンドワーカーを認識しているが、ディスパッチャー/バックグラウンドワーカーを使用していないことはかなり明確です。 – edvaldig

+2

@edvaldig:私はそれを使用しないように下線を引いていますが、私はこれがあなたから-1の価値があるとは思わない。私のコードがうまくいかなければ、-1を与えてください。しかし、いくつかのアドバイスを与えるのではありません。私はこれが公正だとは思わない。 – HCL

+1

あなたが正しいです、私はそれについて、あまりにも速かったコメントするためにアップヴォートを補足してください:) – edvaldig

0

InvalidateVisual(); @HCLが正しいです...これをしないでください

あなたが言うように、バックグラウンドスレッド/ディスパッチャーを使い始め、UIスレッドをブロック解除したままにしておく方が良いです。マイクロソフトのReactive Extensions libraryを高度な非同期UIプログラミングのために検討することを検討してください。

+0

これは機能しません。無効化は、再描画される領域のみを無効にします。しかしそれは絵画ではありません。 – HCL

+0

@HCL、私のためにうまくいく、関数のドキュメントを参照してください:要素のレンダリングを無効にし、完全な新しいレイアウトのパスを強制します。 OnRenderは、レイアウトサイクルが完了した後に呼び出されます。 – edvaldig

+0

スレッドがブロックされていますか?私は最後に.net3.5SP1の下でそれをテストしました。現時点では機能していません。今動作している場合、4.0で動作を変更しているに違いありません。しかし、これは私にとって大きな驚きです。 – HCL

0

Windows.Formsでは、Button.Refresh()とすることができます。

Windows.FormsまたはWPFでは、メッセージポンプに出力して再描画させることができます。 Async/Awaitは、HCLの答えの不快感なしにこれを行うことができるように設計されています。

Private Async Function Button_OnClick 

    Button.Enabled = False 

    Await Task.Yield 

    [LONG OPERATION] 

End Function 
関連する問題