更改异步TreeView中节点的值

时间:2009-09-15 15:41:54

标签: c# .net winforms tree backgroundworker

我有一个使用BackGround worker的树视图,可以在展开任何节点时添加节点。我在展开后显示“正在加载...”消息,并在加载节点后将其删除。一切正常。现在我想将加载消息更改为“正在加载...节点n / n”。我能够做到这一点,但问题是这条消息没有显示(更新到),而执行节点添加操作,但完成后。我无法弄清楚我做错了什么,我希望有人能够对此有所了解。

这是我的代码。我调试了SetValue方法,它正确地更新了节点文本,但是直到操作结束才显示它。

private void t_AfterExpand(object sender, NodeEventArgs e)
{
    t.AppendNode(new object[] { "Loading.." }, e.Node);
    bw.RunWorkerAsync(new object[] { e.Node });
}

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    t.Invoke(new MethodInvoker( () => AddSubNodes(e.Argument) ));
    e.Result = e.Argument;
}

private void AddSubNodes(object arg)
{
    object[] args = arg as object[];
    TreeListNode parentNode = args[0] as TreeListNode;

    int nodeCount = 10;
    for (int i = 0; i < nodeCount; i++)
    {
        t.AppendNode(new object[] { "node cell text" }, parentNode);
        bw.ReportProgress(i, new object[]{ parentNode, "node: " + i.ToString() + "/" + nodeCount.ToString()});
    }
}

private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    object[] args = e.UserState as object[];
    TreeListNode parentNode = args[0] as TreeListNode;
    string percentMsg = args[1].ToString(); //node: n/n message

    t.Invoke(new MethodInvoker(() => parentNode.Nodes[0].SetValue(0, percentMsg))); //change "Loading.." to "node: n/n"
    //parentNode.Nodes[0].SetValue(0, mesaj);
}

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    object[] result = e.Result as object[];
    TreeListNode node = result[0] as TreeListNode;

    node.Nodes.RemoveAt(0); //remove loading text
}

1 个答案:

答案 0 :(得分:0)

(主要)问题在于你的bw_ProgressChanged。它不需要调用任何东西,因为它是Bgw的同步ProgressChanged的工作。我没有受伤,但无论如何都松开了Invoke。

您没有看到任何更改的原因是缺少Update()。

private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    object[] args = e.UserState as object[];
    TreeListNode parentNode = args[0] as TreeListNode;
    string percentMsg = args[1].ToString(); //node: n/n message

    parentNode.Nodes[0].SetValue(0, percentMsg); //change "Loading.." to "node: n/n"
    parentNode.TreeView.Update(); // or Form.Update

}

bw_DoWork()中存在另一个问题,您在AddSubNodes()方法上使用Invoke。因此,99%的代码完全在主线程上运行,而您的解决方案根本不是多线程的。

我会做类似的事情:

//untested
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
//    t.Invoke(new MethodInvoker( () => AddSubNodes(e.Argument) ));
    object[] args = arg as object[];
    TreeListNode parentNode = e;

    var newNodes = new List<TreeNode>();

    int nodeCount = 10;
    for (int i = 0; i < nodeCount; i++)
    {
       // t.AppendNode(new object[] { "node cell text" }, parentNode);
        newNodes.Add(new object[] { "node cell text" }); // ???
        bw.ReportProgress(i, new object[]{ parentNode, "node: " + i.ToString() + "/" + nodeCount.ToString()});
    }

    // e.Result = e.Argument;
    e.Result = newNodes;
}

然后,在bw_RunWorkerCompleted中,快速将newNodes的元素添加到't'。