WinForms:在BackgroundWorker线程中导航TreeView

时间:2016-01-20 16:45:21

标签: c# treeview backgroundworker

我有一个带有TreeView控件的简单WinForms应用程序。 我正在尝试创建ExpandAll函数。它调用获取选定节点并运行递归函数

private void expandNode2(TreeNode tn)
{
    if (tn == null) return;

    tn.TreeView.BeginUpdate();
    Application.DoEvents();
    tn.Expand();
    tn.TreeView.EndUpdate();
     foreach (TreeNode tnChild in tn.Nodes)
    {
        expandNode2(tnChild);
    }
 }

如果树很大,表格会冻结。如何在backgroundworker线程中展开树?当我调用此函数时,我收到了跨线程错误。

1 个答案:

答案 0 :(得分:0)

由于主线程拥有treeView,因此您需要调用invoke来更新树。但这会将节点的扩展重新放回主线程上,从而锁定你的UI。

您可以克隆根节点并将其传递给后台工作程序(bw) 展开该节点及其子节点然后将其传回并将root =设置为bw结果(可以在bw完成的方法中完成)。这将把所有扩展都转移到bw,但可能是昂贵的资源,因为我们必须首先克隆你的节点

    private void btnExpandR_Click(object sender, EventArgs e)
    {
        BackgroundWorker bw = new BackgroundWorker();
        TreeNode tempnode = treeView.Nodes[0].Clone() as TreeNode;
        bw.DoWork += bw_DoWork;
        bw.RunWorkerCompleted += NodeCopy;
        bw.RunWorkerAsync(tempnode);
    }

    private void NodeCopy(object sender, RunWorkerCompletedEventArgs e)
    {
        treeView.Nodes[0] = e.Result as TreeNode;
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        TreeNode tempNode = e.Argument as TreeNode;
        Exp(tempNode);
        e.Result = tempNode;
    }

    private void Exp(TreeNode tn)
    {
        tn.Expand();

        foreach(TreeNode t in tn.Nodes)
        {
            if(t.Nodes.Count > 0)
            {
                exp(t);
            }
        }
    }

您也可以使用

进行扩展
    private void Exp(TreeNode tn)
    {
        tn.ExpandAll();
    }