Dudley
Dudley

Reputation: 29

ProgressChanged not updating progressbar

I have an issue with ProcessChanged. It's fired in the code (when I'm looking in the debugger) but it doesn't update in my mainscreen where the progressbar is located.

The initialisation of the BackgroundWorker

private void Import_Click(object sender, RoutedEventArgs e)
    {
        progressbarImport.Value = 0;

        int max = DatagridZegrisWeekImport.Items.Count;

        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += worker_DoWork;
        worker.ProgressChanged += worker_ProgressChanged;
        worker.WorkerReportsProgress = true;
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
        worker.RunWorkerAsync();
    }

The DoWork

void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        var manager = new ZegrisReadToDB();

        int progressPercentage = 0;
        int max = DatagridZegrisWeekImport.Items.Count;

        for (int i = 0; i < max; i++)
        {
            this.Dispatcher.Invoke(() =>
            {
                DatagridZegrisWeekImport.SelectedIndex = i;
                var selecteditem = DatagridZegrisWeekImport.SelectedItem as ZegrisWeekDataImport;
                string exist = manager.CheckExist2(selecteditem.Artikelnummer, selecteditem.Jaar);
                if (exist == "")
                {
                    insert statement;

                    progressPercentage = Convert.ToInt32(((double)i / max) * 100);
                    (sender as BackgroundWorker).ReportProgress(progressPercentage);
                    Thread.Sleep(100);
                }
                else
                {
                    update statement

                    progressPercentage = Convert.ToInt32(((double)i / max) * 100);
                    (sender as BackgroundWorker).ReportProgress(progressPercentage);
                    Thread.Sleep(100);
                }
            });
        }
    }

The ProgressChanged

void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        Application.Current.Dispatcher.Invoke(() =>
        this.progressbarImport.Value = e.ProgressPercentage);
    }

As you may see, I have already tried a couple of solutions found on this forum, but none seem te be working. It's the first time I'm using BackgroundWorker and somewhere I lost my train of thought.

Upvotes: 0

Views: 187

Answers (1)

the.Doc
the.Doc

Reputation: 886

If you are intent on using the BackgroundWorker then try the following code

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        var manager = new ZegrisReadToDB();

        int progressPercentage = 0;

        // use the source list if you have it available, rather than casting here
        List<ZegrisWeekDataImport> items = DatagridZegrisWeekImport.Items.Cast<ZegrisWeekDataImport>().ToList();
        var max = items.Count;

        for (int i = 0; i < max; i++)
        {                    
            var item = items[i];

            string exist = manager.CheckExist2(item.Artikelnummer, item.Jaar);

            if (exist == "")
            {
                insert statement;

                progressPercentage = Convert.ToInt32(((double)i / max) * 100);
                (sender as BackgroundWorker).ReportProgress(progressPercentage);
            }
            else
            {
                update statement

                progressPercentage = Convert.ToInt32(((double)i / max) * 100);
                (sender as BackgroundWorker).ReportProgress(progressPercentage);                       
            }
        }
    }

    void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        this.progressbarImport.Value = e.ProgressPercentage);
    }

If you have control of your ZegrisReadToDB class it would be beneficial to make this async if you can. Below is a version that uses async/await

    // bind you progress bar to this
    public double Progress { get; set; } // raise property changed

    // bind your datagrid to this property
    public List<ZegrisWeekDataImport> Items {get;set;} = new List<ZegrisWeekDataImport>();

    private async void Import_Click(object sender, RoutedEventArgs e)
    {
        await DoWork();
    }

    public async Task DoWork()
    {
        for (int i = 0; i < Items.Count; i++)
        {
            var item = Items[i];

            string exist = await manager.CheckExist2(item.Artikelnummer, item.Jaar);

            if (exist == "")
            {
                await insert statement
            }
            else
            {
                await update statement
            }

            Progress = (double)i / max) * 100; 
        }
    }

Upvotes: 2

Related Questions