【问题标题】:Working with ProgressBar and ComboBox使用 ProgressBar 和 ComboBox
【发布时间】:2012-12-16 03:50:09
【问题描述】:

我遇到了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));
}

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

【问题讨论】:

  • 我可以总结一个 TL;DR 版本的问题吗?设置数据源albumList.DataSource = list; 需要3-4秒,如何在分配时显示选框进度条?对吗?
  • 您确定 BackgroundWorker 类已连接到 DoWork 事件(即您的代码中有 bgWorker.DoWork += bgWorker_DoWork; 吗?)。我也看不到你在哪里停止和启动ProgressBar
  • 在我看来这段代码无法编译?bgWorker_DoWork 中的folderPath 是什么。
  • @Neolisk - 不完全是,部分。 N.getList(folderPath) 需要 3-4 秒。那么如何在这个方法运行时显示一个选框进度条。
  • @HamletHakobyan - folderPath 可能是类中的一个字段。我不认为所有的代码都在这里......

标签: winforms c#-4.0 combobox backgroundworker


【解决方案1】:

您可以使用 ProgressBar 控件的MarqueeAnimationSpeedValue 属性来停止和启动选取框。没有必要使用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-05-20
  • 2017-08-04
  • 1970-01-01
  • 2018-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-04
  • 1970-01-01
相关资源
最近更新 更多