WinForms:在 BackgroundWorker 线程中导航 TreeView

WinForms: navigate TreeView in BackgroundWorker thread

我有一个带有 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);
    }
 }

如果树很大,表格就会被冻结。如何在后台工作线程中扩展树?当我调用此函数时,我收到跨线程错误。

由于主线程拥有 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();
    }