我有一个Windows Forms 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);
但是我仍然不明白为什么初始代码有效,即使它需要两次。
答案 0 :(得分:2)
我怀疑一个TreeNode无法从一个TreeView更改为另一个
这是我的测试代码:
{KeyError}'table_table_'
如果我将using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button3_Click(object sender, EventArgs e)
{
ChangeTree(treeView1);
}
public void ChangeTree(TreeView tree)
{
Thread thread4 = new Thread(() => { UpdateTreeView(tree); });
thread4.Name = "Thread 4";
thread4.IsBackground = true;
thread4.Start();
}
private void UpdateTreeView(TreeView tree)
{
if (tree.InvokeRequired)
{
tree.Invoke((MethodInvoker)delegate
{
UpdateTreeView(tree);
});
}
else
{
tree.Nodes.Clear();
foreach (var node in GetTree())
{
tree.Nodes.Add(node as TreeNode);
}
}
}
private List<TreeNode> GetTree()
{
var result = new List<TreeNode>();
result.Add(new TreeNode("changed"));
return result;
}
}
}
功能更改为
GetTree()
将 private TreeView GetTree()
{
var result = new TreeView();
result.Nodes.Add(new TreeNode("changed"));
return result;
}
函数恢复为之前的状态,它的行为与您描述的一样
答案 1 :(得分:0)
您是否尝试将焦点设置回树视图?使用TreeView.Focus()会导致刷新。