0

アプリの進行状況バー (この場合は WPF 進行状況バー) を更新する専用のクラスを作成したいと思います。私はこのようなことをしました:

public class ProgressBarUpdate : IDisposable
{
    private readonly double _delta;
    private int _current;
    private int _total;
    private readonly ProgressBar _pb;

    public ProgressBarUpdate(ProgressBar pb, int total)
    {
        _pb = pb;
        _total = total;
        // the pb.Maximum is a double so it doesn`t get truncated
        _delta = _pb.Maximum / total; 
        _current = 0;
        _pb.Visibility = Visibility.Visible;

    }
    public void Dispose()
    {
        _pb.Visibility = Visibility.Collapsed;
        _current = 0;
    }
    public void UpdateProgress()
    {
        _pb.Value =(int)_delta * (++_current);
    }

私はこのように(UIスレッドで)使用します:

using (var pu = new ProgressBarUpdate(pb, totalCount)
{
  for (x=0; x<totalCount; x++)
  {
     // operations here 
     pu.UpdateProgress()
  }
}

しかし、おそらくブロックされている UI が正しく更新されていません。すべての進行状況を表示する最良の方法は何ですか?

4

4 に答える 4

0

スレッドの使用を避けたいと言っていたのは、不要な複雑さを望まないためだと思いますが、実際には大したことではありません。操作をマルチスレッド化するのは非常に簡単なことです。非常に短く単純なタスクであっても、これは目的を達成するための最も簡単な方法です。TPLを使用すると、次のようになります。

using System.Threading.Tasks;

...

Task.Factory.StartNew(() => {
    for (...) {
        // operation...
        progressBar.Dispatcher.BeginInvoke(() => progressBar.Value = ...);
    }
});
于 2013-07-29T23:02:35.563 に答える
0

これを試して:

public ProgressBarUpdate(ProgressBar pb, int total)
{
    _pb = pb;
    _total = total;
    _delta = _pb.MaxValue/((double)total);  /make sure you do not truncate delta
    _current = 0;
    _pb.Visibility = Visibility.Visible;

}
public void Dispose()
{
    _pb.Visibility = Visibility.Collapsed;
    _current = 0;
}
public void UpdateProgress()
{
    _pb.Value = (int)( _delta * (++_current)); //update after the increment
}

floatの代わりにも使用することをお勧めしdoubleます。

于 2013-07-29T17:18:04.753 に答える
0

UI スレッドで作業を行っており、UpdateProgress を呼び出している場合、作業が終了し、UI スレッドが他の作業 (UI の更新など) を実行できるようになるまで更新されません。したがって、これは決して機能しません。

バックグラウンド スレッドで作業を行っている場合は、Dispatcher を使用して値の設定を UI スレッドにマーシャリングする必要があります。

http://tech.pro/tutorial/800/working-with-the-wpf-dispatcherの例を次に示します。

if (!myCheckBox.Dispatcher.CheckAccess())
{
  myCheckBox.Dispatcher.Invoke(
    System.Windows.Threading.DispatcherPriority.Normal,
    new Action(
      delegate()
      {
        myCheckBox.IsChecked = true;
      }
  ));
}
else
{
  myCheckBox.IsChecked = true;
}
于 2013-07-29T15:08:33.437 に答える