当具有树形结构的数据的结点很多而且树的深度比较大时,直接用递归遍历明显能发现性能很低。因此,不要一次全部加载,而是当用户点击展开时才加载此结点下的子结点。
实现要点:
每加载添加一个结点时,判断该结点是否为叶子(即不含子结点),若包含子结点,先添加一个空的子节点,这样做主要是让用户在界面能看到“+”表示结点能展开。当用户点击“+”时触发treeView_AfterExpand事件,在该事件中处理添加子结点数据,添加之前,清理删除掉以前的结点。
public partial class MainForm2 : Form
{
public MainForm2()
{
InitializeComponent();
this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
private void MainForm2_Load(object sender, EventArgs e)
{
BindDrives();
}
private void BindDrives()
{
DriveInfo[] drvs = DriveInfo.GetDrives();
foreach (DriveInfo drv in drvs)
{
TreeNode root = new TreeNode();
root.Text = drv.Name;
root.Tag = drv.RootDirectory.ToString();
// root.Nodes.Add("");
treeView1.Nodes.Add(root);
if (Directory.Exists(drv.RootDirectory.ToString()))
{
DirectoryInfo dInfo = new DirectoryInfo(drv.RootDirectory.ToString());
FileSystemInfo[] files = dInfo.GetFileSystemInfos();
if (files.Length > 0) //有子节点,先添加一个空节点
{
root.Nodes.Add("emptyNode", string.Empty);
}
}
}
}
//展开节点,移除以前的空节点,加载子节点
private void treeView1_AfterExpand(object sender, TreeViewEventArgs e)
{
TreeNode parentNode = e.Node;
// parentNode.Nodes.RemoveByKey("emptyNode");//移除空节点
parentNode.Nodes.Clear();
string path = parentNode.Tag.ToString();
if (Directory.Exists(path))
{
DirectoryInfo dir = new DirectoryInfo(path);
FileSystemInfo[] files = dir.GetFileSystemInfos();
foreach (FileSystemInfo f in files)
{
TreeNode node = new TreeNode();
node.Text = f.Name;
node.Tag = f.FullName;
parentNode.Nodes.Add(node); //加载子节点
if (Directory.Exists(node.Tag.ToString()))
{
DirectoryInfo subDir = new DirectoryInfo(node.Tag.ToString());
if (subDir.Attributes != (FileAttributes.System | FileAttributes.Hidden | FileAttributes.Directory))
{
FileSystemInfo[] subFiles = subDir.GetFileSystemInfos();
if (subFiles.Length > 0) //有子节点,先添加一个空节点
{
node.Nodes.Add("emptyNode", string.Empty);
}
}
}
}
}
运行结果如图:
这样,只加载用户要展开的结点,而且每次只加载当前结点的下一代,性能明显能提升,当然还能用多线程技术改善性能、用WindowsAPI获取文件图标并关联TreeView结点,这里就不介绍了。
代码:https://files.cnblogs.com/sndnnlfhvk/TViewSource.rar
递归示例(一):遍历二叉树 http://www.cnblogs.com/sndnnlfhvk/archive/2011/03/31/2001015.html
递归示例(二):WinForm之TreeView的应用—绑定区域树 http://www.cnblogs.com/sndnnlfhvk/archive/2011/03/31/2001064.html
递归示例(三):WinForm之TreeView的应用—绑定磁盘目录(一) http://www.cnblogs.com/sndnnlfhvk/archive/2011/03/31/2001065.html
递归示例(四):WinForm之TreeView的应用—绑定磁盘目录(二) http://www.cnblogs.com/sndnnlfhvk/archive/2011/03/31/2001072.html