我怎样才能更新listView或标签和报告backgroundworker进度更改而不使用invoke?
问题描述:
我不确定invoke是否正确使用它。它工作正常,但我想知道如果我应该使用invoke或其他方式来更新gui控件?如果我想报告更多的1个GUI控件?我怎样才能更新listView或标签和报告backgroundworker进度更改而不使用invoke?
现在我正在使用invoke更新label2和listView控件。 什么时候应该使用invoke,何时不使用,然后如何更新这个gui控件而不用调用?
private string pathtosearch;
private int countfiles;
public Form1()
{
InitializeComponent();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
DirSearch(pathtosearch);
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
}
void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d))
{
Invoke((MethodInvoker)delegate
{
countfiles += 1;
label2.Text = countfiles.ToString();
});
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Invoke((MethodInvoker)delegate
{
ListViewCostumControl.lvnf.Items.Add(excpt.Message);
});
}
}
private void button1_Click(object sender, EventArgs e)
{
DialogResult result = folderBrowserDialog1.ShowDialog();
if (result == DialogResult.OK)
{
label1.Text = folderBrowserDialog1.SelectedPath;
pathtosearch = folderBrowserDialog1.SelectedPath;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (textBox1.TextLength > 0)
backgroundWorker1.RunWorkerAsync();
}
答
使用ReportProgress
方法发送信息给用户界面和ProgressChanged
事件来处理该消息。
private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
var ex = e.UserState as Exception;
if(ex!= null)
ListViewCostumControl.lvnf.Items.Add(ex.Message);
else
label2.Text = e.ProgressPercentage.ToString();;
}
void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d))
backgroundWorker1.ReportProgress(countfiles++);
DirSearch(d);
}
}
catch (System.Exception excpt)
{
backgroundWorker1.ReportProgress(countfiles, excpt);
}
}
ReportProgress
可以用两个参数重载:一个数字来报告简单“进步”,称为类型的对象的UserData一个thesecond。如果你想发送信息丰富,插入这种说法您的自定义对象或任何其他现有的具有所需性能,并在另一边 - 在ProgressChanged
事件,再次“投”,它为适当的类型,例如:
ReportProgress
:
backgroundWorker1.ReportProgress(countfiles, Tuple.Create(currFile, "Copying...", timeRem));
ProgressChanged
事件:
var data = e.UserState as Tuple<string, string, TimeSpan>;