分享一个简单的资源管理器程序,主要是演示下LINQ在C#开发中的运用

以前有人在论坛里面问过,如何实现一个类似资源管理器的界面,其实运用 System.IO 下的一组API,很容易查询文件系统的文件。虽然说容易,但是还是很多人希望能看到具体的代码。下面我对其中最关键的代码作一个演示,程序尽可能简单,以便大家关注于主要问题。

先看下效果图:



代码下载 http://download.csdn.net/detail/caozhy/4169965。

本程序中使用了LINQ语法,简洁性大家可以自己体会,由于LINQ的运用,程序甚至连一个循环语句都不需要。很多人有一种误解,说到LINQ,就是数据库访问,就是ORM框架,就是转化成SQL执行等等,其实这是对LINQ的误解,我想用这个例子程序说明,LINQ没有那么神秘,它就是C# 3时代的一种简单语法,它可以融入到程序的每个角落。大家可以放心大胆地使用LINQ简化开发,书写紧凑的代码。

说一下这个程序的主要意图:

首先看到的是Form_Load,它的作用是加载根节点和驱动器列表:
C# code
?
1
2
             treeView1.Nodes.Add( new  TreeNode( "Computer" , DriveInfo.GetDrives()
                 .Select(x =>  new  TreeNode(x.Name) { Tag = x }).ToArray()) { Tag =  "root"  });

你没有看错,一行就写完了。
如果不用LINQ,我们可以怎么写呢?
C# code
?
1
2
3
4
5
6
             var rootNode =  new  TreeNode( "Computer" ) { Tag =  "root"  };
             treeView1.Nodes.Add(rootNode);
             foreach  (var item  in  DriveInfo.GetDrives())
             {
                 rootNode.Nodes.Add( new  TreeNode(item.Name) { Tag = item });
             }

这段代码的作用和上面的LINQ写法作用是等效的。可是明显写的更复杂了。

使用LINQ写法,用到了Select操作符,这个操作才我们的程序中还会反复出现,所以简单介绍下。

很多人用过SQL,知道用select可以从表中选定某几列,在数学上,这个操作叫投影,通俗地说,就是对集合中的每一个元素做这样一种变换(什么变换由select子句决定),让每个元素成为另一种类型的元素,得到一个新的集合。

从数据中选择几列只是select操作的特例,在LINQ中,Select操作可以方便地将某个类型转换成另一个类型,在这里我们把查询出来的DriveInfo类型对象转换为Nodes.Add()方法理解的TreeNode类型。为此我们使用了一个Lambda表达式:
C# code
?
1
x =>  new  TreeNode(x.Name) { Tag = x }


它相当于你写了这么一个函数:
C# code
?
1
2
3
4
5
6
TreeNode ConvertDriveInfoToTreeNode(DriveInfo x)
{
     TreeNode tn =  new  TreeNode(x.Name);
     tn.Tag = x;
     return  tn;
}


这个函数由谁调用呢?由LINQ调用,而不是你,虽然它是你定义的。

你将函数作为参数传给LINQ,LINQ通过反过来调用你的函数实现这种转换,再提供给你转换后的集合。

之后看到的是treeView1_BeforeExpand事件,它的作用是在展开节点的时候加载下面每个子节点再下一层的节点,为什么要子节点再下一层呢?这样可以让那些包含再下一层元素的节点提前出现“+”号,在展开的时候可以看到。这种按需加载TreeNode的技术很常用,希望新手们熟练掌握。

然后我们看到的是另一个事件处理函数treeView1_AfterSelect,它的作用是在点了某个节点的时候在ListView里面加载这个文件夹下的文件夹和文件。按照Windows习惯,先显示文件夹再显示文件。而且分别对文件夹和文件排序。请问这个如何实现?

如果用LINQ同样简单,只需要使用OrderBy操作就可以了。



附代码如下:

C# code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.IO;
using  System.Linq;
using  System.Text;
using  System.Windows.Forms;
 
namespace  WindowsFormsApplication1
{
     public  partial  class  Form1 : Form
     {
         public  Form1()
         {
             InitializeComponent();
         }
 
