2017-08-01 130 views
0

我需要我的應用程序幫助,我的應用程序中的所有內容都能正常工作,但我想添加最後一個幫助用戶的細節使用應用程序。如何在將數據加載到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

回答

0

你有一個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

0

不要忘記閱讀亞歷山大·彼得羅夫的鏈接...我發佈第二個答案,而不是評論您的文章有語法高亮的.. 。請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

相關問題