ASP.NET自訂控制項開發樣本(一)

來源:互聯網
上載者:User

本文通過實現一個服務端控制項來講解一下控制項開發,該控制項的功能如下:
1.顯示服務端時間,並不停更新
2.通過手動點擊重新整理按鈕以AJAX擷取服務端最新時間
3.能拖動
4.能記住在頁面上的位置,頁面回傳後位置不變
5.能配置一個定時時間,一到這個時間,自動回傳觸發使用者自訂的事件

首先建立一個類庫項目HampWebControl,再建立一個類叫TipTime1,繼承WebControl類。如果不是從已有控制項中繼承,一般就繼承WebControl類,
它是所有ASP.NET服務端控制項的基類。

我們編譯這個項目,再建立一個網站項目,引用HampWebControl項目,建立頁面,在工具箱中拖一個TipTime1控制項到頁面上。

我們運行該頁面,就會發現HTML代碼如下:

就是說預設是呈現成一個span標籤,可以通過重載WebControl基類的TagKey屬性來改變。

這樣呈現在頁面上就是個DIV。 HtmlTextWriterTag是個枚舉,包含了很多HTML標籤。

WebControl基類的Render用來呈現內容,重載它便可以往頁面上呈現任何自訂的標籤。

這樣在頁面上就顯示了一個a標籤,如所示:

注意看,這時a標籤是在DIV外面,如何將它放到DIV裡面呢?這就要重載WebControl基類的RenderContents方法

這樣這個a標籤就在div裡面了,如所示:

接下來為最外圍的DIV加一些樣式,重載基類的AddAttributesToRender方法

這裡有兩種寫法,利用HtmlTextWriterStyle枚舉或者直接寫CSS屬性名稱。

到這裡大家瞭解了自訂控制項如何呈現在頁面上。我們再建立一個類TipTime2,把依舊重載TagKey為DIV,然後重載RenderContents,
顯示一個span標籤與一個input標籤。

 

 

這樣頁面上顯示了當前服務端的時間與一個按鈕,:   
接下來我們來讓使用者可以配置按鈕上的文字,為類TipTime2增加一個Text屬性:

同時將呈現按鈕的代碼改成:

這樣Text屬性便出現在設計檢視的屬性視窗。

修改Text的值,頁面上按鈕上的文本也跟著變了。注意Text屬性是儲存在ViewState中,這樣保證了回傳後值不會丟失。
現在的問題是時間不會變,我們得用javascript來改變它的值。建立一個JS檔案TipTime2.js。
這裡先要說明的是,項目中已有一個JS檔案__WebControlBase.js,裡面是一些公用的JS方法,比如綁定事件、擷取控制項座標等,所有的方法都是
該方法的擴充方法:var HampWebControl=function(){ }

    //停止事件冒泡
HampWebControl.prototype.StopBubble = function(e) {
if (e && e.stopPropagation) {
e.stopPropagation();
} else {
window.event.cancelBubble = true;
}
}

這樣可以減少全域變數,儘可能避免與其它js代碼的變數重名。我將每個控制項作為HampWebControl方法的一個擴充方法存在,同時每個控制項對
應一個數組,用以儲存頁面上所有該控制項的js對象。每個控制項對應一個Refresh方法,用以重新綁定事件,這是為瞭解決回傳後的問題。


現在控制項呈現成HTML的結構是<div><span/><input/></div>,有3個標籤,我們需要用3個變數來分別儲存它們的DOM對象,方便以後操作。

後台對HTML標籤命名時以當前控制項的ClientID開頭,後面根據需要加尾碼,這樣可以一定程度上防止標籤重名。由後台將控制項的ClientID傳過來,
這樣便可以擷取所有DOM對象。拖動效果利用的是現成js方法,屬於純javascript效果,這裡就不展開討論了,有興趣的童鞋可以查看樣本項目源碼。

該方法是由後台註冊指令碼來調用的,如果在數組中已存在就取該對象,否則重新new一個。並調用初始化與綁定事件方法。
這時需要在後台註冊該js檔案才行。關鍵的操作時將該檔案的“產生操作”屬性設定為“內嵌資源”,使得編譯的時候該js檔案會作為DLL檔案的一部分。

接下來需要聲明所需的資源檔,嚴格按檔案夾的結構來命名。這裡註冊了2個JS檔案:公用JS檔案__WebControlBase.js與控制項專用的JS檔案TipTime2.js。

然後在代碼中註冊指令碼即可。

在《道不遠人 深入解析ASP.NET2.0控制項開發》這本書中,註冊指令檔的代碼是放在OnPreRender方法中,但是實際應用中我發現,如果將自訂
控制項放在UpdatePanel控制項中,就會引發一些問題,所以我都放在OnLoad方法中去註冊指令檔。
注意註冊指令檔這裡用了2種不同的方法。
第1種是迴圈Head標籤裡面是否存在了指令碼,如果不存在,就插入一個<script>標籤。
第2種直接調用.NET的註冊方法。

        /// <summary>
/// 向頁面註冊公用jacascript檔案
/// </summary>
/// <param name="control">控制項對象</param>
internal static void RegisterCommonJSFile(Control control)
{
//註冊jacascript檔案
String jslink = "<script src='" +
control.Page.ClientScript.GetWebResourceUrl(control.GetType(),
"HampWebControl.includes.__WebControlBase.js")
+ "' type='text/javascript' ></script>";
Register(jslink,control);
}

/// <summary>
/// 註冊資源
/// </summary>
/// <param name="strLink">資源字串</param>
private static void Register(string strLink, Control control)
{
//為了保證資源只註冊一次,迴圈比較,已存在了就不添加
Boolean flag = false;
for (Int32 i = 0; i < control.Page.Header.Controls.Count; i++)
{
LiteralControl lc = control.Page.Header.Controls[i] as LiteralControl;
if (lc != null)
{
if (lc.Text == strLink)
{
flag = true;
break;
}
}
}
if (!flag)
{
LiteralControl include = new LiteralControl(strLink);
control.Page.Header.Controls.Add(include);
}
}

第1種是用於註冊公用的資源檔,第2種用於註冊該控制項特有的資源檔。 因為第2種方法只能保證多個該控制項對象只註冊一個指令碼,但不能保證其它控制項也
重複註冊了該指令碼,所以為了保證公用的資源檔只註冊一次,就用第1種方式。
下一步就是註冊要執行的指令碼代碼:

這裡如果控制項是隱藏的,就不註冊。其實如果控制項時放在其它容器控制項中,比如Panel,而父容器控制項設定為隱藏,那麼該控制項也不可見,但是依舊執行了註冊上面的指令碼的
代碼,所以要在前台Init方法中去判斷相應的DOM對象是否存在,這裡就沒有多做判斷。
最後設定一下樣式,使之變為浮動,則控制項在頁面上便能拖動了。

先講到這裡,歸納一下,主要講了如何呈現自訂控制項,如何添加屬性,如何增加資源檔。下一講介紹如何調用AJAX與實現自訂事件。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.