zoukankan      html  css  js  c++  java
  • [转]C#中TreeView组件使用方法初步

    TreeView组件是由多个类来定义的,TreeView组件是由命名空间"System.Windows.Forms"中的"TreeView"类来定义的,而其中的节点(即Node),是由命名空间"System.Windows.Forms"中的"TreeNode"来定义的。所以当在程序中创建一个TreeView对象,其实只是创建了一个可以放置节点的"容器"。而在这个容器中加入一个节点,其实就是加入了从"TreeNode"类中创建的一个节点对象;同样删除一个节点,也就是删除一个"TreeNode"节点对象。

      一. 本文中介绍的程序设计及运行环境

       (
    1).微软视窗2000 服务器版

       (
    2)..net Framework SDK 正式版

      二. C#操作TreeView组件中的一些常用方法以及具体实现:

      TreeView组件虽然是一个操作起来比较麻烦的组件,但归根到底,可以总结为三种基本操作:加入子节点、加入兄弟节点和删除节点。掌握了这三种常用操作,对于在编程中灵活运用TreeView组件是十分必要的。下面就分别来加以介绍。

      (
    1).加入子节点:

      所谓子节点,就是处于选定节点的下一级节点。加入子节点的具体过程是:首先要在TreeView组件中定位要加入的子节点的位置,然后创建一个节点对象,然后利用TreeVeiw类中对节点的加入方法(即:Add ( )方法),加入此节点对象。下面就是在treeView1组件中加入一个子节点的具体代码:

      
    //首先判断是否选定组件中的位置
    if ( treeView1.SelectedNode == null )
    {
    MessageBox.Show ( 
    "请选择一个节点" , "提示信息" , MessageBoxButtons.OK , MessageBoxIcon.Information ) ;
    }
    else
    {
    //创建一个节点对象,并初始化
    TreeNode tmp ;
    tmp 
    = new TreeNode ( "节点名称" ) ;
    //在TreeView组件中加入子节点
    treeView1.SelectedNode.Nodes.Add ( tmp ) ;
    treeView1.SelectedNode 
    = tmp ;
    treeView1.ExpandAll ( ) ;


      (
    2).加入兄弟节点:

      所谓兄弟节点,就是在选定的节点的平级的节点。加入兄弟节点的方法和加入子节点的方法基本一致,只是在最后的实现方法上有着略微的区别。加入兄弟节点的具体步骤,首先也是要确定要加入的兄弟节点所处的位置,接着定义一个节点对象,最后调用TreeView类中对兄弟节点加入的方法,加入此节点对象。加入兄弟节点和加入子节点的最大区别就在于这最后一步。希望读者能够注意。下面是在TreeView组件加入一个兄弟节点的具体代码:

      
    //首先判断是否选定组件中节点的位置
    if ( treeView1.SelectedNode == null )
    {
    MessageBox.Show ( 
    "请选择一个节点" , "提示信息" , MessageBoxButtons.OK , MessageBoxIcon.Information ) ;
    }
    else
    {
    //创建一个节点对象,并初始化
    TreeNode tmp ;
    tmp 
    = new TreeNode ( textBox1.Text ) ;
    //在TreeView组件中加入兄弟节点
    treeView1.SelectedNode.Parent.Nodes.Add ( tmp ) ;
    treeView1.ExpandAll ( ) ;


      (
    3).删除节点:

      删除节点就是删除TreeView组件中选定的节点,删除节点可以是子节点,也可以是兄弟节点,但无论节点的性质如何,必须保证要删除的节点没有下一级节点,否则必须先删除此节点中的所有下一级节点,然后再删除此节点。删除节点比起上面的二个操作要显得略微简单,具体方法是:首先判断要删除的节点是否存在下一级节点,如果不存在,就调用TreeView类中的Remove ( )方法,就可以删除节点了。下面是删除TreeView组件中节点的具体代码:

      
    //判断选定的节点是否存在下一级节点
    if ( treeView1.SelectedNode.Nodes.Count == 0 )
    //删除节点
    treeView1.SelectedNode.Remove ( ) ;
    else
    MessageBox.Show ( 
    "请先删除此节点中的子节点!" , "提示信息" , MessageBoxButtons.OK , MessageBoxIcon.Information ) ; 

      (
    4).TreeView组件的一些其他常用操作:

      其他的一些常用操作比起上面的三种操作,在具体实现上要显得简单许多。这些常用操作无非是,展开所有节点,展开指定的节点、和折叠所有节点。下面就来具体介绍一下:

      
    < I > .展开所有节点:

      要展开TreeView组件中的所有节点,首先就要把选定的节点指针定位在TreeView组件的根节点上,然后调用选定组件的ExpandAll方法就可以了,下面是具体代码:

    //定位根节点
    treeView1.SelectedNode = treeView1.Nodes [ 0 ] ;
    //展开组件中的所有节点
    treeView1.SelectedNode.ExpandAll ( ) ;

      
    < II > .展开选定节点的下一级节点:

      由于只是展开下一级节点,所以就没有必要用ExpandAll ( )方法了。展开下一级节点只需要调用Expand ( )方法就可以了,下面是具体的实现代码:

    treeView1.SelectedNode.Expand ( ) ;

      
    < III > .折叠所有节点:

      折叠所有节点和展开所有节点是一组互操作,具体实现的思路也大致相同,折叠所有节点也是首先要把选定的节点指针定位在根节点上,然后调用选定组件的Collapse ( )就可以了,下面是具体的实现代码:

      
    //定位根节点
    treeView1.SelectedNode = treeView1.Nodes [ 0 ] ;
    //折叠组件中所有节点
    treeView1.SelectedNode.Collapse ( ) ; 

      至此已经把在C#操作TreeView组件的常用方法和一般方法基本都介绍完了。 
      三. C#编写的一个完整操作TreeView组件的例子:

      下面是C#编写一个的关于TreeView组件的例子,在这个例子中,结合以上介绍的常用方法和一般方法,基本覆盖来TreeView组件的一些最常用的操作。譬如可以灵活的程序中的TreeView组件中,进行加入子节点、兄弟节点、删除节点、折叠、展开等操作。其中前三种基本操作是通过程序中弹出菜单中的功能来实现的,后面操作是通过程序中的按钮来实现的。下面是此程序的代码节略(TreeView.cs):

      
    using System ;
    using System.Drawing ;
    using System.Collections ;
    using System.ComponentModel ;
    using System.Windows.Forms ;
    using System.Data ;
    namespace 全面掌握TreeView组件的使用方法
    {
    /// Form1 的摘要说明。
    public class Form1 : Form
    {
    private TreeView treeView1 ;
    private Button button1 ;
    private Button button2 ;
    private Button button3 ;
    private MenuItem menuItem2 ;
    private MenuItem menuItem3 ;
    private MenuItem menuItem4 ;
    private ContextMenu contextMenu1 ;
    private TextBox textBox1 ;
    private Label label1 ;
    /// 必需的设计器变量。
    private System.ComponentModel.Container components = null ;
    public Form1 ( )
    {
    //初始化窗体中的组件
    InitializeComponent ( ) ;
    }
    /// 清理所有正在使用的资源。
    protected override void Dispose ( bool disposing )
    {
    if ( disposing )
    {
    if ( components != null ) 
    {
    components.Dispose ( ) ;
    }
    }
    base.Dispose ( disposing ) ;
    }
    private void InitializeComponent ( )
    {
      
    //初始化代码(略) 
    }
    [ STAThread ]
    static void Main ( ) 
    {
    Application.Run ( 
    new Form1 ( ) ) ;
    }
    private void AddChildNode ( )
    {
    //首先判断是否选定组件中的位置
    if ( treeView1.SelectedNode == null )
    {
    MessageBox.Show ( 
    "请选择一个节点" , "提示信息" , MessageBoxButtons.OK , MessageBoxIcon.Information ) ;
    }
    else
    {
    if ( textBox1.Text != "" )
    {
    //创建一个节点对象,并初始化
    TreeNode tmp ;
    tmp 
    = new TreeNode ( textBox1.Text ) ;
    //在TreeView组件中加入子节点
    treeView1.SelectedNode.Nodes.Add ( tmp ) ;
    treeView1.SelectedNode 
    = tmp ;
    treeView1.ExpandAll ( ) ;
    }
    else
    {
    MessageBox.Show ( 
    "TextBox组件必须填入节点名称!" , "提示信息" , MessageBoxButtons.OK , MessageBoxIcon.Information ) ;
    return ;
    }
    }
    }
    private void AddParent ( )
    {
    //首先判断是否选定组件中节点的位置
    if ( treeView1.SelectedNode == null )
    {
    MessageBox.Show ( 
    "请选择一个节点" , "提示信息" , MessageBoxButtons.OK , MessageBoxIcon.Information ) ;
    }
    else
    {
    if ( textBox1.Text != "" )
    {
    //创建一个节点对象,并初始化
    TreeNode tmp ;
    tmp 
    = new TreeNode ( textBox1.Text ) ;
    //在TreeView组件中加入兄弟节点
    treeView1.SelectedNode.Parent.Nodes.Add ( tmp ) ;
    treeView1.ExpandAll ( ) ;
    }
    else
    {
    MessageBox.Show ( 
    "TextBox组件必须填入节点名称!" , "提示信息" , MessageBoxButtons.OK , MessageBoxIcon.Information ) ;
    return ;
    }
    }
    TreeNode tnode 
    = new TreeNode ( textBox1.Text ) ;
    }
    private void treeView1_MouseDown ( object sender , MouseEventArgs e )
    {
    if ( e.Button == MouseButtons.Right )
    contextMenu1.Show ( 
    this , new Point ( e.X , e.Y ) ) ;
    }
    private void button1_Click ( object sender , System.EventArgs e )
    {
    treeView1.SelectedNode.Expand ( ) ;
    }
    private void menuItem2_Click ( object sender , System.EventArgs e )
    {
    AddChildNode ( ) ;
    }
    private void menuItem3_Click ( object sender , System.EventArgs e )
    {
    AddParent ( ) ;
    }
    private void menuItem4_Click ( object sender , System.EventArgs e )
    {
    //判断选定的节点是否存在下一级节点
    if ( treeView1.SelectedNode.Nodes.Count == 0 )
    //删除节点
    treeView1.SelectedNode.Remove ( ) ;
    else
    MessageBox.Show ( 
    "请先删除此节点中的子节点!" , "提示信息" , MessageBoxButtons.OK , MessageBoxIcon.Information ) ;
    }
    private void button2_Click ( object sender , System.EventArgs e )
    {
    //定位根节点
    treeView1.SelectedNode = treeView1.Nodes [ 0 ] ;
    //展开组件中的所有节点
    treeView1.SelectedNode.ExpandAll ( ) ;
    }
    private void button3_Click ( object sender , System.EventArgs e )
    {
    //定位根节点
    treeView1.SelectedNode = treeView1.Nodes [ 0 ] ;
    //折叠组件中所有节点
    treeView1.SelectedNode.Collapse ( ) ;
    }
    }



      在成功编译TreeView.cs后,即可运行程序。

      四. 总结:

      TreeView组件是一个既令程序员头痛,又令程序员难以割舍的组件。这是因为TreeView组件使用非常灵活,显示内容有层次,并且
    "容量"相对又比较大。但同时在实际的编程比起其他组件又相对麻烦。掌握了本文介绍的这些用C#操作TreeView组件的基本方法后,我想对于在使用TreeView组件中的一般的问题,应该都能够克服了吧。 


    WinForm TreeView 上逐层加载数据2008
    -09-23 22:48TreeView 是一个很好的表达树形结构的控件。如果要加载的数据比较多的话,就需要逐层加载数据。要实现逐层加载数据,首先想到的就是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;
         }

  • 相关阅读:
    codevs 1115 开心的金明
    POJ 1125 Stockbroker Grapevine
    POJ 2421 constructing roads
    codevs 1390 回文平方数 USACO
    codevs 1131 统计单词数 2011年NOIP全国联赛普及组
    codevs 1313 质因数分解
    洛谷 绕钉子的长绳子
    洛谷 P1276 校门外的树(增强版)
    codevs 2627 村村通
    codevs 1191 数轴染色
  • 原文地址:https://www.cnblogs.com/wequst/p/1419649.html
Copyright © 2011-2022 走看看