Настройте Backgroundworker MVVM, обновите Progressbar - PullRequest
1 голос
/ 06 февраля 2012

У меня есть класс 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).

ЧтоТеперь я хочу, чтобы обновлял Progressbar в этих местах (смотрите Код), пока ListViews загружаются. Как мне установить 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).Но, может быть, теперь у тебя есть лучшее видение того, что я ищу ..

Ответы [ 2 ]

3 голосов
/ 06 февраля 2012

Вы должны выбрать: использовать один фоновый рабочий для загрузки всех представлений списка или использовать несколько фоновых рабочих, каждый из которых заполняет список.

В настоящее время вы пытаетесь заставить фонового работника начать работу над другим заданием до того, как предыдущее задание будет завершено.

Чтобы исправить это быстро: поместите весь код для загрузки списков в обработчике 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(...);
2 голосов
/ 06 февраля 2012

Все зависит от того, что на самом деле означает «просмотр списка заполнения». Если вы отправляетесь в базу данных, чтобы получить данные, то это определенно должно быть в фоновом потоке. Однако, если у вас уже есть данные и вам просто нужно заполнить представление списка, то BackgroundWorker совсем не поможет - это только ухудшит ситуацию. Это потому, что вам необходимо выполнить маршалинг обратно в поток пользовательского интерфейса, чтобы получить доступ к ListView!

Если у вас есть много данных, которые нужно добавить к ListView, и вы хотите, чтобы пользовательский интерфейс оставался отзывчивым, вам нужно добавлять данные в виде кусков в отдельных сообщениях диспетчера. Когда блок будет добавлен, поставьте в очередь другое сообщение, чтобы добавить следующий блок. Это дает диспетчеру время для обработки других сообщений во время заполнения списка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...