【发布时间】:2023-04-07 19:20:01
【问题描述】:
我有一个 Windows 窗体 C# 应用程序,它处理 TreeView 并使用单独的线程来更新它。 单击按钮启动更新:
private void button3_Click(object sender, EventArgs e)
{
vc.ChangeTree(treeView1);
}
ChangeTree() 在单独的线程中启动 UpdateTree() 以异步更新 TreeView。 在这里我只需要使用 Thread 即可:
public void ChangeTree(TreeView tree)
{
Thread thread4 = new Thread(() => { UpdateTreeView(tree); });
thread4.Name = "Thread 4";
thread4.IsBackground = true;
thread4.Start();
}
UpdateTree() 只是调用 TreeView 并将另一棵树的节点添加到其中。请注意,没有耗时的操作。 GetTree() 只是返回另一个 TreeView:
private void UpdateTreeView(TreeView tree)
{
if (tree.InvokeRequired)
{
tree.Invoke((MethodInvoker)delegate
{
UpdateTreeView(tree);
});
}
else
{
tree.Nodes.Clear();
foreach (var node in GetTree().Nodes)
{
tree.Nodes.Add(node as TreeNode);
}
//Application.DoEvents(); // doesn't help
}
}
问题是它实际上将节点添加到树中,但表单没有显示它。单击按钮后,我检查了treeView1.Nodes。它包含我需要的节点。
根据我的搜索,Application.DoEvents() 没有帮助,即使它可能。 treeView1.Refresh() 也没有。
如果我单击按钮两次,treeView1 会按我的计划更新。但我不知道为什么,显然我不需要这种行为。
所以问题来了。如何让它一键更新?
事实证明,TreeNode 不能被多个 TreeView 使用。
解决方法我发现是使用treeNode.Clone():
tree.Nodes.Add((node as TreeNode).Clone() as TreeNode);
但是我仍然不明白为什么最初的代码可以工作,尽管它花了两次。
【问题讨论】:
-
您在
foreach循环之后尝试过tree.Invalidate()吗? -
@Übercoder 是的,没有结果
标签: c# multithreading winforms treeview