WinForm TreeView 上逐层加载数据

TreeView 是一个很好的表达树形结构的控件。如果要加载的数据比较多的话,就需要逐层加载数据。要实现逐层加载数据,首先想到的就是TreeView 的 BeforeExpand 事件,它在节点展开前触发。但问题是BeforeExpand 事件每次展开时都会触发。有没有只在首次展开才触发的事件呢,可惜没找到。没关系,我们 
复制C#代码保存代码
/// <summary>
/// 自定义节点类,继承于系统的 TreeNode 类
///   自定义节点类的目的就是给节点增加一个 IsFirstExpand 属性
/// </summary>
public class DirNode : TreeNode
{
    
// 该节点是否首次被展开
    private bool isFirstExpand = true;

    
public DirNode()
        : 
base()
    { }

    
public DirNode(string text)
        : 
base(text)
    { }

    
/// <summary>
    
/// 该节点是否首次被展开
    
/// 因为 TreeNode 没有该属性,那我们自己定义吧!
    
/// </summary>
    public bool IsFirstExpand
    {
        
get { return isFirstExpand; }
        
set { isFirstExpand = value; }
    }
}自定义一个 TreeView 节点类,给它加一个是否首次被展开的属性。 
自定义 TreeView 节点类有了“是否首次被展开”的属性之后,逐层展开 TreeView  节点的算法如下: 
   
1)   在 Form_Load 时,先加载前两层节点(只是加载,不用展开)。 
   
2)   BeforeExpand 事件,判断该节点“是否首次被展开”。 
         如果该节点“是否首次被展开”,那么我们就给该节点的“每个子节点”,再添加“子节点”(如果有的话)。 

下面是一个加载目录树程序的完整代码: 
复制C#代码保存代码using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;

namespace DirectoryTree
{
    
public partial class DirectoryTreeForm : Form
    {
        
public DirectoryTreeForm()
        {
            InitializeComponent();
        }

        
private void DirectoryTreeForm_Load(object sender, EventArgs e)
        {
            
// 列出所有盘符:C:,D:,E:
            string[] drivers = Environment.GetLogicalDrives();
            
for (int i = 0; i < drivers.Length; i++)
            {
                
if (PlatformInvokeKernel32.GetDriveType(drivers[i]) == PlatformInvokeKernel32.DRIVE_FIXED)
                {
                    DirNode root 
= new DirNode(drivers[i]);
                    treeView1.Nodes.Add(root);
                    
// 添加一级目录
                    AddChildNotes(root);
                }
            }
        }

        
/// <summary>
        
///  节点展开之前事件
        
/// </summary>
        
/// <param name="sender"></param>
        
/// <param name="e"></param>
        private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            DirNode node 
= (DirNode) e.Node;
            
// 判断该节点是否首次被展开
            if (node.IsFirstExpand)
            {
                
// 为 e.Node 下的每个子节点,添加子节点
                for (int i = 0; i < node.Nodes.Count; i++)
                {
                    
// 添加子节点
                    AddChildNotes(node.Nodes[i]);
                }
                node.IsFirstExpand 
= false;
            }
        }

        
/// <summary>
        
/// 添加 node 的子节点
        
/// </summary>
        
/// <param name="node"></param>
        private void AddChildNotes(TreeNode node)
        {
            
try
            {
                DirectoryInfo dir 
= new DirectoryInfo(GetPathFromNode(node));
                DirectoryInfo[] e 
= dir.GetDirectories();
                FileInfo[] f 
= dir.GetFiles();
                
string name;
                
for (int i = 0; i < e.Length; i++)
                {
                    name 
= e[i].Name;
                    
if (!name.Equals("."&& !name.Equals(".."))
                    {
                        node.Nodes.Add(
new DirNode(name));
                    }
                }
                
for (int i = 0; i < f.Length; i++)
                {
                    name 
= f[i].Name;
                    node.Nodes.Add(
new DirNode(name));
                }
            }
            
catch
            { }
        }

        
/// <summary>
        
/// 获得该节点的完整路径
        
/// </summary>
        
/// <param name="node"></param>
        
/// <returns></returns>
        private string GetPathFromNode(TreeNode node)
        {
            
if (node.Parent == null)
            {
                
return node.Text;
            }
            
return Path.Combine(GetPathFromNode(node.Parent), node.Text);
        }
    }

    
/// <summary>
    
/// 目录节点类,继承于系统的 TreeNode 类
    
///   自定义节点类的目的就是给节点增加一个 IsFirstExpand 属性
    
/// </summary>
    public class DirNode : TreeNode
    {
        
// 该节点是否首次被展开
        private bool isFirstExpand = true;

        
public DirNode()
            : 
base()
        { }

        
public DirNode(string text)
            : 
base(text)
        { }

        
/// <summary>
        
/// 该节点是否首次被展开
        
/// 因为 TreeNode 没有该属性,那我们自己定义吧!
        
/// </summary>
        public bool IsFirstExpand
        {
            
get { return isFirstExpand; }
            
set { isFirstExpand = value; }
        }
    }


    
/// <summary>
    
/// API 函数
    
/// </summary>
    public class PlatformInvokeKernel32
    {
        [DllImport(
"KERNEL32", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
        
public static extern int GetDriveType(string lpRootPathName);
        
public const int DRIVE_FIXED = 3;
    }
}
posted on 2007-04-30 01:06  编程山人  阅读(916)  评论(0编辑  收藏  举报