使用DataTable将数据加载到DataGridView的Progressbar

我有一个DataGridView ,我在其中从SQL服务器数据库加载数据。 当我加载数据时需要很长时间。

我想向用户提供数据正在加载的信息。 我可以问你在将数据加载到DataGridView时连接Progressbar的最佳方法是什么?

我不希望任何人为我制作完整的代码。 我只是想知道如何做到这一点。

我看到有人以赏金授予我的问题。 我想说,目前我使用这个代码,如果它适合的话我会评价。

 DTGdataTable = new DataTable(); SqlDataAdapter SDA = new SqlDataAdapter SDA.Fill(DTGdataTable); dataGridView1.DataSource = DTGdataTable ; 

谢谢大家的时间。

如果问题是从数据库中获取数据需要很长时间,我有一个可能的解决方案:

  private void buttonLoad_Click(object sender, EventArgs e) { progressBar.Visible = true; progressBar.Style = ProgressBarStyle.Marquee; System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(loadTable)); thread.Start(); } private void loadTable() { // Load your Table... DataTable table = new DataTable(); SqlDataAdapter SDA = new SqlDataAdapter(); SDA.Fill(table); setDataSource(table); } internal delegate void SetDataSourceDelegate(DataTable table); private void setDataSource(DataTable table) { // Invoke method if required: if (this.InvokeRequired) { this.Invoke(new SetDataSourceDelegate(setDataSource), table); } else { dataGridView.DataSource = table; progressBar.Visible = false; } } 

将加载数据的方法放入另一个线程,并在数据源完成时设置数据源。 应该有一个调用。 如果要在进度条中显示百分比值,请不要使用“Marquee”样式并添加另一个函数和委托,您可以调用该函数来设置进度条的值。

如果将数据绑定到网格是问题,那么您不能将绑定放入另一个线程,并且您可能会显示在另一个线程中运行的进度弹出窗口。

我希望这有帮助。

试试这个…这应该是最快的路线……

 1) Add a button control. 2) Add a datagridview control. 3) Add a single column into the datagridview control. 4) Add a progressbar control. 5) Leave them all with default names. 

在button1_Click事件下,添加这段代码……

 int maxnumber = 1000; progressBar1.Value = 0; progressBar1.Maximum = maxnumber; for (int x = 0; x <= maxnumber - 1; x++) { Application.DoEvents(); dataGridView1.Rows.Add(new string[] {Convert.ToString(x)}); progressBar1.Value += 1; label1.Text = progressBar1.Value.ToString(); } 

而已。 编辑以满足您的需求。 这不是您想要的完整确切代码,但它应该让您入门。 我冒昧宣布maxnumber保持进度条的限制。 在您的情况下,这应该是您的数据库的行数,它减去1,因为索引始终从零开始:)

上面的方法是单线程的,这意味着当你的循环还没有完成时你仍然无法进行多任务处理。 在某些情况下,根据代码的算法,使用单线程方法可能比使用multithreading路由更快。 无论如何,第二种方法是使用背景工作者。 这是人们最常喜欢的,因为用户在列表加载时仍然可以执行操作。 有点像安装程序,你可以取消安装,即使它正在做某事。 下面的网站应该让你入门。 代码在VB.NET中,但可以很容易地转换为C#:)

http://social.msdn.microsoft.com/Forums/vstudio/en-US/efd7510c-43ed-47c4-86a3-1fa350eb0d30/fill-datagridview-using-backgroundworker-progressbar?forum=vbgeneral

问题是所有数据加载在一起并从数据库返回。 您需要获取数据加载进度。 这可以从数据库完成。

  1. 从数据库获取数据行的计数。 (此查询将返回单个数字,因此会更快)。

  2. 获取部分数据(Divide&conquer strategy),您可以使用OFFSET和FETCH数据库查询。 (这是每次调用时返回的数据部分)OFFSET和FETCH在不同的数据库上可用。 在MSSQL中,它是在2012版本中引入的。

当我们从服务器获取部分数据时,我们可以计算进度。

在您的代码中,此行将占用大部分处理时间:

 SDA.Fill(DTGdataTable); 

所以我认为最重要的是在执行过程中跟踪进度。 要做到这一点,首先需要知道您期望的行数。 SQLDataAdapter无法提供此信息,因此您需要首先运行额外的COUNT(*)查询才能获得此数字。 然后,您可以将其用作ProgressBar上的最大值。

我的实际加载代码基于Michael Hofmeiers解决方案,但不是在Marquee模式下使用ProgressBar,而是使用Timer Control中的实际进度数据来提供它。 因此,在您的表单上,添加一个Timer控件(在我的示例中名为progressTimer),将其Interval设置为100毫秒并将Enabled设置为false。 代码然后变成:

 private DataTable table = null; private void buttonLoad_Click(object sender, EventArgs e) { // TODO: Select the row count here and assign it to progressBar.Maximum progressBar.Visible = true; System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(loadTable)); thread.Start(); progressTimer.Enabled = true; } private void loadTable() { // Load your Table... this.table = new DataTable(); SqlDataAdapter SDA = new SqlDataAdapter(); SDA.Fill(table); setDataSource(table); } internal delegate void SetDataSourceDelegate(DataTable table); private void setDataSource(DataTable table) { // Invoke method if required: if (this.InvokeRequired) { this.Invoke(new SetDataSourceDelegate(setDataSource), table); } else { progressTimer.Enabled = false; dataGridView.DataSource = table; progressBar.Visible = false; } } private void progressTimer_Tick(object sender, EventArgs e) { if (this.table != null) progressBar.Value = this.table.Rows.Count; } 

运行此操作时,您的应用程序将在加载过程中保持响应,并且您将看到ProgressBar更改以反映加载的行数。 仅在最后(当您在DataGridView上设置DataSource时)应用程序似乎“挂起”,但我认为没有办法避免这种情况。 您只能从主线程执行此操作,因此UI变得无法响应是不可避免的。 但在我的测试中,DataGridView可以在大约一秒钟内轻松处理300K +行,因此这不应该是一个很大的问题。

1.从谷歌下载ajax loader.gif。

2.使用此代码替换该图像..

3.相应地设定时间..

  $("#ssubmit").click(function () { $("#spinner").show(); setInterval(function () { $("#spinner").hide(); }, 20000); });