填写dataGridView谢谢backGroundWorker
我有这段代码:
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { remplirDataGrid(); } private void frmChercherActesLoad(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(); } private void remplirDataGrid() { dataGridView1.DataSource = ActeServices.getAllActes(0, 40); dataGridView1.Columns[0].Visible = false; dataGridView1.Columns[1].HeaderText = "Code acte"; dataGridView1.Columns[2].HeaderText = "Désignation"; dataGridView1.Columns[3].HeaderText = "Pris en charge"; dataGridView1.Columns[4].HeaderText = "Id article"; dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); }
这是方法getAllActe
:
public static IEnumerable getAllActes(int skipCount, int takeCount) { var myTableAdapter = new SmartDocDALServices.SmartDocDataSetTableAdapters.actesTableAdapter(); myTableAdapter.Fill(myDataSet.actes); var myResult = from q in myDataSet.actes.AsEnumerable() select new Acte { code = q.code, designation = q.designation, priseEnCharge = q.prise_en_charge, idArticle = q.id_article, }; if (skipCount != -1) myResult.Skip(skipCount); if (takeCount != -1) myResult.Take(takeCount); IEnumerable myResultRet = myResult.ToList(); return myResultRet;
我喜欢做的是在运行应用程序后使用后台工作程序填充我的datagridview
我收到此错误:
线程间操作无效:控制’dataGridView1已成为从创建它以外的线程进行访问的主题。
我试试这个
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { IEnumerable result = ActeServices.getAllActes(0, 40); backgroundWorker1.ReportProgress(0, result); } void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { dataGridView1.DataSource = (IEnumerable)e.UserState; dataGridView1.Columns[0].Visible = false; dataGridView1.Columns[1].HeaderText = "Code acte"; ***
但没有及时获得? 我希望当BGW加载数据foreash数据加载时,datagrid更新它将它添加到DGV
您无法从BackgroundWorker线程更新UI。
您需要向UI发送一个事件,然后执行以下操作:
private void EventHandler(object sender, YourEventArgs e) { if (this.dataGridView1.InvokeRequired) { this.dataGridView1.Invoke((MethodInvoker)delegate { this.AddToGrid(e.YourData); }); } else { this.AddToGrid(e.YourData); } }
DataGridView不是线程安全的。 但是,如果数据已经可用,则设置DataSource应该足够快。
我建议:
-
仅使用BackgroundWorker在另一个线程中加载数据
-
在RunWorkerCompleted事件中设置DataSource和datagridview的其他修改(您可以通过设置将结果从DoWork方法传递给Completed事件
e.Result = ActeServices.getAllActes(0,40);
-
可选:将dataGridView1.AutoGenerateColumns设置为false,并在Windows窗体设计器或代码中手动添加列以避免闪烁。
这是因为GUI内容无法从GUI线程以外的其他线程进行修改。 要解决此问题,您需要使用Dispatcher调用GUI线程上的更改。
应该事先设置DataGrid,因此您在异步操作中所做的就是填充数据。
var data = ActeServices.getAllActes(0, 40); Dispatcher.BeginInvoke( new Action( () => { dataGridView1.DataSource = data; }))
BackgroundWorker类旨在在后台线程上运行长期操作。 由于您只能从创建它们的线程访问UI组件,因此您可以使用BackgroundWorker类的RunWorkerCompleted事件在DoWork处理程序完成后更新UI。 此外,您可以使用BackgroundWorker类的ProgressChanged事件安全地更新进度UI。