如何在将数据加载到DataGridView的同时将数据加载1到100%完成加载时

如何在将数据加载到DataGridView的同时将数据加载1到100%完成加载时

问题描述:

我需要我的应用程序帮助,我的应用程序中的所有内容都能正常工作,但我想添加最后一个帮助用户的细节使用应用程序。如何在将数据加载到DataGridView的同时将数据加载1到100%完成加载时

我有一个combobox,有三个选择用户将使用,每个选择有不同的仓库数据库环境。所以如果他们在组合框仓库1中选择,然后将数据库1表数据加载到datagridview,但是当他们选择应用程序正在加载显示数据时,所以何时这样做取决于有多少数据有时需要5到15秒来加载或更多我想添加一个进度条,让用户知道要等到进度达到100%。

所以我需要帮助,如何使进度条在datagridview加载数据时工作。如果您需要更多信息,请让我知道。

后的变化,请检查一下,但我得到一个错误 [![在这里输入的形象描述] [1] [1]

​​

更新的代码:// 全局变量 // datagridview,bindingsource,data_apapter全局对象变量 private DataGridView dataGridView = new DataGridView(); private BindingSource bindingSource = new BindingSource(); private SqlDataAdapter dataAdapter = new SqlDataAdapter();

//class objects 
    Databases lemars = new Databases(); 
    Databases schuyler = new Databases(); 
    Databases detroitlakeskc = new Databases(); 
    /* 
    * The GetLeMarsConnectionDatabaseConnection method starts the database string connection for warehouse LeMars21St 
    */ 
    private void GetLeMarsConnectionDatabaseConnection(string selectCommand, Databases database) 
    { 

     try 
     { 

      //Create the connection string, data adapter and data table. 
      String connectionString = database.LeMarsConnectionString; 


      // Specify a connection string. Replace the given value with a 
      // valid connection string for a Northwind SQL Server sample 
      // database accessible to your system. 
      // Create a new data adapter based on the specified query. 
      dataAdapter = new SqlDataAdapter(selectCommand, connectionString); 

      // Create a command builder to generate SQL update, insert, and 
      // delete commands based on selectCommand. These are used to 
      // update the database. 
      SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter); 

      // Populate a new data table and bind it to the BindingSource. 
      System.Data.DataTable table = new System.Data.DataTable(); 
      table.Locale = System.Globalization.CultureInfo.InvariantCulture; 
      dataAdapter.Fill(table); 
      bindingSource.DataSource = table; 

      // Resize the DataGridView columns to fit the newly loaded content. 
      dataGridView_ShowAllData.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader); 

     } 
     //catch the error if cannot get a database connection 
     catch (SqlException) 
     { 
      MessageBox.Show("FootPrint-LEMARS Database couldn't received a connection ***ERROR***"); 
     } 

    } 


    private void cmb_DatabaseSelection_SelectedIndexChanged(object sender, EventArgs e) 
    { 

     //Boolean selection statements to Fill the DataGridView based on the user selecction 
     if (cmb_DatabaseSelection.SelectedItem == "LeMars21St") 
     { 
      dataGridView_ShowAllData.DataSource = bindingSource; 

      //query with 11 columns 
      GetLeMarsConnectionDatabaseConnection("Select * from dbo.AllInvoicesInReadyStatus", lemars); 


     } 

     private void bgnWorker_LoadingForm_DoWork(object sender, DoWorkEventArgs e) 
    { 
     // TODO: query your database 
     // for easier reading I assume that your query-result has only one column 
     //string query = @"Select * from dbo.AllInvoicesInReadyStatus"; 
     //** did you strip your sql-execution-code? have a look at https://msdn.microsoft.com/de-de/library/system.data.sqlclient.sqlcommand.aspx 


     var queryResult = new List<object>(); 
     bgnWorker_LoadingForm.ReportProgress(10); 

     var table = new System.Data.DataTable(); 
     // TODO: create matching columns for your query-result in the datatable 
     // https://msdn.microsoft.com/de-de/library/system.data.datatable.newrow(v=vs.110).aspx 
     // Create new DataTable and DataSource objects. 

     // Declare DataColumn and DataRow variables. 
     DataColumn column; 
     DataRow row; 
     DataView view; 

     // Create new DataColumn, set DataType, ColumnName, and add to DataTable.  
     column = new DataColumn(); 
     column.DataType = typeof(string); 
     column.ColumnName = "invoice"; 
     table.Columns.Add(column); 

     // Create second column. 
     column = new DataColumn(); 
     column.DataType = typeof(string); 
     column.ColumnName = "shipment"; 
     table.Columns.Add(column); 

     // Create third column. 
     column = new DataColumn(); 
     column.DataType = typeof(string); 
     column.ColumnName = "Project"; 
     table.Columns.Add(column); 

     // Create fourth column. 
     column = new DataColumn(); 
     column.DataType = typeof(DateTime); 
     column.ColumnName = "invoiceDateTB"; 
     table.Columns.Add(column); 

     // Create fifth column. 
     column = new DataColumn(); 
     column.DataType = typeof(DateTime); 
     column.ColumnName = "CreatedDate"; 
     table.Columns.Add(column); 

     // Create sixth column. 
     column = new DataColumn(); 
     column.DataType = typeof(string); 
     column.ColumnName = "typeName"; 
     table.Columns.Add(column); 

     // Create seventh column. 
     column = new DataColumn(); 
     column.DataType = typeof(string); 
     column.ColumnName = "statusName"; 
     table.Columns.Add(column); 

     // Create eighth column. 
     column = new DataColumn(); 
     column.DataType = typeof(decimal); 
     column.ColumnName = "total"; 
     table.Columns.Add(column); 

     // Create ninth column. 
     column = new DataColumn(); 
     column.DataType = typeof(string); 
     column.ColumnName = "import_status"; 
     table.Columns.Add(column); 

     // Create tenth column. 
     column = new DataColumn(); 
     column.DataType = typeof(DateTime); 
     column.ColumnName = "Time_Completed"; 
     table.Columns.Add(column); 

     // Create eleventh column. 
     column = new DataColumn(); 
     column.DataType = typeof(string); 
     column.ColumnName = "ERROR_DESCRIPTION"; 
     table.Columns.Add(column); 



     for (var i = 0; i < queryResult.Count; i++) 
     { 
      var progress = 10 + (int)((float)i/queryResult.Count) * 90; 
      bgnWorker_LoadingForm.ReportProgress(progress); 
      //** dont know whats going on here 
      //** but normally you should iterate your data-reader here and transfer the data of your query result to the created row... like this: https://msdn.microsoft.com/de-de/library/haa3afyz(v=vs.110).aspx 
      row = table.NewRow(); 
      row["invoice"].ToString(); 
      row["shipment"].ToString(); 
      row["Project"].ToString(); 
      row["invoiceDateTB"] = typeof(DateTime); 
      row["CreatedDate"] = typeof(DateTime); 
      row["typeName"].ToString(); 
      row["statusName"].ToString(); 
      row["total"] = typeof(decimal); 
      row["import_status"].ToString(); 
      row["Time_Completed"] = typeof(DateTime); 
      row["ERROR_DESCRIPTION"].ToString(); 

      table.Rows.Add(row); 

      // TODO: add the row data to the table 
      // same link as before: https://msdn.microsoft.com/de-de/library/system.data.datatable.newrow(v=vs.110).aspx 
     } 

     //**begin: move this stuff to worker completed 
     // Create a DataView using the DataTable. . 
     view = new DataView(table); 
     //**end 

     // Set a DataGrid control's DataSource to the DataView. 
     dataGridView_ShowAllData.DataSource = view; 

     e.Result = table; 
    } 

    private void bgnWorker_LoadingForm_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     System.Data.DataTable table = (System.Data.DataTable)e.Result; 
     // TODO: Check for errors 
     // TODO: Assign the table to your grid 
     // TODO: unlock your ui, hide progress dialog 
    } 

    private void bgnWorker_LoadingForm_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     // TODO: update your progress dialog/progressbar, f.e. 
     prgBar_DataGridViewLoading.Value = e.ProgressPercentage; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     if (bgnWorker_LoadingForm.IsBusy) return; 
     bgnWorker_LoadingForm.RunWorkerAsync(); 
     // TODO: lock your ui, show progress dialog or progressbar... 
    } 
