在填充巨大的TreeView时使用ProgressBar

时间:2011-04-08 22:32:10

标签: c# process treeview load progress-bar

我正在使用大量数据填充树视图,并且通常程序需要一段时间才能将控件返回给用户(我想这在树视图方面只是过多的过程)。因此,我决定给出一个进度条,以显示用户的情况正常。

在这个树视图中,我选择了一个文件夹,该文件夹中的所有xml文件都将添加到该文件夹​​中,树视图如下所示:

+ FOLDER NAME 1
|__xml file name 1
|__xml file name 2
+FOLDER NAME 2
|__xml file name 1
|__xml file name 2

问题是,我的进度条实际上将比树视图本身更快地完成,我认为是时候让树视图可见需要时间。我怎么能这样做?

这是我浏览文件夹并将其传递给填充树视图的函数的代码(抱歉太长了,但我会让它更清晰)如你所见,我希望50%的进度条被填充在这部分和其他50部分中添加节点到树视图:

        private void toolStripBrowseDirectory_Click(object sender, EventArgs e)
    {
        //Reset progressbar
        toolStripProgressBar.Value = 0;

        folderBrowser.ShowNewFolderButton = false;
        DialogResult result = folderBrowser.ShowDialog();

        int countAllfiles = 0;
        int countGoodFiles = 0;

        if (result == DialogResult.OK)
        {
            toolStripProgressBar.Value = 0;

            string selectedFolder = folderBrowser.SelectedPath;
            string[] files = Directory.GetFiles(selectedFolder, "*.xml", SearchOption.AllDirectories);
            List<string> goodFiles = new List<string>();

            toolStripProgressBar.Maximum = files.Length;

            countAllfiles = files.GetLength(0);

            //Folder name
            FileInfo folderInfo = new FileInfo(selectedFolder);
            string folderName = folderInfo.Name;

            if (countAllfiles != 0)
            {
                foreach (string file in files)
                {
                    //file name
                    FileInfo fileInfo = new FileInfo(file);
                    string fileName = fileInfo.Name;

                    try
                    {
                        XmlDocument checkFileType = new XmlDocument();
                        checkFileType.Load(file);

                        if (checkFileType.SelectSingleNode("//Document/@Type").Value == "Test Results")
                        {
                            countGoodFiles++;
                            goodFiles.Add(file);
                        }
                    }
                    catch (Exception a)
                    {
                        StartForm.setDebug("Comparison Mode", a.Message, 21, "Can not read Selected XML file '" + fileName + "'", "Check file for compatibilyty", "File was excluded from list");
                    }

                    this.toolStripProgressBar.PerformStep();
                }

                if (countGoodFiles == 0)
                {
                    MessageBox.Show("There are no compatible XML files (exported from ZTR files) in '" + folderName + "'", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    StartForm.setDebug("Comparison Mode", "N/A", 20, "There are no compatible XML files (exported from ZTR files) in '" + folderName + "'", "Select a folder that contains compatible files!", "No file has been added to Select File Tree");
                    toolStripProgressBar.Value = 100;
                }
                else if (countGoodFiles > 0)
                {
                    this.Cursor = Cursors.WaitCursor;

                    AddFilesToTree(folderName, goodFiles.ToArray());

                    this.Cursor = Cursors.Default;
                }
            }
            else
            {
                MessageBox.Show("There are no XML files in '" + folderName + "'", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);                    
            }
        }           
    }

这是用于poulating treeview

        private void AddFilesToTree(string folder, string[] files)
    {
        //Define folder node
        TreeNode folderNode = new TreeNode();
        folderNode.Text = folder;
        folderNode.Name = "folder";
        folderNode.Tag = folder;

        treeViewBrowsedFiles.Nodes.Add(folderNode);

        //Define file node
        foreach (string file in files)
        {
            try
            {
            //To check if the file is a valid test result (converted to XML from ZTR files)
            XmlDocument checkFileType = new XmlDocument();
            checkFileType.Load(file);

                LoadZTRCmp xml = new LoadZTRCmp(file);

                TreeNode fileNode = new TreeNode();
                fileNode.Text = xml.FileInfo("BatchNumber");
                fileNode.Name = "file";
                fileNode.Tag = file;

                folderNode.Nodes.Add(fileNode);

                this.toolStripProgressBar.PerformStep();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }

        folderNode.Toggle();
    }

那么如何正确地做到这一点?

更新 ** 解决了 ** 我发现了这个问题,在使用函数向treeview添加节点之前我必须先做这行!

                        toolStripProgressBar.Maximum += countGoodFiles;

                    AddFilesToTree(folderName, goodFiles.ToArray());

进度条的固定MAX值 在TreeView开始加载之前,仍然进度条完成(最大化)...

6 个答案:

答案 0 :(得分:1)

如果你经常只调用Application.DoEvents(),你可以跳过进度条,它会显示随节点扩展的TreeView,并且应该足以让用户知道他们需要等待多长时间。

答案 1 :(得分:1)

也许使用marquee的进度条模式,它只是在进度条上来回移动,然后在加载树时隐藏进度条?那样你仍然可以看到应用程序的可见性正在做一些工作,用户可以知道等待吗?

progressBar1.Style = ProgressBarStyle.Marquee;

答案 2 :(得分:1)

       int progressSteps = (files.Length / 100)/2;

这很神秘,但我当然不理解逻辑。代码很难阅读,你应该分解它并使用更多的辅助方法。试试这个:

        toolStripProgressBar.Maximum = files.Length;

答案 3 :(得分:1)

检查值toolStripProgressBar.Maximum。当您的流程完成时,它是否等于ProgressBar的值?

如果ProgressBar的Step属性为1,则它应该等于您要在ProgressBar上显示的步数。 toolStripProgressBar.Maximum可能设置得太高,因此在您的流程完成之前它永远不会到达终点。

答案 4 :(得分:0)

更好的方法可能是根据需要填充树的分支;因此,当您的用户打开一个新分支时,只需获取子分支。在一次启动时填充整个树是浪费的,因为您的用户可能只对树的一小部分感兴趣并且不想等待整个事情加载,以便他们可以查看小部分他们感兴趣的树。

答案 5 :(得分:0)

看看BackgroundWorker。它允许您从单独的步骤填充树视图,使您的用户界面更具响应性。它还支持报告进度,因此如果您仍想显示进度条,则完全可以。

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
http://www.codeproject.com/KB/cpp/BackgroundWorker_Threads.aspx