贊助商連結

12月 10, 2006

自製標籤雲控制項 TagCloud Controls

| 原始連結

最近的小朋友似乎都很沉迷Web 2.0,只要某網站掛上Web2.0的logo並且加上大大的beta圖樣就會莫明奇妙的大紅大紫,也難怪大家都不捨得把那個beta拿掉,原因可能是:

「我們還有太多創意要加進系統裡,所以我們需要不斷的修改」。

嗯,是哦,真是個好理由,好吧,為了能跟的上潮流我決定用ASP.NET技術創造一個跟Web2.0能沾上一點邊的小玩意,那就是今天的主角TagCloud Controls(標籤雲)控制項。

Web2.0 強調與終端使用者的互動,絕大部份的網站內容都要求使用者提供,於是我們便不知不覺得變成網站的免費人工,其中TagCloud就是一種俱代表性的運用, 每個使用者發現有用的內容就為這個內容記上自己認為最適當的標籤,經過大量而客觀的標示之後,我們就可以看出某些議題似乎是被大多數人喜愛的, TagCloud就是用來顯示這方面資訊的最佳工具,del.icio.us 就是使用TagCloud最經典的模範網站之一。

關於TagCloud Controls
我並不打算在這裡深入紹介TagCloud Controls的撰寫方式,因為它簡單到可說是沒有技巧可言,我僅僅用了300行程式碼就完成TagCloud 控制項,如果你還是很好奇的話可以到文章的下方連結下載編譯後可直接使用的dll檔及程式原始碼,當然為了更接近我心目中的Web2.0,所以這個控制項 目前還是beta版,謝謝。

載入資料
TagCloud Controls 提供幾個方式載入標籤,其中 LoadData(string[] Tags); 方法可以接收簡單的字串陣列,並將所讀取到的每個字串當成標籤,當重覆的標籤在字串陣列中,TagCloud Controls就會自動計算出每種標籤的熱門程度,然後配合CSS以不同的樣式、大小顯示在頁面上,其它的還有 LoadData(DataTable table, string column); 及LoadData(DbDataReader reader, string column); 等方法提供從DataReader及DataTable載入標籤的方法。

設定屬性
接著我們需 要為TagCloud設定幾個必要的屬性,CssClass屬性用來定義整個控制項的CSS類別,TagLevelCssClass則是標籤連結的的 CSS類別,實際上TagCloud會將標籤分可七種不同的熱門程度,假設TagLevelCssClass= “TagLv” 則標籤連結會被Render成 TagLv_1, TagLv_2, TagLv_3, TagLv_4, TagLv_5, TagLv_6, TagLv_7等CSS類別,你可以觀查一下我包含在下方連結中TagCloudDemo網站的做法。

另一個很重要的屬性是 PathRule,這個屬性用來定義標籤連結的規則,
例如 PathRule=" ~/tags/{0}/Default.aspx" 時,控制項會把中間的{0}代入標籤名稱,於是在 "game"這個標籤的url則是 http://localhost/tags/game/Default.aspx,你可以依照網頁的架構去修改這個屬性,以便讓每個標籤能連結到正確的 網址,唯一要注意的是別忘了在這個屬性中要包含至少一個 "{0}" 才有意義。

樣式表
這個控制項被設計成配合一個CSS檔來顯示,下面是一個簡單的範例,你還是可以去修改成你想要的樣子。
.TagCloud
{
    border: solid 1px #cacaca;
    font-family: Arial;
    width:400px;
}

.TagCloud a
{
    text-decoration: none;
    margin:3px;
}

.TagCloud a:hover
{
    color: #ff6600;
}
.TagLv_1{font-size:8pt;}
.TagLv_2{font-size:10pt;}
.TagLv_3{font-size:12pt;}
.TagLv_4{font-size:14pt;}
.TagLv_5{font-size:16pt;}
.TagLv_6{font-size:18pt;}
.TagLv_7{font-size:20pt;}

完成以上所有的步驟後執行它你可以看到以個充滿Web2.0味道的漂亮的TagCloud。



我要再強調一次,因為它還只是個beta版,所以我相信還有許多可以改善的空間,例如把標籤熱門程度修改成可以任意設定成不同程級,或者讓相對太過冷門的標籤不顯示等等,不管有什麼特別的想法你都可以去修改原始碼達到想要的樣子。


下載TagCloud Controls

