3

I'm trying to write a simple program (c#) that read a set of zip files to search for some specific files.

i implemented this using winform and a background worker but i'm having some trouble to understand how to configure the progress bar to progress dynamically according to the number of files i'm parsing.

for example in Directory A i have 400 zip file so i want the "size" of the progress bar to be 400 units so each file a open will increment the progress bar by 1. In directory B i only have 4 zip file so i need 4 block in the progress bar

i tried to do the following code just to test the progress bar i set the Maximum to 20 (to represent 20 zip files) and in a loop incremnt by 1 the progress bar

        private void button_SearchZip_Click(object sender, EventArgs e)
    {
        if(!backgroundWorker_SearchZip.IsBusy)
        {
            SearchZipArgs args = new SearchZipArgs
            {
                sourceDirectory = this.textBox_SrcDir.Text
            };

            backgroundWorker_SearchZip.RunWorkerAsync(args);
            this.button_SearchZip.Enabled = false;
        }
        else
        {
            MessageBox.Show(@"Search already in process. please try again later");
        }
    }

    private void backgroundWorker_SearchZip_DoWork(object sender, DoWorkEventArgs e)
    {

            this.progressBar_SearchZip.Style = ProgressBarStyle.Blocks;
            //this.progressBar_SearchZip.Step = 1;
            this.progressBar_SearchZip.Minimum = 0;
            this.progressBar_SearchZip.Maximum = 20;
            for(int i = 0; i < 20; i++)
            {
                backgroundWorker_SearchZip.ReportProgress(i);
                Thread.Sleep(300);
            } 
    }

    public MainForm()
    {
        InitializeComponent();
        this.backgroundWorker_SearchZip.WorkerReportsProgress = true;
        this.backgroundWorker_SearchZip.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker_SearchZip_DoWork);
        this.backgroundWorker_SearchZip.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker_SearchZip_ProgressChanged);
        this.backgroundWorker_SearchZip.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker_SearchZip_RunWorkerCompleted);
    }

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

but this is what i get in the progress bar:

Progress bar screenshot when work is done

for some reason if uncomment the:

this.progressBar_SearchZip.Step = 1;

the progress bar is not working at all

any help would be nice :)

Edit: Found the problem! i was trying to change the progress bar from the background thread and i got an error "Cross-thread operation not valid: Control 'progressBar Search Zip' accessed from a thread other than the thread it was created on" after fixing this error (with the help of this thread: Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on) the problem is solved

Community
  • 1
  • 1
Dardar
  • 624
  • 3
  • 13
  • 30

4 Answers4

1

The Step property is used to when calling the PerformStep method.

To set the current position of the progress bar you can use the Increment function like this:

progressBar.Increment(1);

or set its value like this:

progressBar.Value = yourValue;
S.Dav
  • 2,436
  • 16
  • 22
  • @S. Dav - For my knowledge - Do we need to write these lines in ProgressChanged? I think this gets called from ReportProgress? – A3006 Feb 22 '17 at 08:54
  • You might be right, but we don't see the ReportProgress function in the question. – S.Dav Feb 22 '17 at 08:58
1

You need to add

backgroundWorker_SearchZip.ProgressChanged += this.OnProgressChanged;

into your initialization function (e.g. Form_Load)

and then add

private void OnProgressChanged(object sender, ProgressChangedEventArgs e) {
  this.progressBar_SearchZip.Increment(1);
}
Bob Vale
  • 18,094
  • 1
  • 42
  • 49
  • is it really a good idea to subscribe the `ProgressChanged` event in the Button Click event as per your suggestion? This should preferably be done on `Form_Load` or any other initializing method – S.Dav Feb 22 '17 at 09:04
  • Good point, I misread the question and thought I saw it being initialized in the click event. I'll make an edit – Bob Vale Feb 22 '17 at 09:17
  • @S.Dav forgot to add the ProgressChanged code . I've edited the question – Dardar Feb 22 '17 at 11:33
  • @BobVale this.backgroundWorker_SearchZip.Increment(1) does not complie. did u mean: this.progressBar_SearchZip.Increment(1) ? – Dardar Feb 22 '17 at 11:37
0

this code works for me:

this.progress_bar.Properties.Minimum = 0; 
this.progress_bar.Properties.Maximum = datatable.Rows.Count;

foreach (DataRow row in datatable.Rows)     {

   // operation that you need to do     

   this.progress_bar.Increment(1);
   this.progress_bar.Update();
}

Good luck

raBinn
  • 159
  • 1
  • 11
  • so if u get 10 rows or 1000 rows - in both cases the progress bar is filled till the end? – Dardar Feb 22 '17 at 11:42
  • yes, with each iteration in the foreach you increase the value of progress bar by 1 and you update the state of progress bar .... That sample code is operational in a project that imports rows from a datatable and performs a series of checks with them. – raBinn Feb 22 '17 at 11:54
0

Found the problem!

i was trying to change the progress bar from the background thread and i got an error "Cross-thread operation not valid: Control 'progressBar Search Zip' accessed from a thread other than the thread it was created on"

after fixing this error (with the help of this thread: Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on) the problem is solved

Community
  • 1
  • 1
Dardar
  • 624
  • 3
  • 13
  • 30