问题的名称是:“从后台工作人员更新 GUI”,但正确的名字是 world :“从后台工作人员更新 GUI 或从后台工作人员报告多个变量(整数除外)"
请让我解释一下我的情况。在一个程序中,我有一个后台工作人员来分析信息。分析的结果是 - 表单 GUI 元素应该填充必要的数据。在 GUI 中我想更新
- 2 个数据网格视图
- 1 个列表框
- 5 labels
据我了解 - 我只能原生地报告1int
value via ReportProgress()
后台工作者的方法。
所以问题是 - 我怎样才能通过List<>
(+一些其他变量:string
, int
) via ReportProgress()
?基本上 - 我想用信息更新 GUI,但“1 个整数”是不行的。所以要么应该可以通过一个传递多个变量ReportProgress()
或者我可以使用Invoke
从BackgroundWorker本身内部更新GUI..我个人不喜欢Invoke
方法...你的意见是什么?
这是我的代码(见评论):
private void button9_Click(object sender, EventArgs e) // start BW
{
bw.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
bw.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.RunWorkerAsync(10);
}
private void button10_Click(object sender, EventArgs e) // cancel BW
{
bw.CancelAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int count = (int)e.Argument;
for (int i = 1; i <= count; i++)
{
if (bw.CancellationPending)
{
e.Cancel = true;
break;
}
List<List<string>> list_result = new List<List<string>>();
list_result = Proccess();
bw.ReportProgress(list_result.Count()); // right now I can only return a single INT
/////////// UPDATE GUI //////////////
// change datagridview 1 based on "list_result" values
// change datagridview 2
// change listbox
// change label 1
// change label ..
Thread.Sleep(20000);
}
MessageBox.Show("Complete!");
e.Result = sum;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
prog_count++;
listBox1.Items.Add("Count: (" + prog_count.ToString() + "/20). Found: " + e.ProgressPercentage.ToString() + ".");
}
有一个UserState
调用时的参数ReportProgress
.
var list_result = new List<List<string>>();
new backgroundWorker1.ReportProgress(0, list_result);
参数类型是object
所以你必须将其转换回你需要的类型:
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
var userState = (List<List<string>>)e.UserState;
}
棘手的问题是,如何确定是否要传回List
,或列表的列表,或单个字符串,数字等。您必须测试中的每种可能性ProgressChanged
event.
void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
var myList = e.UserState as List<List<string>>;
if (myList != null)
{
// use list
return;
}
int myNumber;
if (Int32.TryParse(e.UserState.ToString(), out myNumber))
{
// use number
return;
}
var myString = e.UserState.ToString();
// use string
}
或者,您可以创建一个类来保存您需要的所有值(或使用Tuple http://msdn.microsoft.com/en-us/library/system.tuple%28v=vs.110%29.aspx),在后台运行所有内容以填充该类,然后将其传递给RunWorkerCompleted
事件,并从那里立即更新您的 UI。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)