비동기 트리 뷰에서 노드 값 변경
-
07-07-2019 - |
문제
확장 할 때 노드를 추가하기 위해 배경 작업자를 사용하는 TreeView가 있습니다. "로드"를 표시합니다. 확장 후 메시지가 표시되고 노드가로드 된 후 제거합니다. 잘 작동합니다. 이제 로딩 메시지를 "로드 ... 노드 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
}
해결책
(주) 문제는 BW_PROGRESSCHANDED와 관련이 있습니다. ProgressChanged를 동기화하는 것이 BGW의 작업이기 때문에 아무것도 호출 할 필요가 없습니다. 나는 아프지 않지만 어쨌든 호출을 느슨하게한다.
변경 사항이 보이지 않는 이유는 업데이트 ()가 없기 때문입니다.
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 () 메소드에서 호출을 사용합니다. 결과적으로 코드의 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_RUNWORKERCOMPETED에서 NewNodes의 요소를 'T'에 빠르게 추가하십시오.
제휴하지 않습니다 StackOverflow