+0

你不能做到这一点与填充的方法,因为你没有在回路中的任何控制。您将不得不调整您的查询和代码以获取记录计数,然后循环遍历记录以使用单独的线程填充表。或者只是将进度条设置为一种标志样式。 – LarsTech

+0

我明白了,你可以显示例如有控制填充datadridview或进度条劳斯莱斯风格 – AndresBryan29

+0

'progressBar1.Style = ProgressBarStyle.Marquee时;' – LarsTech

你有一个BackgroundWorkerWorkerReportsProgress = true)如果你想“real'正在进行做手工的方式...

快速和脏描述:

1)在BackgroundWorker.DoWork函数查询您的表(10%),在本地创建匹配的DataTable,迭代结果并将其添加到您的本地DataTable(10-100%)。

2)使用ReportProgress将当前进度状态从BackgroundWorker.DoWork内部发送到您的用户界面。

3)在BackgroundWorker.ProgressChanged中,您可以安全地更新您的ui /进度条。

4)然后返回(赋值给DoWorkEventArgs.Result)的本地数据表,作为BackgroundWorker.DoWork结果...

5),并通过访问RunWorkerCompletedEventArgs.Result检索结果中BackgroundWorker.RunWorkerCompleted和数据表分配给您的DataGrid

快速和肮脏的,例如...

