Backgroundworker MVVMの設定、プログレスバーの更新

私はStartCommandクラスを持っている:

public class StartCommand : ICommand
{
    public void Execute(object parameter)
    {
        //Fill Listview1
        ...
        //Here I want to increase the Progressbarvalue   

        //Fill Listview2
        ...
        //Here again and so far..       
    }
}

MainWindow.xaml progressBar )の[スタート]ボタンをクリックすると、Executeコマンドが実行されます。

What I want now, is updating the Progressbar on these places (look at Code), while the ListViews are loading. How do I set up the Backgroundworker?

私はそのようなものを試しました:

public class StartCommand : ICommand
    {
        MainWindow mainWindow;

        public StartCommand(MainWindow mainWindow)
        {
             this.mainWindow = mainWindow
        }

        public void Execute(object parameter)
        {
            //Fill Listview1
            ...
            mainWindow.backgroundWorker1.RunWorkerAsync(10);  

            //Fill Listview2
            ...
            mainWindow.backgroundWorker1.RunWorkerAsync(20);      
        }
    }

MainWindow:

public partial class MainWindow : Window
{
    BackgroundWorker backgroundWorker1;

    public MainWindow()
    {
        InitializeComponent();
        InitializeBackgroundWorker();
    }

    private void InitializeBackgroundWorker()
    {
        backgroundWorker1.DoWork +=
            new DoWorkEventHandler(backgroundWorker1_DoWork);
        backgroundWorker1.RunWorkerCompleted +=
            new RunWorkerCompletedEventHandler(
        backgroundWorker1_RunWorkerCompleted);
        backgroundWorker1.ProgressChanged +=
            new ProgressChangedEventHandler(
        backgroundWorker1_ProgressChanged);
    }


    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;
        e.Result = UpdateProgressBar((int)e.Argument, worker);
    }

    private int UpdateProgressBar(int value, BackgroundWorker worker)
    {
        worker.ReportProgress(value);
        return Convert.ToInt32(progressBar.Value);
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {

    }

    private void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e)
    {
        progressBar.Value = e.ProgressPercentage;
    }
}

}

それはうまくいきません(これはいくつかのコピー/ペーストの手配です。なぜなら、これを達成する方法がわからず、スレッドでWPFで初めて作業しているからです)。しかし、たぶん、今、私が探しているものの、より良い光景を得ました。

1

2 答え

選択する必要があります:1つのバックグラウンドワーカーを使用してすべてのリストビューをロードするか、複数のバックグラウンドワーカーを使用して、それぞれリストビューを作成します。

現在、バックグラウンドワーカーは、前のジョブが完了する前に別のジョブで作業を開始するようにしています。

これをすばやく修正するには、リストビューをDoWorkハンドラにロードするすべてのコードを記述します。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
   //fill listview1
    worker.ReportProgress(percentageDone);
   //fill listview2
    worker.ReportProgress(percentageDone);
   //fill listview3
    worker.ReportProgress(percentageDone);
}

複数のバックグラウンドワーカーを使用するには、複数のバックグラウンドワーカーを作成します。

var bw1 = new BackgroundWorker();
bw1.DoWork += ...;
bw1.RunAsync(...);
var bw2 = new BackgroundWorker();
bw2.DoWork += ...;
bw2.RunAsync(...);
var bw3 = new BackgroundWorker();
bw3.DoWork += ...;
bw3.RunAsync(...);
3
追加された
問題は、コードを分離したいということです。つまり、MainWindowのBackgroundcodeに "ListViewFilling"を書きたくないということです。私はまだクラスStartCommandでそれをしたい.. ListViewFillingのようなもの: viewModel.MissingTables = schemaComparer.GetSchemaModifications (viewMode‌ l.FirstSchemaToCompa‌ re、viewModel.SecondSchemaToCompare);
追加された 著者 eMi,
ちょうどそうでしたが、どうすれば私のプログレスバーにアクセスできますか?
追加された 著者 eMi,
良い!あなたができることは、ViewModelに背景作業者を置くことです。
追加された 著者 Erno de Weerd,
プロパティをViewModelで進捗させ、プログレスバーのValueプロパティをバインドします。それはMVVMです。
追加された 著者 Erno de Weerd,
また、 BackgroundWorkerを設定する必要があります。 WorkerReportsProgress プロパティを true に設定して ReportProgress を有効にします。
追加された 著者 Clemens,

これはすべて、「フィリング・リスト・ビュー」が実際に意味するものに依存します。データを取得するためにデータベースに行くなら、間違いなくバックグラウンドスレッド上にあるはずです。しかし、既にデータを持っていて、リストビューを作成するだけであれば、 BackgroundWorker はまったく役に立たないでしょう。これは、 ListView にアクセスするためにUIスレッドにマーシャリングする必要があるからです!

ListView に追加するデータがたくさんあり、その間UIが応答し続けるようにするには、別々のディスパッチャメッセージでデータをチャンクに追加する必要があります。チャンクが追加されたら、別のメッセージをキューに入れて次のチャンクを追加します。これにより、ディスパッチャは、リストが入力されている間に他のメッセージを処理する時間を与えます。

2
追加された
私はデータベースからデータを取得している、私は同時に7 Listviewsを埋めるが、それは長いので、約3-7秒かかるので、UIは本当に応答する必要があります..
追加された 著者 eMi,