私はツリービューを表示するguiフォームを持っています。背景作業者がツリービューを構築している間、マーキーの進捗バーを使用するアラートフォームを表示します。私が持っている問題は、マーキーが表示されず、doworkが実行されている間ではなく、GUIに制御が戻るまで、progresschangedルーチンが起動しないということです。Backgroundworker_progresschangedは、コントロールがGUIに戻るときにのみ呼び出されます
誰も私が間違ってこれをコード化しているか、それがどのように動作するかを誤解しているか否かの判断が支援していただけますか?ありがとう。
セットアップ:
alert = new AlertForm();
alert.Message = string.Format("Building folder tree ({0}), please wait.", Global.RootDir);
// event handler for the Cancel button in AlertForm
alert.Cancelled += new EventHandler<EventArgs>(btnExit_Click);
alert.Show();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.DoWork += backgroundWorker1_DoWork;
backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
backgroundWorker1.ProgressChanged += backgroundWorker1_ProgressChanged;
backgroundWorker1.RunWorkerAsync();
バックグラウンドワーカーコード(.ReportProgressの上にではなくbackgroundWorker1_ProgressChangedにデバッグ段階):
worker running - no marquee in gui
worker complete - marquee displays in gui:表示されているもの
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
backgroundWorker1.ReportProgress(1);
Invoke(new MethodInvoker(() => CreateTreeView(treeView1)));
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
alert.Refresh();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
alert.Close();
if (treeView1.Nodes.Count > 0)
{
treeView1.ExpandAll();
treeView1.TopNode = treeView1.Nodes[0];
}
}
==============================================私は、新しいツリービューオブジェクトを作成するにそののクローニングになってしまっている下のコメントに基づいて==========================
GUIオブジェクト。
TreeView treeView = new TreeView();
CreateTreeView(treeView);
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
if (Global.Error)
{
_alert.Close();
string errorMessage = Global.ErrorMessage;
MessageBox.Show(errorMessage, @"Error occurred", MessageBoxButtons.OK);
Global.Error = false;
}
}
else
{
TreeView treeView = (TreeView)e.Result;
CopyTreeNodes(treeView, treeView1);
if (treeView1.Nodes.Count > 0)
{
treeView1.ExpandAll();
treeView1.TopNode = treeView1.Nodes[0];
}
_alert.Close();
treeView = null;
}
}
public void CopyTreeNodes(TreeView treeViewSource, TreeView treeViewTarget)
{
foreach (TreeNode node in treeViewSource.Nodes)
{
TreeNode treeNode = new TreeNode(node.Text, node.ImageIndex, node.SelectedImageIndex);
CopyNodeChildren(treeNode, node);
treeViewTarget.Nodes.Add((TreeNode)node.Clone());
}
}
public void CopyNodeChildren(TreeNode parent, TreeNode original)
{
foreach (TreeNode tn in original.Nodes)
{
TreeNode treeNode = new TreeNode(tn.Text, tn.ImageIndex, tn.SelectedImageIndex);
parent.Nodes.Add((TreeNode)tn.Clone());
CopyNodeChildren(treeNode, tn);
}
}
なし*実際に*ワーカースレッド上で実行されません。 Invoke()をすぐに呼び出してUIスレッド上で実行します。もちろん、コードが完了するまで何かが再描画されないようにします。このコードがワーカースレッド上で実行できることはほとんどありません。また、ワーカースレッドを使用しても多くの助けを借りることはありませんが、ユーザーはまだ仕事が完了するのを待っています。非常に大きなTreeViewの標準的な手法は、ユーザが展開するまで、実際のノードに置き換えられないダミーノードを追加することです。 –