我正在用大量数据填充树视图,通常程序需要一段时间才能将控制权交还给用户(我想这只是树视图方面的进程太多了(。所以我决定给用户一个进度条来显示一切进展顺利。
在这个树视图中,我选择了一个文件夹,该文件夹中的所有xml文件都将添加到该文件夹中,树视图如下所示:
+ FOLDER NAME 1
|__xml file name 1
|__xml file name 2
+FOLDER NAME 2
|__xml file name 1
|__xml file name 2
所以问题是,我的进度条实际上会比树视图本身完成得快得多,我认为是progam让树视图可见的时候花了必要的时间。我该怎么做?
这是我的代码,用于浏览文件夹并将其传递给一个函数来填充树视图(对不起,它太长了,但我认为它会让它更清楚(正如你所看到的,我希望在向树视图添加节点时,将进度条的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());
进度条的固定最大值在TreeView开始加载之前,Still progressbar已完成(已达到最大值(。。。
int progressSteps = (files.Length / 100)/2;
这很神秘,但我当然不明白其中的逻辑。代码很难阅读,您应该将其分解并使用更多的辅助方法。试试这个:
toolStripProgressBar.Maximum = files.Length;
您可以跳过进度条,如果您只是每隔一段时间调用Application.DoEvents()
,它将显示TreeView随节点一起扩展,并且应该与用户足够相关,以了解他们需要等待多长时间。
也许可以使用marquee的进度条模式,它只是在进度条上来回移动,然后在加载完树后隐藏进度条?这样你仍然可以看到应用程序正在做一些工作,而用户可以知道要等待吗?
progressBar1.Style=ProgressBarStyle.Markee;
检查值工具StripProgressBar.Maximum。当您的流程完成时,它是否等于ProgressBar的值?
如果ProgressBar的Step属性为1,则应等于要在ProgressBar上显示的步骤数。这可能是因为toolStripProgressBar.Maximum设置得太高,所以在流程完成之前它永远不会到达终点。
更好的方法可能是根据需要填充树的分支;因此,当用户打开一个新分支时,只需获取子分支即可。在一次启动中填充整个树是浪费的,因为用户可能只对树的一小部分感兴趣,而不想等待整个内容加载,以便查看他们感兴趣的树的一小部分。
看看BackgroundWorker。它允许您从一个单独的步骤填充树视图,使您的用户界面反应更灵敏。它还支持报告进度,所以如果你仍然想显示进度条,这是完全可能的。
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
http://www.codeproject.com/KB/cpp/BackgroundWorker_Threads.aspx