不能在TreeView (WinForms)中展开节点
本文关键字:节点 WinForms TreeView 不能 | 更新日期: 2023-09-27 18:15:15
我以编程方式填充TreeView
(在不同的线程中,如果它重要的话)。
我希望在TreeView
加载到window时扩展第一层节点。我几乎到处都尝试过(在工作线程中,在主线程中,在Form.Load
, Form.Shown
等的事件处理程序中),但TreeView
仍然崩溃。
我做错了什么?
treeView.UpdateTree((object tree) => {
treeView.Nodes[0].Nodes.Add(text);
});
public static void UpdateTree(this Control ctrl, Action<object> code) {
if (ctrl.InvokeRequired) {
ctrl.BeginInvoke(code, (TreeView)ctrl);
}
else {
code.Invoke((TreeView)ctrl);
}
}
更新2
private void btnFillTree_Click(object sender, EventArgs e) {
......
treeDirectoryContents.Nodes.Add("GeneralFolder");
......
//there I create Thread() that fills treeDirectoryContents
......
treeDirectoryContents.ExpandAll();
}
据我所知…. NET 3.5)你不能从不同的线程访问GUI元素(你可以准备一些数据,但必须从主线程访问TreeView.Nodes
-使用Control.BeginInvoke
…你也可以检查Control.InvokeRequired
)。
填满所有节点后,可以直接执行
foreach (TreeNode node in treeView) node.Expand()
EDIT after UPDATE2:
- 节点只有在有子节点时才能扩展。
- 控件只能从主线程访问(检查
Control.InvokeRequired
) - BeginInvoke()是异步的(不等待)而
Invoke()
是同步的(像BeginInvoke + EndInvoke) - 永远不要从主线程调用
Thread.Join()
(使用BackgroundWorker.IsBusy
或模仿一些状态变量,例如bool done = false; thread.Start(); while(!done) Application.DoEvents()
来自MSDN的示例:
// Start the download operation in the background.
this.backgroundWorker1.RunWorkerAsync();
// Disable the button for the duration of the download.
this.downloadButton.Enabled = false;
// Once you have started the background thread you
// can exit the handler and the application will
// wait until the RunWorkerCompleted event is raised.
// Or if you want to do something else in the main thread,
// such as update a progress bar, you can do so in a loop
// while checking IsBusy to see if the background task is
// still running.
while (this.backgroundWorker1.IsBusy)
{
progressBar1.Increment(1);
// Keep UI messages moving, so the form remains
// responsive during the asynchronous operation.
Application.DoEvents();
}
EDIT -我认为应该如何做(使用线程)
using System;
using System.Threading;
using System.Windows.Forms;
class MyForm : Form {
public static void Main() {
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MyForm());
}
TreeView tree = new TreeView() { Dock = DockStyle.Fill };
MyForm() {
Controls.Add(tree);
tree.Nodes.Add("Loading...");
}
protected override void OnLoad(EventArgs e) {
new Thread(Fill).Start();
base.OnLoad(e);
}
void Create(string text) {
if (InvokeRequired) Invoke(new Action<string>(this.Create), text);
else tree.Nodes[0].Nodes.Add(text);
}
void Finish() {
if (InvokeRequired) Invoke(new Action(this.Finish));
else {
tree.Nodes[0].Text = "The Nodes";
tree.ExpandAll();
}
}
void Fill() {
for (int i = 0; i < 10; i++) {
Create("Node #" + i.ToString());
Thread.Sleep(100);
}
Finish();
}
}