无法在TreeView(WinForms)中展开节点 [英] Can't expand nodes in TreeView (WinForms)

查看:82
本文介绍了无法在TreeView(WinForms)中展开节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在以编程方式填充TreeView(如果重要的话,将其填充在其他线程中).

I'm filling TreeView programmatically (in different thread if it matters).

我希望在TreeView加载到窗口时扩展第一级节点.我几乎在所有地方都尝试过(在工作线程,主线程中,在Form.LoadForm.Shown的事件处理程序中),但是TreeView仍然崩溃.

I want the first level of nodes to be expanded when TreeView loads to window. I've tried almost everywhere (in worker thread, in main thread, in event handlers of Form.Load, Form.Shown etc.), but TreeView is still collapsed.

我在做什么错了?

更新

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).

As far I know (.NET 3.5) you cannot acces GUI elements from different thread (you can prepare some data but must access TreeView.Nodes from main thread only - use Control.BeginInvoke for that ... you can as well check Control.InvokeRequired).

填满所有节点后,您就可以做

After filling all the nodes you can just do

foreach (TreeNode node in treeView) node.Expand()

在UPDATE2之后进行

  1. 节点只有在有子节点时才可以扩展.
  2. 只能从主线程访问控件(请检查Control.InvokeRequired)
  3. BeginInvoke()是异步的(不等待),而Invoke()是同步的(例如BeginInvoke + EndInvoke)
  4. 请勿从主线程调用Thread.Join()(使用BackgroundWorker.IsBusy或通过某些状态变量(例如bool done = false; thread.Start(); while(!done) Application.DoEvents()
  5. )模仿
  1. Nodes can only be expanded when they have children.
  2. Controls can only be accessed from main thread (check Control.InvokeRequired)
  3. BeginInvoke() is asynchronous (does not wait) while Invoke() is synchronous (like BeginInvoke + EndInvoke)
  4. Never call Thread.Join() from main thread (use BackgroundWorker.IsBusy or mimic that by some state variable e.g. 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();
}

编辑-我该怎么做(使用线程)

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();
    }
}

这篇关于无法在TreeView(WinForms)中展开节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