(C#)TreeView控件综合实例

利用TreeView控件,建立一颗树。程序带有保存文本和二进制的功能。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.Serialization.Formatters.Binary;

// 知识点:
//   TreeView控件的应用:添加、修改、删除节点
//   得到当前节点、父节点的值
//   响应节点选择事件
//   节点存储数据
namespace Ch0602_学生成绩_二进制文件_
{
    public partial class FrmGrade : Form
    {
        public FrmGrade()
        {
            InitializeComponent();
        }

        private void btnAddSC_Click(object sender, EventArgs e)
        {
            if (cboType.SelectedIndex == 0)
            {
                // 添加学校节点,并指定该节点为当前节点
                if (txtNameSC.Text.Length > 0)
                {
                    TreeNode node = tvSC.Nodes.Add(txtNameSC.Text);
                    tvSC.SelectedNode = node;
                }
                else
                    MessageBox.Show("请指定学校的名称");
            }
            else
            {
                if (tvSC.SelectedNode == null || tvSC.SelectedNode.Level >= 1)
                    MessageBox.Show("先选择学校,然后再创建班级节点");
                else
                {
                    // 添加班级节点,并展开学校节点
                    if (txtNameSC.Text.Length > 0)
                    {
                        tvSC.SelectedNode.Nodes.Add(txtNameSC.Text);
                        tvSC.SelectedNode.Expand();
                    }
                    else
                        MessageBox.Show("请指定班级的名称");
                }
            }
        }

        private void btnAddStud_Click(object sender, EventArgs e)
        {
            if (tvSC.SelectedNode == null || tvSC.SelectedNode.Level != 1)
            {
                MessageBox.Show("请指定班级");
                return;
            }

            string sname = tvSC.SelectedNode.Parent.Text;
            string cname = tvSC.SelectedNode.Text;
            Student stud = new Student(sname, cname);
            stud.No = txtNo.Text;
            stud.Name = txtName.Text;
            stud.Sex = cboSex.Text;
            stud.Birth = DateTime.Parse(dtpBirth.Text);
            stud.Grade = int.Parse(txtGrade.Text);
            stud.Addr = txtAddr.Text;

            TreeNode node = tvSC.SelectedNode.Nodes.Add(stud.No);
            // 给添加的节点绑定数据
            node.Tag = stud;
            // 展开班级节点
            tvSC.SelectedNode.Expand();
        }

        private void tvSC_AfterSelect(object sender, TreeViewEventArgs e)
        {
            // 显示当前节点内容
            if (tvSC.SelectedNode != null && tvSC.SelectedNode.Level == 2 && tvSC.SelectedNode.Tag != null)
            {
                Student stud = (Student)tvSC.SelectedNode.Tag;
                lboStudent.Items.Add(stud.ToString());

                txtNo.Text = stud.No;
                txtName.Text = stud.Name;
                cboSex.Text = stud.Sex;
                dtpBirth.Text = stud.Birth.ToString();
                txtGrade.Text = stud.Grade.ToString();
                txtAddr.Text = stud.Addr;
            }
        }

        private void tvSC_AfterSelect(object sender, TreeViewEventArgs e)
        {
            // 显示当前节点内容
            if (tvSC.SelectedNode != null && tvSC.SelectedNode.Level == 2 && tvSC.SelectedNode.Tag != null)
            {
                Student stud = (Student)tvSC.SelectedNode.Tag;
                lboStudent.Items.Add(stud.ToString());


                txtNo.Text = stud.No;
                txtName.Text = stud.Name;
                cboSex.Text = stud.Sex;
                dtpBirth.Text = stud.Birth.ToString();
                txtGrade.Text = stud.Grade.ToString();
                txtAddr.Text = stud.Addr;
            }
        }


        private void cboType_SelectedIndexChanged(object sender, EventArgs e)
        {
            txtNameSC.Clear();
        }


        private void btnModStud_Click(object sender, EventArgs e)
        {
            if (tvSC.SelectedNode == null || tvSC.SelectedNode.Level != 2)
            {
                MessageBox.Show("请指定学生");
                return;
            }


            string sname = tvSC.SelectedNode.Parent.Parent.Text;
            string cname = tvSC.SelectedNode.Parent.Text;
            Student stud = new Student(sname, cname);
            stud.No = txtNo.Text;
            stud.Name = txtName.Text;
            stud.Sex = cboSex.Text;
            stud.Birth = DateTime.Parse(dtpBirth.Text);
            stud.Grade = int.Parse(txtGrade.Text);
            stud.Addr = txtAddr.Text;


            // 修改节点信息
            tvSC.SelectedNode.Text = stud.No;
            // 修改节点的绑定数据
            tvSC.SelectedNode.Tag = stud;
        }


        private void btnDelStud_Click(object sender, EventArgs e)
        {
            // 删除节点数据
            tvSC.SelectedNode.Remove();
        }
        
        // 读文本文件,生成树结构
        private void miFileRead_Click(object sender, EventArgs e)
        {
            // 显示打开文件对话框
            OpenFileDialog dlgOpen = new OpenFileDialog();
            if (dlgOpen.ShowDialog() != DialogResult.OK)
                return;


            // 以指定文件和编码格式打开文件,准备读
            StreamReader sr = new StreamReader(dlgOpen.FileName, Encoding.Default);


            tvSC.Nodes.Clear();
            string pattern = @"\s*,\s*|\s+";    // “\s”表示空格,“\s*”表示0个或多个空格,“\s+”表示1个或多个空格
            string sname0 = "", cname0 = "";
            // 读取一行文本
            string line;
            string[] fields;
            while ((line = sr.ReadLine()) != null)
            {
                //fields = line.Split(' ', '\t');
                fields = Regex.Split(line, pattern);


                string sname = fields[0];
                string cname = fields[1];
                Student stud = new Student(sname, cname);
                stud.No = fields[2];
                stud.Name = fields[3];
                stud.Sex = fields[4];
                stud.Birth = Convert.ToDateTime(fields[5]);
                stud.Grade = int.Parse(fields[6]);
                stud.Addr = fields[7];


                // 如果学校名改变了,添加学校节点
                if (sname != sname0)
                {
                    tvSC.SelectedNode = tvSC.Nodes.Add(sname);
                    sname0 = sname;
                }


                // 如果班级名改变了,添加班级节点
                if (cname != cname0)
                {
                    // 调整当前节点
                    if (tvSC.SelectedNode.Level == 1)
                        tvSC.SelectedNode = tvSC.SelectedNode.Parent;


                    tvSC.SelectedNode = tvSC.SelectedNode.Nodes.Add(cname);
                    cname0 = cname;
                }


                // 添加学生节点
                TreeNode node = tvSC.SelectedNode.Nodes.Add(stud.No);
                node.Tag = stud;
            }


            // 关闭文件
            sr.Close();
        }


        // 遍历树结构,写文本文件
        private void miFileWrite_Click(object sender, EventArgs e)
        {
            // 显示保存文件对话框
            SaveFileDialog dlgSave = new SaveFileDialog();
            if (dlgSave.ShowDialog() != DialogResult.OK)
                return;


            // 指定文件和编码格式打开指定文件准备写
            StreamWriter sw = new StreamWriter(dlgSave.FileName, false, Encoding.Default);


            // 遍历树结构,写文本文件
            WriteTxtFile(sw, tvSC.Nodes);


            // 关闭文件
            sw.Close();


        }


        // 用递归遍历一棵树所有节点
        private void WriteTxtFile(StreamWriter sw, TreeNodeCollection nodes)
        {
            foreach (TreeNode node in nodes)
            {
                if (node.Level == 2)
                {
                    Student stud = node.Tag as Student;
                    string line = string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5:yyyy-MM-dd}\t{6}\t{7}",
                        stud.Sname, stud.Cname, stud.No, stud.Name, stud.Sex, stud.Birth, stud.Grade, stud.Addr);
                    sw.WriteLine(line);
                }


                if (node.Nodes.Count > 0)
                    WriteTxtFile(sw, node.Nodes);
            }
        }


        private void miFileReadBin_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlgOpen = new OpenFileDialog();
            if (dlgOpen.ShowDialog() != DialogResult.OK)
                return;


            FileStream fs = new FileStream(dlgOpen.FileName, FileMode.Open, FileAccess.Read);


            tvSC.Nodes.Clear();
            // 建立一个读流的类br
            BinaryReader br = new BinaryReader(fs);
            // 初始化变量
            string sname0 = "", cname0 = "";
            // 文件指针指向文件头
            br.BaseStream.Seek(0, SeekOrigin.Begin);
            // 循环读,直到文件指针指向文件尾
            while (br.BaseStream.Position < br.BaseStream.Length)
            {
                // 按字段读出每个学生的记录
                Student stud = new Student();
                stud.Sname = br.ReadString();
                stud.Cname = br.ReadString();
                stud.No = br.ReadString();
                stud.Name = br.ReadString();
                stud.Sex = br.ReadString();
                stud.Birth = Convert.ToDateTime(br.ReadString());
                stud.Grade = br.ReadInt32();
                stud.Addr = br.ReadString();


                // 添加到树形节点
                // 如果学校名改变了,添加学校节点
                if (stud.Sname != sname0)
                {
                    tvSC.SelectedNode = tvSC.Nodes.Add(stud.Sname);
                    sname0 = stud.Sname;
                }


                // 如果班级名改变了,添加班级节点
                if (stud.Cname != cname0)
                {
                    // 调整当前节点
                    if (tvSC.SelectedNode.Level == 1)
                        tvSC.SelectedNode = tvSC.SelectedNode.Parent;


                    tvSC.SelectedNode = tvSC.SelectedNode.Nodes.Add(stud.Cname);
                    cname0 = stud.Cname;
                }


                // 添加学生节点
                TreeNode node = tvSC.SelectedNode.Nodes.Add(stud.No);
                node.Tag = stud;


            }


            br.Close();
            fs.Close();
        }


        private void miFileWriteBin_Click(object sender, EventArgs e)
        {
            // 显示保存文件对话框
            SaveFileDialog dlgSave = new SaveFileDialog();
            if (dlgSave.ShowDialog() != DialogResult.OK)
                return;


            // 建立一个写文件流fs
            FileStream fs = new FileStream(dlgSave.FileName, FileMode.Create, FileAccess.Write);
            // 建立一个写流的类bw
            BinaryWriter bw = new BinaryWriter(fs);
            
            // 遍历树结构,写文本文件
            WriteBinFile(bw, tvSC.Nodes);


            // 关闭写流类和文件流
            bw.Close();
            fs.Close();
        }


        // 用递归遍历一棵树所有节点
        private void WriteBinFile(BinaryWriter bw, TreeNodeCollection nodes)
        {
            foreach (TreeNode node in nodes)
            {
                if (node.Level == 2)
                {
                    Student stud = node.Tag as Student;


                    bw.Write(stud.Sname);
                    bw.Write(stud.Cname);
                    bw.Write(stud.No);
                    bw.Write(stud.Name);
                    bw.Write(stud.Sex);
                    bw.Write(stud.Birth.ToString("yyyy-MM-dd"));
                    bw.Write(stud.Grade);
                    bw.Write(stud.Addr);
                }


                if (node.Nodes.Count > 0)
                    WriteBinFile(bw, node.Nodes);
            }
        }


        private void miFileReadBin2_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlgOpen = new OpenFileDialog();
            if (dlgOpen.ShowDialog() != DialogResult.OK)
                return;


            FileStream fs = new FileStream(dlgOpen.FileName, FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs);


            tvSC.Nodes.Clear();
            // 初始化变量
            string sname0 = "", cname0 = "";
            // 文件指针指向文件头
            fs.Seek(0, SeekOrigin.Begin);
            // 循环读,直到文件指针指向文件尾
            while (fs.Position < fs.Length)
            {
                // 按字段读出每个学生的记录
                int length = br.ReadInt32();
                byte[] buffer = new byte[length];
                buffer = br.ReadBytes(length);
                Student stud = (Student)BytesToObject(buffer);


                // 添加到树形节点
                // 如果学校名改变了,添加学校节点
                if (stud.Sname != sname0)
                {
                    tvSC.SelectedNode = tvSC.Nodes.Add(stud.Sname);
                    sname0 = stud.Sname;
                }


                // 如果班级名改变了,添加班级节点
                if (stud.Cname != cname0)
                {
                    // 调整当前节点
                    if (tvSC.SelectedNode.Level == 1)
                        tvSC.SelectedNode = tvSC.SelectedNode.Parent;


                    tvSC.SelectedNode = tvSC.SelectedNode.Nodes.Add(stud.Cname);
                    cname0 = stud.Cname;
                }


                // 添加学生节点
                TreeNode node = tvSC.SelectedNode.Nodes.Add(stud.No);
                node.Tag = stud;


            }


            br.Close();
            fs.Close();


        }


        private void miFileWriteBin2_Click(object sender, EventArgs e)
        {
            // 显示保存文件对话框
            SaveFileDialog dlgSave = new SaveFileDialog();
            if (dlgSave.ShowDialog() != DialogResult.OK)
                return;


            // 建立一个写文件流fs
            FileStream fs = new FileStream(dlgSave.FileName, FileMode.Create, FileAccess.Write);
            BinaryWriter bw = new BinaryWriter(fs);


            // 遍历树结构,写文本文件
            WriteBinFile2(bw, tvSC.Nodes);


            // 关闭写流类和文件流
            bw.Close();
            fs.Close();
        }


        private void WriteBinFile2(BinaryWriter bw, TreeNodeCollection nodes)
        {
            foreach (TreeNode node in nodes)
            {
                if (node.Level == 2)
                {
                    Student stud = node.Tag as Student;


                    byte[] buffer = ObjectToBytes(stud);
                    bw.Write(buffer.Length);
                    bw.Write(buffer);
                }


                if (node.Nodes.Count > 0)
                    WriteBinFile2(bw, node.Nodes);
            }
        }


        // 对象序列化为字节数组
        public static byte[] ObjectToBytes(Object obj)
        {
            MemoryStream ms = new MemoryStream();
            byte[] bytes = null;
            try
            {
                // 序列化
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(ms, obj);
                bytes = ms.ToArray();
            }
            catch (Exception e)
            {
                throw new Exception(e.ToString());
            }
            finally
            {
                ms.Close();
            }
            return bytes;
        }


        // 字节数组反序列化为对象
        public static Object BytesToObject(byte[] bytes)
        {
            MemoryStream ms = new MemoryStream(bytes);
            Object obj = new Object();
            try
            {
                // 反序列化
                ms.Position = 0;
                BinaryFormatter formatter = new BinaryFormatter();
                obj = formatter.Deserialize(ms);
            }
            catch (Exception e)
            {
                throw new Exception(e.ToString());
            }
            finally
            {
                ms.Close();
            }
            return obj;
        }


        private void miClear_Click(object sender, EventArgs e)
        {
            tvSC.Nodes.Clear();
        }
    }
}

下面是类的定义。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Ch0602_学生成绩_二进制文件_
{
    [Serializable]
    public class Student
    {
        public string Sname { get; set; }
        public string Cname { get; set; }
        public string No { get; set; }
        public string Name { get; set; }
        public string Sex { get; set; }
        public DateTime Birth { get; set; }
        public int Grade { get; set; }
        public string Addr { get; set; }


        public Student()
        {
        }

        public Student(string sname, string cname)
        {
            Sname = sname;
            Cname = cname;
        }

        public new string ToString()
        {
            return string.Format("{0}:{1},{2},{3:yyyy-MM-dd},{4},{5}", No, Name, Sex, Birth, Grade, Addr);
        }
    }

}



原文地址:https://www.cnblogs.com/finlay/p/3234757.html