10月 29, 2006

.NET 2.0 的應用程式設定

| 原始連結

雖然我以為大家都應該知道這件事,但讓我感到意外的是好像還有很多人不知道.NET 2.0的Settings要怎麼用,所以接下來我要對.NET 2.0中的設定檔做一點說明。

還記得那個遙遠的年代,所有的應用程式都有一套自己保存設定的方法,它們可能會在自己的目錄下放一個設定檔,當程式啟動時就開始讀進所有的參數,並且依照相關的設定去執行任務,當時最通用的設定檔就是.INI格式的檔案,找找你硬碟裏的INI檔並且打開它,你會發現INI檔使用非常簡單的名稱/值的結構,它看起來像是這樣:

[Settings]
Value1 = abc
Value2 = 12345
Value3 = 2006-01-01
…..
………..

後來Windows被微軟創造出來後,在Windows的系統內有另一種保存設定的方法,那就是Register,Register屬於集中管理式的設定方法,當Register中的參數遭到恐怖份子不當的修改很可能會對作業系統造成嚴重的影響,而且很難去修正錯誤,不過以上都不是我今天要講的重點,我想要說的是XML格式的設定檔。

現在XML格式流行,人們發現以XML格式保存文件是一件非常酷的事,於是.NET便大量支援使用XML,就連設定檔也都以XML文件的形式保存,原本在.NET Framework中就有XmlDocument物件可以用來對XML文件做存取控制,到了.NET 2.0又加上了專門針對應用程式設定操作更好的方法。

首先在你的"專案"(Porject)上按右鍵並且點選"屬性"(Propertys)再點選"設定"(Settings)頁簽,如果這時後畫面提示你目前沒有設定檔,你可以按下中間的連結建立一個新的設定檔,一切順利的話你可以看到一個編輯畫面。


編輯你應用程式所需要設定參數然後存檔,這時後你可以發現在方案總管多了一個Settings.settings的檔案。


一切就緒剩下的問題是如何在程式中運用這些設定值,一步一步來其實很簡單,讀取設定值跟寫入設定值只需要短短幾行程式就可以做到。

讀取設定值:


寫入設定值:


你甚至還可以在設定檔的載入、存檔及修改中加入事件:

最後有幾點我要特別說明:

  1. 設定值的範圍有分Application及User兩種,Application是所有使用者共用的設定,而User是各別使用者帳號的設定。
  2. Application是唯讀的所以不能被修改。
  3. Application的設定檔會放在程序目錄下的"程式名稱.exe.config"
  4. User的設定檔會放在C:\Documents and Settings\使用者帳號\Local Settings\Application Data\專案名稱\版本\user.config
照著以上的方法做,你會發現善用.NET 2.0的Settings,操作應用程式設定檔再也不會是件苦差事。

9月 01, 2006

拿掉那些沒有用的空白

| 原始連結

你是否時常用瀏覽器欣賞自己寫出來的Web應用程式,並且暗中讚嘆自己是如此富有創造力,這些花花綠綠的網頁可不只是外表好看而已,它更帶給無數人們方便的新應用與驚奇,如果你看著自己的作品會有一點感動,非常好,你不只是一個會寫Code的程式工人,你跟本就是一個程式藝術家,不過我想談的不是如何讓網頁變的更漂亮這些太主觀的議題,今天就讓我們來看看漂亮網頁後面的原始碼。

打開你最滿意的網站並且檢視由程式執行過後的原始碼,通常會在左邊的部份挾帶大量的空白與Tab字元,而且在每行的右邊會跟著一個換行的符號,這會依照你編寫的習慣而有所不同。
 

這其實沒什麼大不了的,反正瀏覽器會自動略過它們然後顯示出正確的結果,但是這些沒有用處的泛空白字元依然存在不會憑空消失,於是就在每次的HTTP要求中一點一滴的消耗網路的頻寬,如果能去除掉這些泛空白字元我還可以把省下來的字元數多開幾個控制項的ViewState隱藏欄位,至少ViewState比沒有任何用處的空白好用多了。

我們現在正需要一個過濾器,在每次伺服器將網頁資料送出去之前把所有廢物殘渣清乾淨,寫一個繼承Stream的物件用來替換掉原來的資料流是個很好的主意,以下是一個簡單的範例。

