Frage

Ich habe einen treeview BackGround Arbeiter mit Knoten hinzuzufügen, wenn Sie jede erweitern. Ich zeige ein „Loading ..“ Nachricht nach dem erweitern und entfernen Sie es, nachdem die Knoten geladen werden. Es funktioniert gut, und alle. Jetzt möchte ich „Loading ... Knoten n / n“ die Ladenachricht ändern. Ich war in der Lage, es zu tun, aber das Problem ist diese Meldung nicht angezeigt wird (aktualisiert) , während tun Sie den Knoten Hinzufügen Operation aber , nachdem es abgeschlossen . Ich kann nicht herausfinden, was ich falsch mache, und ich hoffe, dass jemand ein Licht auf diesem verschütten kann.

Hier ist mein Code. Ich gedebuggt SetValue-Methode und aktualisiert korrekt den Knotentext, aber nicht bis zum Ende des Vorgangs angezeigt ..

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
}
War es hilfreich?

Lösung

Das (Haupt-) Problem ist, mit Ihrem bw_ProgressChanged. Es braucht nichts an Invoke, weil es die BGW Job ist es, die Progress zu synchronisieren. Ich tut nicht weh, aber verlieren die Invoke trotzdem.

Der Grund, warum Sie keine Änderungen sehen Sie, ist das Fehlen eines 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

}

Es gibt ein weiteres Problem in bw_DoWork () Sie Invoke verwenden, um auf den AddSubNodes () -Methode. Als ein Ergebnis von 99% des Codes läuft vollständig auf dem Haupt-Thread und Ihre Lösung ist überhaupt nicht multi-threaded.

Ich würde so etwas wie:

//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;
}

Und dann, in bw_RunWorkerCompleted, fügen Sie schnell die Elemente newNodes zu 't'.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top