使用ProgressBar和ComboBox

时间:2013-01-01 13:25:53

标签: winforms c#-4.0 combobox backgroundworker

我遇到了Marquee ProgressBar的问题。我需要执行一个方法(refreshList())来获得List<string>。然后,我将此List分配给ComboBox,以便ComboBox使用新的Items进行刷新。由于refreshList()需要3或4秒,我想要运行Marquee ProgressBar。但我不能。 ProgressBar没问题,但ComboBox未加载新Items

我的refreshList()方法:

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

我有以下代码,它工作正常:

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));

    }
}

但我添加了ProgressBar并编写了此代码:

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();

    }
}

我将refreshList()放在doWork()方法中:

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

但不幸的是,这不起作用。任何人都可以帮我解决这个问题吗?提前谢谢。

1 个答案:

答案 0 :(得分:1)

您可以使用ProgressBar控件的MarqueeAnimationSpeedValue属性来停止和启动Marquee。没有必要使用WorkerReportsProgress *因为你没有递增正常的进度条 - 你只是想“旋转”Marquee。

您可以执行以下操作:

    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;
    }

请记住通过设计器中的“属性”栏的“事件”部分将RunWorkerCompleted事件连接到backgroundWorker1_RunWorkerCompleted。

首先,我们通过将MarqueeAnimationSpeed属性设置为非零正数作为成功选择文件夹的一部分来启动ProgressBar的动画。

然后,在调用RunWorkerAsync之后,代码在DoWork方法中构建列表,然后将结果分配给DoWorkEventArgs,DoWorkEventArgs将传递给RunWorkerCompleted事件(在DoWork完成时触发)。

backgroundWorker1_RunWorkerCompleted方法中,我们停止进度条(并将其值设置为零以有效地将其返回到其原始状态),然后我们将列表传递给refreshList方法以对其进行数据绑定并填充组合框。

使用VS2012,Windows Forms,.Net 4.0进行测试(使用Thread.Sleep模拟N.getList所需的时间)

*当您想要增加进度条时,使用WorkerReportsProgress和相关的ReportProgress方法/事件 - 您可以告诉GUI您已完成10%,完成20%,完成50%等等。