         private  void  Form1_Load( object  sender, EventArgs e)
         {
             treeView1.Nodes.Add( new  TreeNode( "Computer" , DriveInfo.GetDrives()
                 .Select(x =>  new  TreeNode(x.Name) { Tag = x }).ToArray()) { Tag =  "root"  });
         }
 
         private  void  treeView1_BeforeExpand( object  sender, TreeViewCancelEventArgs e)
         {
             e.Node.Nodes.Cast<TreeNode>().ToList().ForEach(x =>
                 {
                     try
                     {
                         if  (x.Nodes.Count == 0)
                         {
                             TreeNode[] nodes =  new  TreeNode[] { };
                             if  (x.Tag.GetType() ==  typeof (DriveInfo))
                             {
                                 var item = x.Tag  as  DriveInfo;
                                 nodes = Directory.GetDirectories(item.Name)
                                     .Select(y =>  new  DirectoryInfo(y))
                                     .Select(y =>  new  TreeNode(y.Name) { Tag = y })
                                     .ToArray();
                             }
                             if  (x.Tag.GetType() ==  typeof (DirectoryInfo))
                             {
                                 var item = x.Tag  as  DirectoryInfo;
                                 nodes = Directory.GetDirectories(item.FullName)
                                     .Select(y =>  new  DirectoryInfo(y))
                                     .Select(y =>  new  TreeNode(y.Name) { Tag = y })
                                     .ToArray();
                             }
                             x.Nodes.AddRange(nodes);
                         }
                     }
                     catch  { }
                 });
         }
 
         private  void  treeView1_AfterSelect( object  sender, TreeViewEventArgs e)
         {
             if  (e.Node.Tag.GetType() ==  typeof ( string ) && e.Node.Text ==  "Computer" )
             {
                 listView1.Items.AddRange(DriveInfo.GetDrives()
                     .Select(x =>  new  ListViewItem( new  string [] { x.Name, x.DriveType.ToString(), x.DriveType == DriveType.Fixed ? (x.TotalSize / 1048576 / 1024).ToString() +  "GB"  ""  }))
                     .ToArray());
 
             }
             if  (e.Node.Tag.GetType() ==  typeof (DriveInfo))
             {
                 listView1.Items.Clear();
                 listView1.Items.AddRange(Directory.GetDirectories((e.Node.Tag  as  DriveInfo).Name)
                     .Select(x =>  new  DirectoryInfo(x)).OrderBy(x => x.Name)
                     .Select(x =>  new  ListViewItem( new  string [] { x.Name,  "Folder" "" , x.CreationTime.ToString()})).ToArray());
                 listView1.Items.AddRange(Directory.GetFiles((e.Node.Tag  as  DriveInfo).Name,  "*.*" , SearchOption.TopDirectoryOnly)
                     .Select(x =>  new  FileInfo(x)).OrderBy(x => x.Name)
                     .Select(x =>  new  ListViewItem( new  string [] { x.Name,  "File" , (x.Length / 1024).ToString() +  "KB" , x.CreationTime.ToString() })).ToArray());
             }
             if  (e.Node.Tag.GetType() ==  typeof (DirectoryInfo))
             {
                 listView1.Items.Clear();
                 listView1.Items.AddRange(Directory.GetDirectories((e.Node.Tag  as  DirectoryInfo).FullName)
                     .Select(x =>  new  DirectoryInfo(x)).OrderBy(x => x.Name)
                     .Select(x =>  new  ListViewItem( new  string [] { x.Name,  "Folder" "" , x.CreationTime.ToString() })).ToArray());
                 listView1.Items.AddRange(Directory.GetFiles((e.Node.Tag  as  DirectoryInfo).FullName,  "*.*" , SearchOption.TopDirectoryOnly)
                     .Select(x =>  new  FileInfo(x)).OrderBy(x => x.Name)
                     .Select(x =>  new  ListViewItem( new  string [] { x.Name,  "File" , (x.Length / 1024).ToString() +  "KB" , x.CreationTime.ToString() })).ToArray());
             }
         }
     }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值