Dev TreeList + Dev GridControl 文件管理系统

1. 最近去公司实习,实习有一周的考核期,其中就给我布置了这个任务:做一个文件管理系统,类似于我的电脑,不过得用 DevExpress插件里面的。用 C# 写的。

首先 VS 新建 WinForm 项目,左边添加 Dev TreeList,右边添加 Dev GridControl,右边上面添加前进、后退按钮和一个textButton。

 

 

接下来直接上代码:

 

2.原先 GridControl 的数据源是 datatable,然后直接用

                DataTable dt = new DataTable();

                DataRow dr = dt.NewRow();
                dr["FileName"] = fi.Name;
                dr["DataTime"] = fi.LastWriteTime;
                dr["Getpath"] = s; 。

在后面用的是 this.gridControl1.DataSource = dt;

给 GridControl 初始化时直接用的:

            dt.Columns.Add("FileName", System.Type.GetType("System.String")); dt.Columns[0].Caption = "文件名称";
            dt.Columns.Add("FileSize", System.Type.GetType("System.String")); dt.Columns[1].Caption = "文件大小";
            dt.Columns.Add("DataType", System.Type.GetType("System.String")); dt.Columns[2].Caption = "文件类型";
            dt.Columns.Add("DataTime", System.Type.GetType("System.String")); dt.Columns[3].Caption = "修改时间";
            dt.Columns.Add("Getpath", System.Type.GetType("System.String")); dt.Columns[4].Caption = "文件路径";

但是,带我的老大说这写得不够面向对象,扩展性不好。后来苦思冥想,用  List<T> 来作GridControl 的数据源,然后封装成一个对象给GridControl 的列赋值这样就是面向对象了。

下面直接上代码。

一、先增加一个类 FormItem.cs,代码如下

 

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

namespace TreeTest
{
    public class FormItem
    {
        //文件名称
        public string FileName
        {
            get;
            set;
        }

        //文件大小
        public string FileSize
        {
            get;
            set;
        }

        //文件类型
        public string DataType
        {
            get;
            set;
        }

        //修改时间
        public string DataTime
        {
            get;
            set;
        }

        //文件路径
        public string Getpath
        {
            get;
            set;
        }
    }
}

 

二、在 Form1.cs 上写下如下代码,代码都有注释,应该有点基础的都能看懂。

 

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 DevExpress.XtraTreeList.Nodes;
using System.IO;
using DevExpress.XtraTreeList;
using System.Net.Mime;

