我正在将数据表中的数据加载到应用程序的datagridview中。 这样做时,我想通过第二个窗体通知用户该应用程序仍在运行,该窗体上有一个进度条显示其进度和一个Label,其中包含有关已向数据网格中装入多少行的信息。
我确实知道将数据加载到App中会冻结我的GUI,所以我决定使用第二种形式从我的主要任务中调用它。
我打电话
Task task = new Task(LeftJoinTables);
task.Start();
然后在LeftJoinTables
中运行此代码
...
foreach(DataRow rows in FileJoinMail.Rows)
{
wfrm.UpdateProgressBar(++i);
dataGridView1.Rows.Add(
false, //Checkbox
rows["Fullpath"],
rows["Filename"],
rows["File Size"],
rows["UserID"],
rows["E-Mail"],
rows["Date"]);
wfrm.ProcInfo($@"Loading Data [{i.ToString()}/{count.ToString()}]");
}
在第二个表单类上,我获得了此方法,该方法调用Waitform,Waitform使用信息更新Progressbar和标签
public void ProcInfo(string message)
{
this.Invoke((MethodInvoker)delegate
{
ProcInfoLabel.Text = message;
});
}
public void UpdateProgressBar(int value)
{
this.Invoke((MethodInvoker)delegate
{
ProcBar.Value = value;
});
}
但是从这一点来看,我遇到了线程冲突。.我以为使用invoke可以解决这个问题。
答案 0 :(得分:1)
基本上,Windows UI(及其中的控件)使用消息泵(队列)更新,并且要使其正常工作,应创建控件的句柄。确保这一点的一种简单方法是确保您的表单可见(并且由于它是进度条,因此应该可见)。
private void button1_Click(object sender, EventArgs e)
{
wfrm.Show(); // make sure you are making the form visible before updating
Task task = new Task(LeftJoinTables);
task.Start();
}
private void LeftJoinTables()
{
wfrm.ProcInfo("test");
}
此外,您更新数据网格的调用也需要调用。
如果要在不显示控件的情况下强制其创建,可以使用以下内容(取自https://blogs.msdn.microsoft.com/mapo/2011/04/27/forcing-handle-creation-in-a-net-windows-forms-control/):
if (!mycontrol.IsHandleCreated)
{
// This call forces creation of the control's handle.
IntPtr handle = mycontrol.Handle;
}