天天看點

一個"簡單"的ASP.NET的伺服器控件

    在我主持過的一個Asp.Net論壇上,一個使用者詢問如何在一個頁面上去通過hyperlink列出一個路徑下的很多檔案名,能使使用者能點選它們。我認為這是可能是經常執行的動作,是以決定建立一個伺服器控件來封裝它。

    起初,我嘗試了Web使用者控件,但我想能允許設定邊框,字型,背景顔色等。使用Web使用者控件,我要為每一個屬性手動設定。俗話說:“你寫的代碼越少,你的錯誤越少了”,是以我要研究一個更好的方法。

    我決定建立自己首個自定義伺服器控件。我試着去繼承一個label控件,但label控件不支援滾動條。 是以,我選擇繼承Panel控件。最終的控件具有Panel控件的所有屬性(顔色,邊框,滾動支援等),再加上一些我添加自定義屬性。使用Panel控件将會盡最小的努力。

第一部分:自定義伺服器控件

初始化的伺服器控制相對容易。下面是最終的代碼:

代碼

 注意:

控件名字:

   去煩惱一個控件的名稱是非常愚蠢做法,真的是這樣嗎?錯誤的命名一個控件(或裡任何變量)就像結婚。由于你将要與它走很長一段時間,在将來改變它可能會非常痛苦。是以首先要用好你的命名。

    我稱這個控件為: HyperlinkFileList.

溢出問題:

    如果控件的高度一旦設定,檔案的清單超出了控件的高度。就會使檔案“溢出”控件的邊界。

    為了解決這個問題,我将下面代碼放到控件的構造函數之中:

  if ((Height != null) && (ScrollBars == ScrollBars.None))

      ScrollBars = ScrollBars.Auto;

CSS 布局:

    因為控件是基本是一個div(panel渲染成一個div),然後,設定"display"屬性為"inline-block",允許多個控件并排在一起。

    Style["display"] = "inline-block";

CSS框模型:

    我不喜歡文本卡在控件的左側,是以我添加一些CSS來填充。我也在控件的周圍使用一些css樣式。使它不會與其它控件貼的很死。

     // add spacing outside the control

    Style["margin"] = "0.5em";

    // add space inside the control 

    Style["padding-left"] = "0.5em"; 

狀态管理:

    在最初的測試的時候, 我發現每次控件都能運作,它都将重新讀取的檔案目錄。檔案輸入輸出代價是很昂貴的。我想去結合的伺服器控件的“State”。但它使用的是View State 類型,兩次發送檔案清單到用戶端是效率非常低的 。一次作為HTML清單,一次在ViewState 。

    是以我想使用 Session State, Application State 和Cache。

    我決定将檔案清單放在一個緩存對象之中。使清單能在session之間共享。如果記憶體在溢出,緩存中的清單将會丢失。

    我将檔案的目錄和檔案filter連接配接在一起,作為緩存中索引鍵。這樣允許多個控件同時使用和共享檔案清單。

    開始,我添加了使開發人員可以強制重新讀取需要的檔案的功能。但是,緩存對象可以使用依賴關系:任何從屬目錄更改會導緻緩存過期。最後的代碼是非常的簡單:

    側注:當然,這隻是一個代碼行,但做了幾個小時的研究,以決定這是最好的方法去處理狀态的管理的問題。有時需要很長的時間編寫很少的代碼。

Property Editor:

    我将所有的自定義屬性分組到标題 "Files List"下面。他們都在一個地方與Panel的屬性分離開來。

下面是四個控件在一個頁面上的标簽

下面是他們渲染之後的樣子:

第二部分:自定義伺服器控件編輯器

選擇檔案目錄:

   我認為粘貼檔案的目錄路徑是業餘開發人員使用的法子,是以我決定添加一個目錄浏覽器。  

  開發伺服器控件編輯器所用時間比開發實際控件用的時間更長。

   我認為控件的檔案的目錄,應在兩個方面可設定:

Absolute Path: C:\PublicData\ImageFiles\

Virtual Path: ~\xmlFiles\

    我試着設計兩個内置浏覽來設定FilesDirectory屬性。

[EditorAttribute(typeof(System.Web.UI.Design.UrlEditor), typeof(UITypeEditor))]

    我沒有使用UrlEditor,因為它不允許浏覽外部站點的主目錄。

[EditorAttribute(typeof(System.Windows.Forms.Design.FolderNameEditor), typeof(UITypeEditor))]

    我沒有使用FolderNameEditor,因為它沒有提供虛拟路徑的選擇。此外,它迫使使用者選擇一個我不想選擇檔案。

要建立自定義伺服器控件編輯器,就要建立一個類自UITypeEditor繼承和覆寫兩個功能...其中一個啟動一個DialogBox。

下面是代碼:

     以下是編輯的DialogBox,如下所示:

    我将不會顯示DialogBox代碼,因為這是它比較長,涉及廣。由于缺乏文檔,在開發過程中進行了反複的試錯。但也有一些利益的東西...

目錄分隔符(斜線):

    反斜杠像 "\~"這樣被使用的時候,GetProjectItemFromUrl 函數将不能正常使用。它正斜杠:"/~"能正常工作。是以,我確定所有的目錄分隔符使用正斜杠。但是,從目錄浏覽器傳回的目錄使用的是反斜杠。是以我們要確定一緻性...雖然它使代碼有點淩亂,但真的沒有我更喜歡其他選擇。

伺服器控件開發提示:

    一旦控件放置到頁面上,你能自動的更新bin檔案路徑下面的DLL,通過右擊右擊控件,選擇“Refresh”。我不得不删除從bin目錄下的控件,然後重新添加到網頁上,以擷取最新版本到該項目中。

調試編輯器:

    調試控件是非常容易的。調試控件的編輯器卻非常的難。因為它運作在Visual Studio中。我在不同的地方添加下面代碼:

System.Diagnostics.Debugger.Break();

當運作到斷點,你得到下面這個令人爽快的畫面:

點選 "Debug the program",将建立一個新的 Visual Studio 執行個體。你就能夠調試控件的編輯器了。原來的運作Visual Studio将鎖定的(至少在我這裡是這樣的),你不得不去終止。由于欠缺自定義伺服器控件編輯器的文檔,這是非常寶貴的去尋找和了解什麼被傳遞了,發生了什麼。

可能的改進:

•标題字型可設定(大小,顔色,背景顔色...)

•将名稱放在一個固定的div中,檔案清單在另一可調整大小或有scrollable的div中。

•添加一個布爾字段來選擇顯示在連結的檔案擴充名。

希望這篇文章能夠幫助你。

歡迎讨論,謝謝!

本文轉自麒麟部落格園部落格,原文連結:http://www.cnblogs.com/zhuqil/archive/2009/12/28/HyperlinkFileList.html,如需轉載請自行聯系原作者

繼續閱讀