1

進行状況を示す WPF ポップアップを表示しようとしています。

問題は、Thread.Sleep が完了する前にポップアップが表示されないことです。これは単なる例です。私のプログラムでは、同期的に実行する必要がある複雑な IO および DB ロジックがあり、進行状況をポップアップに表示する必要があります。

これが私のコード例です:

    private ProgressBar m_ProgressBar;

    private void buttonDoWork_Click(object sender, RoutedEventArgs e)
    {
        var progressPopup = new Popup { PopupAnimation = PopupAnimation.Fade, StaysOpen = true, Height = 150, Width = 260 };
        m_ProgressBar = new ProgressBar
                              {
                                  HorizontalAlignment = HorizontalAlignment.Stretch,
                                  VerticalAlignment = VerticalAlignment.Stretch
                              };

        progressPopup.Child = m_ProgressBar;

        progressPopup.IsOpen = true;

        Thread.Sleep(5000);
        this.m_ProgressBar.Value = 25;
        Thread.Sleep(5000);
        this.m_ProgressBar.Value = 50;
        Thread.Sleep(5000);
        this.m_ProgressBar.Value = 75;
        Thread.Sleep(5000);
        this.m_ProgressBar.Value = 100;
    } 

アップデート

問題は、メイン スレッドをブロックするロジックがメイン スレッドにとどまる必要があることです。他にできることはありません。別のスレッドでポップアップを実行する方法はありますか?

4

3 に答える 3

4

使用する

Dispather.BeginInvoke(new Action(()=>{ this.m_ProgressBar.Value = progress; });

UI スレッドの進行状況バーを更新します。

一般に、このようにコードを織り込むべきではありません (UI とロジックが混同されています)。

イベントを発生させて進行状況を報告する BackgroundWorker または Task を使用できます。

編集

明確にするために:ViewModel /コードから変更されたデータを公開し、イベント(PropertyChanged)を発生させて、UIをそれらの値にバインドできるようにします。これにより、UI とコードを分離したままにすることができます。

于 2012-05-22T13:27:36.350 に答える
0

BackgroundWorkerUI スレッドとバックグラウンド スレッドの分割が非常に明確な場合に使用します。

たとえば、これを使用して、ProgressChangedイベント (UI スレッドに属する) に署名し、バックグラウンド プロセスについてユーザーに通知したいことを何でも行うことができます。

于 2012-05-22T13:41:34.930 に答える
0

問題は、表示、描画、イベントへの応答などのためにメッセージをディスパッチできるように、WPF がメッセージ ループを回転させる必要があることbuttonDoWork_Clickです。できるだけ早く終了するようにコードを構成する必要があります。そうしないと、UI 全体がフリーズします。

さらに、その単一のメソッド内で進捗値をインクリメントしても、基本的には何もしません。メッセージ ループの観点から見ると、進行状況の値には 100 という 1 つの値しか含まれていませんでした。ProgressBarこれは、クリック イベントが終了する前に に書き込んだ最後の値です。これは、プログレス バーが最終的に更新を許可された時点を認識している唯一の値です。

長時間実行される操作を UI スレッドから取得する必要があります。これが私がアドバイスすることです。

  • クラスを使用しTaskて、ワーカー スレッドで操作を開始します。
  • ワーカー スレッドが進行状況情報を単純な変数に発行するようにします。
  • 選択した間隔で、UI スレッドがタイマーを介して進行状況情報をポーリングするようにします。それに応じて更新しProgressBarます。
于 2012-05-22T14:00:17.997 に答える