Windows Form TreeView 上逐层加载数据

      TreeView 是一个很好的表达树形结构的控件。如果要加载的数据比较多的话,就需要逐层加载数据。要实现逐层加载数据,首先想到的就是TreeView 的 BeforeExpand 事件,它在节点展开前触发。但问题是BeforeExpand 事件每次展开时都会触发。有没有只在首次展开才触发的事件呢,可惜没找到。没关系,我们自定义一个 TreeView 节点类,给它加一个是否首次被展开的属性。
     ///   <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  节点的算法如下:
   1)   在 Form_Load 时,先加载前两层节点(只是加载,不用展开)。
   2)   在 BeforeExpand 事件,判断该节点“是否首次被展开”。
         如果该节点“是否首次被展开”,那么我们就给该节点的“每个子节点”,再添加“子节点”(如果有的话)。

下面是一个加载目录树程序的完整代码:
ContractedBlock.gif ExpandedBlockStart.gif 加载目录树程序的完整代码
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:dot.gif
            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;
    }
}

本文地址: http://www.cnblogs.com/anjou/archive/2006/12/28/605628.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值