真正的重點在於Write函式中的兩行
outputData = Regex.Replace(outputData, "[\r\n\t]", "", RegexOptions.IgnoreCase);
outputData = Regex.Replace(outputData, "  +", " ", RegexOptions.IgnoreCase);
第一行我把所有的換行字元及Tab字元全部清楚掉,第二行把連續的空白字串換成單一個空白,最後把清理過後的字串再轉換成Stream交給系後做後續的處理,然後我們還要在Global.asax中的Application_BeginRequest事件使用這個加強過的Stream。

大功告成了,再次打開網頁看看原始碼你會發現那些該死的空白與換行字元都消失了,全部變成一串長長的字串,如果你有注意看我示範中的圖片的話應該會發現原本的網頁有12,949個位元組,現在只有10,277個位元組,足足省了21.73%的容量,我都還沒動手去除掉網頁中的註解部份呢。
 

看了以上的成果展示是否想要馬上把它加到你的系統中呢?先別急我還是必需讓你了解天下沒有白吃的午餐,任何過度偏激的行為背後都會有一些後遺症。

第一,我範例只是很簡單的去除連續空白,所以還有會有少數零星的無用空白留下來,而且有些如<pre>或是<textarea> Tag中的連續空白應該被保留下來,所以正確的做法應該用更複雜的規則運算式公式去解析HTML。
第二,每次Request就會引發伺服器過慮網頁內容,這影響伺服器的效能,影響的成度取決於過慮的程式碼是否太過複雜,所以如果你的程式掃瞄整個頁面只為了找出兩個無用字元的話,我想還是算了吧。

所以當你執意要使用這項技巧,我想提醒你要多注意被過慮後的網頁內容是否會變的不正常,而且千萬不要使用太複雜的過慮算式,如果你的網站是用100M/100M光纖架設的話我甚至希望你放棄這個愚蠢的想法,因為跟本沒必要,最後願主保佑那些整日與網頁原始碼為伍的傢伙,讓他們遠離可怕又討人厭的空白。

8月 02, 2006

監看檔案的異動

| 原始連結

軟體的功能越來越強大也越來越方便,於是不知不覺中一些很神奇的事就會被視為理所當然,但是只要仔細的找一找你就會發現其實有很多的不可思異之處,假如你的電腦是安裝Windows的作業系統的話,應該對每天都會用到的檔案總管很熟悉吧,你可以照以下步驟做:先打開檔案總管並將目錄指向”桌面”,這個時後你會在右邊的清單中看到因為懶得整理而散亂在桌面上的所有檔案,現在直接在桌面上隨便選一個沒有用的檔案然後按F2更改檔名,這時後檔案總管發現你偷改檔名所以也再右邊的清單中自動更新檔名了,真是厲害…。

我知道很多人看到這裡大概正準備按”上一頁”離開了,這不過是件普通的不能在普通的事,但如果你正巧不是很忙的話還請稍等一下,我正開始要告訴你如何在程式中運用這平凡又好用的功能。

在.NET龐大的類別庫中有一個FileSystemWatcher物件,它擁有接收來自作業系統中對於檔案更動訊息的能力,為了讓你能快速的認識它我打算寫一個小小的程式示範如何監看檔案的異動。



這是一個視窗程式,我在程式中宣告了一個FileSystemWatcher物件,並關將Path屬性設定為 “d:\Temp”、Filter屬性設為”*.*”、這表示FileSystemWatcher會監看d:\Temp下的所有檔案另外我還將IncludeSubdirectories屬性設為true,這會讓FileSystemWatcher連同d:\Temp目錄下的子目錄也納入監看的範圍,fsw.Renamed += new RenamedEventHandler(fsw_Renamed);這行則是用來引發檔案更名事件,這樣一來FileSystemWatcher可能接收到Rename的通知,最後的 EnableRaisingEvents = true 就會開使在背景執行緒中進行檔案的監看。

現在只要d:\Temp 目錄下有任何檔案名稱被改變就會自動顯示於視窗中。

 
FileSystemWatcher除了Renamed事件外還有Create、Changed、Deleted三個事件,分別可以監看檔案的新增、更改及刪除,利用這幾個事件你可以發揮創意做出很多令人驚奇的效果,比如說資料檔被修改後自動重新讀取並顯示新的資料,程式甚至不需要重新啟動,當然也許人們會因為太習慣而遺忘它所帶來的便利,不過這真的是體貼使用者的良好設計。