Cool Brain
Cool Brain

Reputation: 649

Working with ProgressBar and ComboBox

I'm in trouble with a Marquee ProgressBar. I need to execute a method (refreshList()) to get a List<string>. Then I assign this List to a ComboBox, so ComboBox refreshes with the new Items. As refreshList() take 3 or 4 sec, I wanted to run a Marquee ProgressBar. But I couldn't. ProgressBar is ok, but ComboBox doesn't load new Items.

My refreshList() method:

private void refreshList(List<string> list)
{
    albumList.DataSource = null;
    albumList.DataSource = list;
}

I have the following code, it works fine:

private void changeDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
{
    fbd.RootFolder     = Environment.SpecialFolder.MyComputer;
    folderPath = "";
    if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        folderPath     =  fbd.SelectedPath;
        refreshList(N.getList(folderPath));

    }
}

But I added a ProgressBar and wrote this code:

private void changeDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
{
    fbd.RootFolder     = Environment.SpecialFolder.MyComputer;
    folderPath = "";
    if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        folderPath     =  fbd.SelectedPath;
        bgWorker.WorkerReportsProgress = true;
        bgWorker.RunWorkerAsync();

    }
}

And I placed refreshList() in doWork() method:

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
    refreshList(N.getList(folderPath));
}

But unfortunately this isn't working. Can anybody help me solving this problem? Thanks in advance.

Upvotes: 3

Views: 684

Answers (1)

dash
dash

Reputation: 91500

You can use the MarqueeAnimationSpeed and Value properties of the ProgressBar control to stop and start the Marquee. There's no need to use WorkerReportsProgress* as you aren't incrementing a normal progress bar - you just want to "spin" the Marquee.

You can do something like the following:

    public Form1()
    {
        InitializeComponent();
        //Stop the progress bar to begin with
        progressBar1.MarqueeAnimationSpeed = 0;             
        //If you wire up the event handler in the Designer, then you don't need 
        //the following line of code (the designer adds it to InitializeComponent)
        //backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
    }

    private void changeDirectoryToolStripMenuItem_Click(object sender, EventArgs e)
    {
        fbd.RootFolder = Environment.SpecialFolder.MyComputer;
        folderPath = "";
        if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            folderPath = fbd.SelectedPath;
            //This line effectively starts the progress bar
            progressBar1.MarqueeAnimationSpeed = 10;                 
            bgWorker.RunWorkerAsync(); //Calls the DoWork event

        }
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        e.Result = N.getList(folderPath); //Technically this is the only work you need to do in the background
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //these two lines effectively stop the progress bar
        progressBar1.Value = 0;
        progressBar1.MarqueeAnimationSpeed = 0;
        //Now update the list with the result from the work done on the background thread 
        RefreshList(e.Result as List<String>);
    }


    private void RefreshList(List<String> results)
    {
        albumList.DataSource = null; //You don't need this line but there is no real harm.
        albumList.DataSource = list;
    }

Remember to wire up the RunWorkerCompleted event to backgroundWorker1_RunWorkerCompleted via the Properties bar, Events section in the designer.

To begin with, we start the ProgressBar's animation by setting the MarqueeAnimationSpeed property to a non-zero positive number as part of your successful folder selection.

Then, after calling RunWorkerAsync, the code builds your list in the DoWork method, then assigns the result to the DoWorkEventArgs, which get passed to the RunWorkerCompleted event (which fires when DoWork is finished).

In the backgroundWorker1_RunWorkerCompleted method, we stop the progress bar (and set it's value to zero to effectively return it to it's original state), and then we pass the list to the refreshList method to databind it and populate the ComboBox.

Tested using VS2012, Windows Forms, .Net 4.0 (with a Thread.Sleep to emulate the time taken for N.getList)

*WorkerReportsProgress, and the associated ReportProgress method/event are used when you want to increment the progress bar - you can tell the GUI that you are 10% done, 20% done, 50% done etc etc.

Upvotes: 1

Related Questions