以前有人在論壇里面問(wèn)過(guò),,如何實(shí)現(xiàn)一個(gè)類(lèi)似資源管理器的界面,,其實(shí)運(yùn)用 System.IO 下的一組API,很容易查詢(xún)文件系統(tǒng)的文件,。雖然說(shuō)容易,,但是還是很多人希望能看到具體的代碼。下面我對(duì)其中最關(guān)鍵的代碼作一個(gè)演示,,程序盡可能簡(jiǎn)單,,以便大家關(guān)注于主要問(wèn)題。 先看下效果圖: 代碼下載 http://download.csdn.net/detail/caozhy/4169965,。 本程序中使用了LINQ語(yǔ)法,,簡(jiǎn)潔性大家可以自己體會(huì),由于LINQ的運(yùn)用,,程序甚至連一個(gè)循環(huán)語(yǔ)句都不需要,。很多人有一種誤解,說(shuō)到LINQ,,就是數(shù)據(jù)庫(kù)訪問(wèn),,就是ORM框架,就是轉(zhuǎn)化成SQL執(zhí)行等等,,其實(shí)這是對(duì)LINQ的誤解,,我想用這個(gè)例子程序說(shuō)明,LINQ沒(méi)有那么神秘,,它就是C# 3時(shí)代的一種簡(jiǎn)單語(yǔ)法,,它可以融入到程序的每個(gè)角落。大家可以放心大膽地使用LINQ簡(jiǎn)化開(kāi)發(fā),,書(shū)寫(xiě)緊湊的代碼,。 說(shuō)一下這個(gè)程序的主要意圖: 首先看到的是Form_Load,它的作用是加載根節(jié)點(diǎn)和驅(qū)動(dòng)器列表:
你沒(méi)有看錯(cuò),,一行就寫(xiě)完了,。 如果不用LINQ,我們可以怎么寫(xiě)呢,?
這段代碼的作用和上面的LINQ寫(xiě)法作用是等效的,。可是明顯寫(xiě)的更復(fù)雜了,。 使用LINQ寫(xiě)法,,用到了Select操作符,這個(gè)操作才我們的程序中還會(huì)反復(fù)出現(xiàn),,所以簡(jiǎn)單介紹下,。 很多人用過(guò)SQL,,知道用select可以從表中選定某幾列,在數(shù)學(xué)上,,這個(gè)操作叫投影,,通俗地說(shuō),就是對(duì)集合中的每一個(gè)元素做這樣一種變換(什么變換由select子句決定),,讓每個(gè)元素成為另一種類(lèi)型的元素,,得到一個(gè)新的集合。 從數(shù)據(jù)中選擇幾列只是select操作的特例,,在LINQ中,,Select操作可以方便地將某個(gè)類(lèi)型轉(zhuǎn)換成另一個(gè)類(lèi)型,在這里我們把查詢(xún)出來(lái)的DriveInfo類(lèi)型對(duì)象轉(zhuǎn)換為Nodes.Add()方法理解的TreeNode類(lèi)型,。為此我們使用了一個(gè)Lambda表達(dá)式:
它相當(dāng)于你寫(xiě)了這么一個(gè)函數(shù):
這個(gè)函數(shù)由誰(shuí)調(diào)用呢,?由LINQ調(diào)用,而不是你,,雖然它是你定義的,。 你將函數(shù)作為參數(shù)傳給LINQ,LINQ通過(guò)反過(guò)來(lái)調(diào)用你的函數(shù)實(shí)現(xiàn)這種轉(zhuǎn)換,,再提供給你轉(zhuǎn)換后的集合,。 之后看到的是treeView1_BeforeExpand事件,它的作用是在展開(kāi)節(jié)點(diǎn)的時(shí)候加載下面每個(gè)子節(jié)點(diǎn)再下一層的節(jié)點(diǎn),,為什么要子節(jié)點(diǎn)再下一層呢,?這樣可以讓那些包含再下一層元素的節(jié)點(diǎn)提前出現(xiàn)“+”號(hào),在展開(kāi)的時(shí)候可以看到,。這種按需加載TreeNode的技術(shù)很常用,,希望新手們熟練掌握。 然后我們看到的是另一個(gè)事件處理函數(shù)treeView1_AfterSelect,,它的作用是在點(diǎn)了某個(gè)節(jié)點(diǎn)的時(shí)候在ListView里面加載這個(gè)文件夾下的文件夾和文件,。按照Windows習(xí)慣,先顯示文件夾再顯示文件,。而且分別對(duì)文件夾和文件排序,。請(qǐng)問(wèn)這個(gè)如何實(shí)現(xiàn)? 如果用LINQ同樣簡(jiǎn)單,,只需要使用OrderBy操作就可以了,。 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()); } } } } |
|
來(lái)自: Cloud書(shū)屋 > 《Linq》