【问题标题】:WinForms: navigate TreeView in BackgroundWorker threadWinForms:在 BackgroundWorker 线程中导航 TreeView
【发布时间】:2016-01-20 16:45:20
【问题描述】:

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

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

【问题讨论】:

    标签: c# treeview backgroundworker


    【解决方案1】:

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

    您可以克隆您的根节点并将其传递给后台工作人员(bw) 展开该节点及其子节点,然后将其传回并将您的 root = 设置为 bw 结果(可以在 bw completed 方法中完成)。这会将所有扩展移至 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();
        }
    

    【讨论】:

    • 好像不错,我试试,谢谢。我知道我可以使用 expandall,但这是另一个想法:树通过 WCF 从 db 填充。我想要测试应用程序来为 W​​CF 和 db 创建加载。我单击按钮,树正在逐级扩展。这样我可以在应用程序或 N 个应用程序中运行 N 个表单,它们将创建自动加载。
    • 在这种情况下,用户看到树展开,但看不到进度,逐步展开。
    • 在这种情况下,我认为您对此有点倒退。而不是构建树然后尝试逐层扩展它。当您从数据库加载节点时,为什么不构建具有扩展节点的树?一旦我尝试使用 treeview.Nodes.Find 复制比 treeView.Nodes[0] 更深的节点,树就会停止扩展。我可以让它从已经填充的树中一次扩展一个节点的唯一方法是删除 bw completed 中的节点并重新添加该节点的扩展副本。
    • 您还可以将保存树的控件完全移动到单独的线程中,这样您就可以做您想做的事情而不必担心跨线程问题。它比设置 bw 稍微复杂一些,但我认为总体复杂性会更低。
    • 我正在开发用于负载测试的小应用程序,即它会折叠树然后逐步展开,再次折叠等。要展开的级别数和迭代次数是模拟较低的输入参数或更高的负载。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 2016-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多