• [转]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;
         }

  • 相关阅读:
    「CF505E」 Mr. Kitayuta vs. Bamboos
    「CF1438D」 Powerful Ksenia
    Kruskal重构树
    20210528模拟赛总结
    20210527模拟赛总结
    20210526模拟赛总结
    20210525模拟赛总结
    CF #722 Div2题解
    洛谷P3652 csh和zzy的战争 题解
    [清华集训2012]模积和 题解
  • 原文地址:https://www.cnblogs.com/wequst/p/1419649.html
Copyright © 2020-2023  润新知