3

我遇到了麻烦Marquee ProgressBar。我需要执行一个方法 ( refreshList()) 来获得一个List<string>. 然后我将它分配List给 a 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));
}

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

4

1 回答 1

1

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

您可以执行以下操作:

    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,然后将其传递给 RunWorkerCompleted 事件(在 DoWork 完成时触发)。

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

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

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

于 2013-01-01T13:53:58.287 回答