namespace TreeTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
       // DataTable dt = new DataTable();
        bool _flag = false;
        bool _check = true;

        IList<FormItem> itemsList = new BindingList<FormItem>();
      
        //通过代码给TreeList添加列
        private void CreateColumns()
        {
            string[] captions = { "FullName","Name", "Type" };
            for (int i = 0; i < 3; i++)
            {
                treeList1.Columns.Add();   //增加一列
                treeList1.Columns[i].Caption = captions[i];    //设置每一列的标题
                treeList1.Columns[i].VisibleIndex = (i == 0 || i == 2) ? -1 : i;    // VisibleIndex为-1表示隐藏
                treeList1.Columns[i].OptionsColumn.AllowEdit = false;
            }
        }        

        //遍历磁盘
        private void InitDrives()
        {
            treeList1.BeginUnboundLoad();
            TreeListNode node;
            try
            {
                string[] root = Directory.GetLogicalDrives();   //获取计算机上格式为 "<drive letter>:\" 的逻辑驱动器的名称。例如C盘、D盘等

                foreach (string s in root)
                {
                    node = treeList1.AppendNode(new object[] { s, s, "Logical Driver" }, null);    //给treeList添加节点
                    node.HasChildren = true;
                    node.Tag = true;
                  
                }
            }
            catch { }
            treeList1.EndUnboundLoad();
        }

        //遍历指定路径下的文件---当不是最底层的文件夹时调用此方法,即此文件夹里面既有文件,又有文件夹。
        private void InitFolders(string path, TreeListNode pNode)
        {
            treeList1.BeginUnboundLoad();
            TreeListNode node;   
            DirectoryInfo di;
            FileInfo fi;
            try
            {
                string[] root = Directory.GetDirectories(path);    //返回指定目录中的子目录的名称(包括其路径)。
                foreach (string s in root)
                {
                    try{
                        fi = new FileInfo(s);         // FileInfo
                        di = new DirectoryInfo(s);
                        if (!pNode.Expanded && _flag)     //DirectoryInfo
                        {
                            node = treeList1.AppendNode(new object[] { s, di.Name,"Folder" }, pNode);
                            node.HasChildren = true;
                            node.Tag = true;
                        }

                        _check = true;
                        InitGridControl1(fi, s ,path);
                    }               
                    catch { }
                  }
                  this.gridControl1.DataSource = itemsList;
            } 
            catch { }
            InitFiles(path, pNode);            
            treeList1.EndUnboundLoad();
        }

        //遍历指定路径下的文件---当为最底层的文件夹时调用此方法,即此文件夹里面都是文件,没有文件夹。
        private void InitFiles(string path, TreeListNode pNode)
        {
            TreeListNode node;
            FileInfo fi;
            try
            {
                string[] root = Directory.GetFiles(path);      //GetFiles()获取当前目录下的所有文件
                foreach (string s in root)
                {

                    fi = new FileInfo(s);
                    if (!pNode.Expanded && _flag)
                    {
                        node = treeList1.AppendNode(new object[] { s, fi.Name, "File" }, pNode);
                        node.HasChildren = false;
                    }

                    _check = false;
                    InitGridControl1(fi, s,path);
                }
                this.gridControl1.DataSource = itemsList;
                this.gridView1.Columns["Getpath"].Visible = false;   //隐藏文件路径那一栏
            }
            catch { }
            
        }

        //右侧表格的初始化事件
        private void InitGridControl1(FileInfo fi,string s,string path)
        {
            FormItem Fi = new FormItem();
            Fi.FileName = fi.Name;
            Fi.DataTime = fi.LastWriteTime;
            Fi.Getpath = s;
            if (_check == false)   //当为文件时
            {    
                Fi.FileSize = System.Math.Ceiling(fi.Length / 1024.0).ToString() + " KB";
                Fi.DataType = fi.Extension;
            }
            else    //当为文件夹时
            {     
                Fi.DataType = "文件夹";
            }
            itemsList.Add(Fi);

            textBox1.Text = path;
            textBox1.Font = new Font(textBox1.Font.Name, 16);
        }

        //treeList1的点击事件
        private void treeList1_FocusedNodeChanged(object sender, DevExpress.XtraTreeList.FocusedNodeChangedEventArgs e)
        {
                itemsList.Clear();
               // dt.Clear();
                _flag = false;    //当点击某个结点时,不管treeList有没有展开,都不在tree上增加结点
                InitFolders(e.Node.GetDisplayText("FullName"), e.Node);    //这里有点问题,第二次点击treelist节点时,节点下又重新生成了子节点
                                      
        }

        //在扩展一个节点之前引发
        private void treeList1_BeforeExpand_1(object sender, BeforeExpandEventArgs e)
        {
            if (e.Node.Tag != null)
            {
                Cursor currentCursor = Cursor.Current;
                Cursor.Current = Cursors.WaitCursor;
                itemsList.Clear();
                // dt.Clear();
                _flag = true;
                InitFolders(e.Node.GetDisplayText("FullName"), e.Node);
                e.Node.Tag = null;
                Cursor.Current = currentCursor;
            }
        }     

                    
        private void Form1_Load(object sender, EventArgs e)
        {
            //给右侧列表添加列属性
            this.gridControl1.DataSource = itemsList;

            // this.gridView1.Columns["Getpath"].Visible = false;   //隐藏文件路径那一栏,不能在这里写,会发生未将对象引用到对象的实例
            CreateColumns();
            InitDrives();
            
        }

        //给文件夹和文件加图片
        private void treeList1_GetSelectImage(object sender, GetSelectImageEventArgs e)
        {
            if (e.Node.GetDisplayText("Type") == "Folder")
                e.NodeImageIndex = e.Node.Expanded ? 1 : 0;
            else if (e.Node.GetDisplayText("Type") == "File") e.NodeImageIndex = 2;
            else e.NodeImageIndex = 3;
        }

        //返回上一级目录
        private void button1_Click(object sender, EventArgs e)
        {
            string path = textBox1.Text;      //将当前目录保存到字符串path
            int i = path.LastIndexOf("\\");    //获取字符串最后一个斜杠的位置
            string strPath = path.Substring(0, i);   //取当前目录的字符串第一个字符到最后一个斜杠所在位置。 相当于上级目录
            if (i <= 2) { 
              strPath = path.Substring(0, i+1);
            }
          
            if (i >= 2) {
                itemsList.Clear();
                // dt.Clear();
                FileInfo fi;
                try
                {
                    string[] root = Directory.GetDirectories(strPath);    //返回指定目录中的子目录的名称(包括其路径)。
                    foreach (string s in root)
                    {
                        try
                        {
                            fi = new FileInfo(s);
                            _check = true;
                            InitGridControl1(fi, s, strPath);
                        }
                        catch { }
                    }
                    this.gridControl1.DataSource = itemsList;
                }
                catch
                {
                }
                textBox1.Text = strPath;
            }       
        }

        //前进一步事件
        private void button2_Click(object sender, EventArgs e)
        {
            object ojb = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, "Getpath");  //获取gridControl里面行中的某一列的值,获取文件夹
            string path = (string)ojb;
            MessageBox.Show(path);

        }

        //右键菜单
        private void gridView1_PopupMenuShowing(object sender, DevExpress.XtraGrid.Views.Grid.PopupMenuShowingEventArgs e)
        {
            //选择的行数
            int intselect = gridView1.SelectedRowsCount;
            MenuItemOpen.Enabled = false;
            MenuItemCopy.Enabled = false;
            MenuItemRename.Enabled = false;
            MenuItemDelete.Enabled = false;
            if (intselect == 1)
            {
                MenuItemOpen.Enabled = true;
                MenuItemCopy.Enabled = true;
                MenuItemRename.Enabled = true;
                MenuItemDelete.Enabled = true;
            }
           
        }

        //右键点击事件
        private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if ((e.ClickedItem).Name == "MenuItemOpen")
            {
                object ojb = gridView1.GetRowCellValue(gridView1.FocusedRowHandle, "Getpath");  //获取gridControl里面行中的某一列的值,获取文件夹
                string path = (string)ojb;    
                System.Diagnostics.Process.Start(path);     //打开此文件
                
            }
        }

        //右侧列表双击事件
        private void gridView1_DoubleClick(object sender, EventArgs e)
        {
            string strName = (string)gridView1.GetRowCellValue(gridView1.FocusedRowHandle, "DataType");  //读出文件类型是文件夹还是文件
            string path = (string)gridView1.GetRowCellValue(gridView1.FocusedRowHandle, "Getpath");     //读出文件夹的路径

            if (strName == "文件夹")
            {      //假如是文件夹
                itemsList.Clear();
                //dt.Clear();
                FileInfo fi;
                try
                {
                    string[] root = Directory.GetDirectories(path);    //返回指定目录中的子目录的名称(包括其路径)。
                    if (root.Length == 0)
                    {
                        root = Directory.GetFiles(path);
                        foreach (string s in root)
                        {
                            fi = new FileInfo(s);
                            _check = false;
                            InitGridControl1(fi, s, path);
                        }
                    }
                    else
                    {
                        foreach (string s in root)
                        {
                            try
                            {
                                fi = new FileInfo(s);
                                _check = true;
                                InitGridControl1(fi, s, path);
                            }
                            catch { }
                        }
                    }
                    this.gridControl1.DataSource = itemsList;
                }
                catch
                {
                }
                textBox1.Text = path;
            }
            else {
                System.Diagnostics.Process.Start(path);  //打开此文件
            }
        }

    }
}

 

 

