У меня есть дерево, использующее BackGround, чтобы добавлять узлы при расширении. После разворачивания я вывешиваю сообщение «Загрузка ..» и удаляю его после загрузки узлов. Он работает отлично и все. Теперь я хочу изменить загружаемое сообщение на «Загрузка ... узла n/n». Я смог это сделать, но проблема в том, что это сообщение не отображается (обновлено до) , а выполняет операцию добавления узлов, но после того, как оно завершено.. Я не мог понять, что я делаю неправильно, и я надеюсь, что кто-то может пролить свет на это.Изменение значения узла в асинхронном TreeView
Вот мой код. Я отлажена 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
}
Большое спасибо. Как кто-то, кто только начал использовать BackgroundWorker, я хотел бы задать две вещи: 1. Не работает ли в отдельной теме? Таким образом, не должны ли мои приложения AddSubNodes() работать в этом отдельном потоке? 2. Если мне нужно выполнить работу в RunWorkerCompleted, в чем смысл DoWork? Я предполагаю, что у меня что-то отсутствует с BackGroundWorker. – dstr
1) Да, DoWork is async, но Invoke отталкивает (все) работу обратно к основной теме. 2) Вы должны использовать BGW для выполнения большей части работы без GUI (выборка данных для узлов) и касаться только GUI через Invoke, UpdateProgress или Completed. –
Я переместил вызов AddSubNodes() из DoWork в RunWorkerCompleted, дерево все еще зависает во время работы. Пытался вызвать его, так же повесить трубку. Что случилось с этим? – dstr