Использование ProgressBar при заполнении огромного TreeView - PullRequest
0 голосов
/ 09 апреля 2011

Я заполняю древовидную структуру большим количеством данных, и обычно программе требуется некоторое время, чтобы вернуть управление пользователю (я полагаю, что это слишком большой процесс на стороне древовидного представления).Поэтому я решил дать индикатор выполнения, чтобы показать, что все идет хорошо для пользователя.

В этом древовидном представлении я выбираю папку, и все 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);                    
            }
        }           
    }

И это для выравнивания древовидной структуры

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

Так как же сделать это правильно?

Обновление: ** решено ** Я обнаружил проблему, мне пришлось сделать эту строку, прежде чем использовать функцию для добавления узлов в древовидную структуру !!!

                        toolStripProgressBar.Maximum += countGoodFiles;

                    AddFilesToTree(folderName, goodFiles.ToArray());

фиксированное значение MAX для индикатора выполнения Тем не менее индикатор выполнения завершается (максимально) до того, как TreeView начинает загружаться ...

Ответы [ 6 ]

1 голос
/ 09 апреля 2011

Проверьте значение toolStripProgressBar.Maximum.Это равно значению ProgressBar, когда ваш процесс завершается?

Если свойство шага ProgressBar равно 1, оно должно быть равно количеству шагов, которые вы хотите отобразить на ProgressBar.Возможно, toolStripProgressBar.Maximum установлен слишком высоко, и поэтому он никогда не достигает конца до завершения вашего процесса.

1 голос
/ 09 апреля 2011
       int progressSteps = (files.Length / 100)/2;

Это довольно загадочно, но я, конечно, не понимаю логику. Код трудно читать, вы должны разбить его и использовать больше вспомогательных методов. Попробуйте вместо этого:

        toolStripProgressBar.Maximum = files.Length;
1 голос
/ 09 апреля 2011

Может быть, использовать режим индикатора состояния индикатора, который просто перемещается назад и вперед по индикатору выполнения, а затем скрывать индикатор выполнения, когда дерево загружается? Таким образом, вы все равно получите видимость того, что приложение выполняет некоторую работу, и пользователь может знать, что ждать?

progressBar1.Style = ProgressBarStyle.Marquee;

1 голос
/ 09 апреля 2011

Вы можете пропустить индикатор выполнения, если будете просто вызывать Application.DoEvents() время от времени, он покажет TreeView, расширяющийся с узлами, и должен быть достаточно релевантным для пользователя, чтобы знать, сколько ему еще нужно ждать.

0 голосов
/ 09 апреля 2011

Посмотрите на BackgroundWorker.Это позволяет вам заполнить дерево в виде отдельного шага, что делает ваш пользовательский интерфейс более отзывчивым.Он также поддерживает создание отчетов о прогрессе, поэтому если вы все еще хотите отображать индикатор выполнения, это вполне возможно.

0 голосов
/ 09 апреля 2011

Лучшим подходом, вероятно, является заполнение ветвей дерева по мере необходимости; поэтому, когда ваш пользователь открывает новую ветку, просто получите подветви. Заполнение всего дерева за один раз при запуске является расточительным, потому что есть вероятность, что ваш пользователь интересуется только небольшой частью дерева и не хочет ждать загрузки всей вещи просто для того, чтобы он мог просмотреть маленькую часть дерева, в котором они заинтересованы.

...