ProgressBar не отвечает на пользовательский интерфейс, если не вызвать - PullRequest
1 голос
/ 23 марта 2011

У меня странный случай.У меня есть поле со списком в моем приложении формы Windows.При изменении выбранного индекса запускается фоновый рабочий процесс для взаимодействия с индикатором выполнения.Мой DoWork выглядит так:

private void backgroundWorkerProgressBar_DoWork(object sender, DoWorkEventArgs e)
{
    int campaignID = (int)e.Argument;

    for (int i = 0; i < 100; i++)
    {
        CampaignEmailIndex.TryGetValue(campaignID, out subscribers); // This is a dictionary that keeps subscriber numbers. Subscriber number keeps growing while application works.
        backgroundWorkerProgressBar.ReportProgress(subscribers);
    }

}

Мой Progress_Changed прост:

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

Но этот код не работает должным образом.Индикатор выполнения не перемещается в приложении, пока я не изменю выбранный индекс в выпадающем списке.

Но этот код работает в обработчике событий DoWork.Он изменяет состояние индикатора выполнения и не требует, чтобы я снова выбирал индекс выпадающего списка.

for (int i = 0; i < 100; i++)
{
     backgroundWorkerProgressBar.ReportProgress(i);
}

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

Спасибо всем.

Отредактировано: код, который запускает фонового работника:

private void cmbCampaignInPoolByID_SelectedIndexChanged(object sender, EventArgs e)
{
    int campaignID = (int)cmbCampaignInPoolByID.SelectedItem;
    DataTable dt = DatabaseManager.GetCampaignDetails(campaignID);

    subscribers = DatabaseManager.GetCampaignSubscribers(campaignID).Rows.Count;

    progressBarMailQueu.Maximum = subscribers;
    backgroundWorkerProgressBar.WorkerReportsProgress = true;
    backgroundWorkerProgressBar.DoWork += new DoWorkEventHandler(backgroundWorkerProgressBar_DoWork);
    backgroundWorkerProgressBar.ProgressChanged += new ProgressChangedEventHandler(backgroundWorkerProgressBar_ProgressChanged);
    backgroundWorkerProgressBar.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorkerProgressBar_RunWorkerCompleted);            
    backgroundWorkerProgressBar.RunWorkerAsync(campaignID);

}

1 Ответ

1 голос
/ 23 марта 2011

Я пытался написать твой код:

    private void cb_SelectedIndexChanged(object sender, EventArgs e)
    {
        bg.RunWorkerAsync(cb.SelectedIndex);
    }

    private void bg_DoWork(object sender, DoWorkEventArgs e)
    {
        int campaignID = (int)e.Argument;
        for (int i = 0; i < 100; i++)
        {
            int subscribers = new Random().Next(0, 100);
            bg.ReportProgress(subscribers);
            Thread.Sleep(30);
        }
    }

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

Посмотрите на Thread.Sleep (30) : раньше он мог что-то видеть.У меня все работает: индикатор выполнения перемещается правильно в течение цикла for. bg - это BackgroungWorker с ReportProgress = true и pb - это ProgressBar (0,100).Если вы уверены, что число подписчиков находится в диапазоне 0..pb.Max , это должно сработать.

...