public partial class Form1 : Form 
{ 
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
    { 
     // TODO: query your database 
     // for easier reading I assume that your query-result has only one column 
     var queryResult = new List<object>(); 
     backgroundWorker1.ReportProgress(10); 

     var table = new DataTable(); 
     // TODO: create matching columns for your query-result in the datatable 
     // https://msdn.microsoft.com/de-de/library/system.data.datatable.newrow(v=vs.110).aspx 

     for (var i = 0; i < queryResult.Count; i++) 
     { 
      var progress = 10 + (int)((float)i/queryResult.Count) * 90; 
      backgroundWorker1.ReportProgress(progress); 

      // TODO: add the row data to the table 
      // same link as before: https://msdn.microsoft.com/de-de/library/system.data.datatable.newrow(v=vs.110).aspx 
     } 

     e.Result = table; 
    } 

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     DataTable table = (DataTable)e.Result; 
     // TODO: Check for errors 
     // TODO: Assign the table to your grid 
     // TODO: unlock your ui, hide progress dialog 
    } 

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     // TODO: update your progress dialog/progressbar, f.e. 
     progressBar1.Value = e.ProgressPercentage; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     if (backgroundWorker1.IsBusy) return; 
     backgroundWorker1.RunWorkerAsync(); 
     // TODO: lock your ui, show progress dialog or progressbar... 
    } 
} 

没有测试过,因为我有一个),没有测试 - 数据和b)建立一个完整的例子非常耗时。我也可以忘记的事,但是这可能是一条路可走...

+0

我会查清楚这一点,如果我有额外的问题,我会让你知道的,但如果不问得多可能您在语句的示例代码 – AndresBryan29

+0

抱歉,我没有看到你的代码示例中,我会做一个测试,让你知道的结果 – AndresBryan29

+0

的从dbo.AllInvoicesInReadyStatus查询SELECT *将显示数据 – AndresBryan29

不要忘记阅读亚历山大·彼得罗夫的链接...我发布第二个答案,而不是评论您的文章有语法高亮的.. 。请remeber我不能测试你的代码,但我已经添加了一些评论,带有前缀**

