【问题标题】:How to show progress while populating dataGridView?如何在填充 dataGridView 时显示进度?
【发布时间】:2021-07-30 16:01:17
【问题描述】:

我正在使用给定范围内的随机数填充 datagridview,但是当我生成大量数字时 - 我的程序在生成它们时挂起。这可能会持续一分钟以上(取决于数量)。我知道我可以使用 ProgressBar 显示进度。我试过用它,但我什么都没有。有使用的例子吗?

这是我的代码:

private void button1_Click(object sender, EventArgs e)
{
    if (dataGridView1.RowCount > 0) {
        dataGridView1.Rows.Clear();
        dataGridView1.Refresh();
    }

    N = int.Parse(textBox1.Text);
    range_min = int.Parse(textBox2.Text);
    range_max = int.Parse(textBox3.Text);
    numbers = new int[N];
    if (range_max < range_min) MessageBox.Show("Some alert text");
    else if (range_max == range_min) MessageBox.Show("Some alert text");
    else
    {
        dataGridView1.RowCount = N;
        for (int i = 0; i < N; i++)
        {
            numbers[i] = (int)(Math.Round((range_max - range_min) * rndm.NextDouble() + range_min));
            dataGridView1[0, i].Value = numbers[i];
        }
    }
}

【问题讨论】:

  • 只需用您的逻辑替换从数据表中加载的建议副本。您还可以通过设置最大行数(如果已知)并在每次迭代中调用 DoProgress 来改进这一点,或者您可以使用我所说的“量子步进”,每 10 或 100 或 1000 行...进步1(因此最大值是计数/量子)......这避免了在有大量行时给用户界面带来压力并破坏循环的性能。您可以执行该线程(需要主 UI 线程同步)或不执行,并在需要时在每个进度后使用 Refresh。
  • 好的@OlivierRogier,我刚试过这个,但我得到System.InvalidOperationException:“多个线程上的无效操作:尝试从另一个线程访问控制'dataGridView1'它被创造了。”我该如何解决?另外,我是否需要将 setDataSource() 方法复制到我的代码中?
  • @OlivierRogier,你能不能给我解释一下,给我写个例子?我是 C# 的新手。

标签: c# datagridview textbox progress-bar


【解决方案1】:

在向 UI 添加数据时,您的程序“挂起”,因为您在 UI 线程中完成所有工作,有效地阻塞了线程,直到您的循环完成。因此,您需要在单独的线程中处理这项繁重的工作。但是您只能从 UI/主线程更改 UI,所以这样的事情会引发异常:

    private void button1_Click(object sender, EventArgs e)
    {
        new Thread(() =>
        {
            for (int i = 0; i < 4000; i++)
            {
                dataGridView1.Rows.Add(i.ToString());//throws an exception 
            }
        }).Start();
    }

解决方案是创建一个方法,您可以像这样调用主线程来执行:

    private void button1_Click(object sender, EventArgs e)
    {
        new Thread(() =>
        {
            for (int i = 0; i < 10000; i++)
            {
                this.AddRow(i);
            }
        }).Start();
    }

    public void AddRow(int value)
    {
        if (this.InvokeRequired)
            this.Invoke(new MethodInvoker(() => this.AddRow(value)));
        else
            dataGridView1.Rows.Add(value.ToString());//do your ui update (add row, update progress bar etc..)
        
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-11
    • 2011-07-05
    • 2020-12-12
    • 2018-02-12
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多