三、原先写的不是面向对象的,特别是 InitGridControl1() 函数有很大的不同。以下是原先写的。可以对比上面我写的。

 

      //右侧表格的初始化事件--原先的
        private void InitGridControl1(FileInfo fi,string s,string path)
        {            
                DataRow dr = dt.NewRow();
                dr["FileName"] = fi.Name;
                dr["DataTime"] = fi.LastWriteTime;
                dr["Getpath"] = s;
                if (_check == false)   //当为文件时
                {
                    dr["FileSize"] = System.Math.Ceiling(fi.Length / 1024.0).ToString() + " KB";
                    dr["DataType"] = fi.Extension;
                }
                else {
                    dr["DataType"] = "文件夹";
                }
                dt.Rows.Add(dr);

                textBox1.Text = path;
                textBox1.Font = new Font(textBox1.Font.Name, 16);
        }

 

 

四,最后的结果图:


五、其中遇到的问题

(1)读取文件夹里面的文件时,有三种情况的,一种是文件夹里既有文件夹又有文件,一种是文件夹里面只有文件夹,一种是文件夹里面只有文件。前两种情况可以用方法InitFolders(string path, TreeListNode pNode)读取出来,后一种可用方法InitFiles(string path, TreeListNode pNode)读出。这个地方卡了好久,最后一步步的调试看出来的。

 

(2)怎么点击左侧 TreeList 的文件夹,在右侧 gridControl 里显示出文件夹里面的具体信息。这个卡壳了好久,得亏一个师兄帮忙才做出来[捂脸][捂脸]。

 

(3)隐藏 gridControl  的某一列方法,我原先在 Form1_Load(object sender, EventArgs e) 里面加的这一句:

         this.gridView1.Columns["Getpath"].Visible = false;         总报很恐怖的错误,后来在 InitFiles(string path, TreeListNode pNode) 方法里面加的这句,没有报错。

 

(4)List<T> 对象初始化时不能直接写成 List<FormItem> itemsList = new List<FormItem>();   而应该写成   IList<FormItem> itemsList = new BindingList<FormItem>();

    不然会报很大的错误。

六、未做出来的功能。右边最上头的 前进、后退功能,此功能比较难做,可能需要用到 队列、栈等将点击事件记录下来,然后前进或后退时再取出。比较难做,以后有时间了可能会再做。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值