private void bgnWorker_LoadingForm_DoWork(object sender, DoWorkEventArgs e) 
    { 
     // TODO: query your database 
     // for easier reading I assume that your query-result has only one column 
     //string query = @"Select * from dbo.AllInvoicesInReadyStatus"; 
     //** did you strip your sql-execution-code? have a look at https://msdn.microsoft.com/de-de/library/system.data.sqlclient.sqlcommand.aspx 

     var queryResult = new List<object>(); 
     //queryResult.Add(query); 
     bgnWorker_LoadingForm.ReportProgress(10); 

     var table = new System.Data.DataTable(); 
     // TODO: create matching columns for your query-result in the datatable 
     // https://msdn.microsoft.com/de-de/library/system.data.datatable.newrow(v=vs.110).aspx 
     // Create new DataTable and DataSource objects. 

     // Declare DataColumn and DataRow variables. 
     DataColumn column; 
     DataRow row; 
     DataView view; 

     // Create new DataColumn, set DataType, ColumnName, and add to DataTable.  
     column = new DataColumn(); 
     //** you could write just typeof(string) here... 
     column.DataType = System.Type.GetType("System.String"); 
     column.ColumnName = "invoice"; 
     table.Columns.Add(column); 

     // Create second column. 
     column = new DataColumn(); 
     column.DataType = Type.GetType("System.String"); 
     column.ColumnName = "shipment"; 
     table.Columns.Add(column); 

     // Create second column. 
     column = new DataColumn(); 
     column.DataType = Type.GetType("System.String"); 
     column.ColumnName = "Project"; 
     table.Columns.Add(column); 

     // Create second column. 
     column = new DataColumn(); 
     column.DataType = Type.GetType("System.DateTime"); 
     column.ColumnName = "invoiceDateTB"; 
     table.Columns.Add(column); 

     // Create second column. 
     column = new DataColumn(); 
     column.DataType = Type.GetType("System.DateTime"); 
     column.ColumnName = "CreatedDate"; 
     table.Columns.Add(column); 

     // Create second column. 
     column = new DataColumn(); 
     column.DataType = Type.GetType("System.String"); 
     column.ColumnName = "typeName"; 
     table.Columns.Add(column); 

     // Create second column. 
     column = new DataColumn(); 
     column.DataType = Type.GetType("System.String"); 
     column.ColumnName = "statusName"; 
     table.Columns.Add(column); 

     // Create second column. 
     column = new DataColumn(); 
     column.DataType = Type.GetType("System.Int32"); 
     column.ColumnName = "total"; 
     table.Columns.Add(column); 

     // Create second column. 
     column = new DataColumn(); 
     column.DataType = Type.GetType("System.String"); 
     column.ColumnName = "import_status"; 
     table.Columns.Add(column); 

     // Create second column. 
     column = new DataColumn(); 
     column.DataType = Type.GetType("System.DateTime"); 
     column.ColumnName = "Time_Completed"; 
     table.Columns.Add(column); 

     // Create second column. 
     column = new DataColumn(); 
     column.DataType = Type.GetType("System.String"); 
     column.ColumnName = "ERROR_DESCRIPTION"; 
     table.Columns.Add(column); 



     for (var i = 0; i < queryResult.Count; i++) 
     { 
      var progress = 10 + (int)((float)i/queryResult.Count) * 90; 
      bgnWorker_LoadingForm.ReportProgress(progress); 

      row = table.NewRow(); 
     //** dont know whats going on here 
     //** but normally you should iterate your data-reader here and transfer the data of your query result to the created row... like this: https://msdn.microsoft.com/de-de/library/haa3afyz(v=vs.110).aspx 
      row["invoice"] = i; 
      row["shipment"] = "shipment" + i.ToString(); 
      row["Project"] = "Project" + i.ToString(); 
      row["invoiceDateTB"].ToString(); 
      row["CreatedDate"].ToString(); ; 
      row["typeName"] = "typeName" + i.ToString(); 
      row["statusName"] = "statusName" + i.ToString(); 
      row["total"].ToString(); 
      row["import_status"] = "import_status" + i.ToString(); 
      row["Time_Completed"].ToString(); ; 
      row["ERROR_DESCRIPTION"] = "ERROR_DESCRIPTION" + i.ToString(); 

      table.Rows.Add(row); 

      // TODO: add the row data to the table 
      // same link as before: https://msdn.microsoft.com/de-de/library/system.data.datatable.newrow(v=vs.110).aspx 
     } 

     //**begin: move this stuff to worker completed 
     // Create a DataView using the DataTable. 
     view = new DataView(table); 

     // Set a DataGrid control's DataSource to the DataView. 
     dataGridView_ShowAllData.DataSource = view; 
     //**end 

     e.Result = table; 
    } 
+0

声音我会检查它并测试它,让我们知道结果谢谢。 – AndresBryan29

+0

已尝试我仍然收到以下错误InvalidOperationException未被用户代码处理跨线程操作无效:从其创建的线程以外的线程访问的控件'dataGridView_ShowAllData'。 – AndresBryan29

+0

@ AndresBryan29请更新您的第一篇文章与您现有的代码,所以我们可以看到发生了什么......请包括所有三个BackgroundWorker的功能:DoWork的,ProgressChanged和RunWorkerCompleted – Michael