最終實現的效果是一個目錄檔案查看器,:
其原理是,當使用者單擊一個目錄的時候,將這個目錄的路徑發送給伺服器端,伺服器端返回這個目錄中的檔案和目錄資訊。在伺服器端,定義一個如下的類來表示要傳遞的檔案資訊:
複製代碼 代碼如下:public class FileInformation
{
public string FullPath
{
get; set;
}
public string Name
{
get; set;
}
public string Info
{
get; set;
}
public bool IsFolder
{
get; set;
}
}
其中FullPath是檔案的完整路徑,用於擷取它的子檔案夾/檔案用,Name是檔案的名字,用於顯示,IsFolder是區分這條資料是一個檔案還是檔案夾,以便用不同的表徵圖來顯示,最後一個Info是一些附加資訊,在此例中沒有用到。根據一個路徑獲得目錄中的檔案資訊的C#代碼很簡單,順便就貼在這裡: 複製代碼 代碼如下:public class FileManager
{
public static List<FileInformation> GetFolderContent(string fullpath)
{
List<FileInformation> res = new List<FileInformation>();
DirectoryInfo info = new DirectoryInfo(fullpath);
if (info.Exists)
{
foreach (DirectoryInfo d in info.GetDirectories())
{
res.Add(new FileInformation
{
FullPath = d.FullName, Name = d.Name,IsFolder = true,
Info = "Any More Information goes here"
});
}
foreach (FileInfo f in info.GetFiles())
{
res.Add(new FileInformation
{
FullPath = f.FullName,Name = f.Name,IsFolder = false,
Info = "Any More Information goes here"
});
}
}
return res;
}
}
此例中採用JSON資料的格式來傳遞這些資訊。因此要將這些資料序列化。在.Net 3.5中,有現成的將實體類序列化成JSON資料的類,使用方法如下 複製代碼 代碼如下:public static string ToJson<T>(T obj)
{
DataContractJsonSerializer d = new DataContractJsonSerializer(typeof(T));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
d.WriteObject(ms, obj);
string strJSON = System.Text.Encoding.UTF8.GetString(ms.ToArray());
ms.Close();
return strJSON;
}
如果是.net 2.0,則可以尋找一些第三方的組件,自己寫一個也不麻煩。
至此,伺服器端的主要工作已經完成了。建立一個Genric Handler檔案,filelist.ashx,代碼如下,簡單的響應下請求,輸出資料即可: 複製代碼 代碼如下:public class FileList : IHttpHandler {
public void ProcessRequest (HttpContext context) {
string path = context.Request.QueryString["path"];
string data = JsonHelper.ToJson<List<FileInformation>>(FileManager.GetFolderContent(path));
context.Response.Write(data);
}
public bool IsReusable {
get {
return false;
}
}
}
下面考慮用戶端html代碼的編寫。最主要的就是兩個事件,也就是滑鼠點擊發送ajax請求,處理返回的json資料產生html代碼,滑鼠再次點擊將html代碼清空。在這裡,採用ul li來顯示這個treeview,在li中有一個不可見的span,裡麵包含了檔案完整的路徑,它將用作發起ajax請求的參數,但是對使用者是不可見的。
HTML代碼很簡單,就4行: 複製代碼 代碼如下:<body>
<ul>
</ul>
</body>
首先需要初始化一個根目錄,例如D:,代碼如下: 複製代碼 代碼如下:$(function() {
$('<li class="folder">D:\\<span class="fullpath">D:\\</span></li>').appendTo('ul');
$('li').hover(function() {
$(this).css('cursor', 'pointer');
},
function() { $(this).css('cursor', 'default'); });
$('li.folder').toggle(LoadFile, CloseFolder);
});
構造好一個li結點,添加到ul中去,然後設定下滑鼠動作的樣式,最後為其綁定事件處理常式,LoadFile和CloseFolder。 複製代碼 代碼如下:function LoadFile(event) {
if (this == event.target) {
var path = $(this).find('span').html();
var node = $('<ul>');
$(this).append(node);
$.getJSON('filelist.ashx', { path: path }, function(data) {
$.each(data, function() {
if (this.IsFolder) {
node.append($('<li>').addClass('folder').html(this.Name).append($('<span>').addClass('fullpath').html(this.FullPath)));
}
else {
node.append($('<li>').addClass('file').html(this.Name).append($('<span>').addClass('fullpath').html(this.FullPath)));
}
});
node.find('li.folder').toggle(LoadFile, CloseFolder);
});
}
}
首先要判斷event的target和this是否是同一個對象,以避免點擊子節點事件浮升的時候造成多次觸發。首先利用find和html函數獲得完整的路徑。構造好一個ul節點並把它添加到當前的li中。此時ul是空的,接下來發起ajax請求,獲得伺服器端的資料。對每條資料產生一個li,其中對於是否是目錄加以判斷,產生帶有不同class的li,再加到node中。最後,不要忘記為新增的節點也綁定事件處理常式。代碼還是比較簡單的,至於關閉目錄節點的代碼就更加簡單了, 複製代碼 代碼如下:function CloseFolder(event) {
if (this == event.target)
$(this).find('ul').remove();
}
至此此範例已經完成了。還少了幾句css,不再列出。
這個例子實現的功能和樣式都比較粗糙,不過在此基礎上做更多的擴充和美化已經不是難事。例如可以加上一點現成的動畫效果: 複製代碼 代碼如下:function CloseFolder(event) {
if (this == event.target) {
var node = $(this).find('ul');
node.hide('slow', function() { $(this).find('ul').remove(); });
}
}
先隱藏,再刪除。類似地,可以載入完畢後立刻隱藏,再淡出。