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

转载于:https://www.cnblogs.com/NetDeng/archive/2009/10/23/1588732.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值