天天看點

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

Hello,朋友們,新年快樂.很長時間沒寫部落格了,一直在想寫這一篇,可沒想好怎麼寫,就一直放着.現在終于有時間了,那麼來繼續我們的話題吧.自定義控件.如果你還不熟悉自定義控件開發的話,還請看看我以前寫了幾篇,希望對你有幫助

1.1何處繼承

自定義控件一般從以下幾個基類(此處不包含資料控件)

一.Control類(所有伺服器控件的基類,算是比較底層的類,如果控件功能比較簡單,要求不多,可直接繼承此類.)

二.WebControl類(标準控件的基類,繼承此類,你可以繼承其豐富的公共屬性,若标準控件中的控件沒有你需要的控件,你可以繼承此類)

三.CompositeControl 類(2.0新增的類,此類繼承自WebControl類,如果你需要制作複合控件,請從繼承此類開始)

四.直接從内置控件繼承(我們知道輪子隻需要發明一遍,你的需求跟内置差不多的話,請考慮這麼做)

1.2呈現控件

Control類Render方法為基本呈現方法,RenderContent方法是在Render方法之上的,其為控件加了一個标簽,我認為RenderContent方法是為WebControl類中屬性準備的.基本的方法繼續深刻的去了解.

1.3與使用者互動

純粹的呈現控件還不夠,我們需要傳遞資料,這就必然讓我們了解自定義控件事件處理

1.4接觸屬性(見第五,九,十篇)

屬性相對而言比較簡單,也比較好了解,但其又比較麻煩.

當控件屬性太多,很容易亂,是以我們又認識了中繼資料,

把屬性進行了分類,如下圖  

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

為了更清晰了,把屬性分好類别,我們又用另外做法,把多種同類型的屬性,定義在一個大的屬性裡面,稱之為複雜屬性,如下圖

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

屬性已經夠多了,不緊如此,我們還知道屬性的每種類型可能不一樣,而在呈現之後都是呈現字元串形式,簡單屬性.net已為你處理好轉換,當你自定義複雜屬性以後,你則需要自己為你定義的複雜屬性定義一個類型轉換器(見第九篇)

屬性還有另外一種做法,就是可以把屬性當成集合屬性來用.可以說是特殊話的複雜控件,這樣做可以提供給一些清單控件使用(見第10篇) 屬性用途還真不少

1.5控件樣式

控件怎麼能缺樣式,我們自然需要它,在此我們再次認識到了WebControl類.當然也了解到了Style類及其子類

,隻要你了解了其中的幾個方法你就可以自定義控件樣式了

1.6複合控件

複合控件的功能往往比較強大,它利用目前已經存在的控件進行組裝成一個新的控件,在此過程中我們學習了在複合控件中定義事件以及定義樣式.

1.7視圖狀态

不得不談的一個話題

一般我們為控件定義的屬性都以視圖狀态的形式儲存,然而複雜屬性的定義和控件樣式定義則需要你了解如何自定義視圖狀态

最後我們還讨論了如何為控件添加用戶端功能,還有為控件定義生成器.

好了,總結終于告一段落,以上寫了兩遍,第一遍寫的時候儲存後資料居然丢失了,痛苦啊.

下面我們分享一些小技巧,或許大家早已經知道了,為了以後更好的學習,我把命名控件全部更改為AspDemo.CustomComponents

此次下載下傳的源碼包括1-16篇的全部的示例代碼,如果有什麼錯誤還請大家指出

補充

一.嵌入資源的使用

1.嵌入控件圖示

内置控件都有自己的圖示,很多人也很喜歡為自己的控件做個圖示,那如何做呢?

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

我們隻需要使用ToolboxBitmap中繼資料就可以了,你需要了解其構造函數,用法如下

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

namespace  AspDemo.CustomComponents

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

        [ToolboxBitmap(typeof(ImageControl), "Resources.Image.bmp")]

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

   public class ImageControl : WebControl

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

    }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

}

注意點:

(1)圖示的位置位于,以你預設命名空間為根目錄,以點文法的方式來指定圖示位置,(即圖示路徑為/Resources)

否則的話以你控件類型命名控件為根目錄,(即圖示路徑為CustomComponents/Resources),大家可以嘗試一下

(2)在屬性面闆指明圖示檔案為嵌入的資源,如下圖

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

2.嵌入其他資源檔案

記得以前我們做了一個控件需要一個js檔案,當需要使用這個控件的話,則也需要使用js檔案,這樣給别人用的話很不方面,我們可以把js檔案作為嵌入資源使用來解決這一問題.以下例子來自MSDN,這裡隻是讓大家知道如何使用

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

[assembly: WebResource( " AspDemo.CustomComponents.Resources.AspDemo.CustomComponents.ResourceLabel.image1.jpg " ,  " image/jpeg " )]

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

[assembly: WebResource( " AspDemo.CustomComponents.Resources.AspDemo.CustomComponents.ResourceLabel.help.htm " ,  " text/html " , PerformSubstitution  =   true )]

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

namespace  AspDemo.CustomComponents

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

    public class ResourceLabel : Control

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

        protected override void CreateChildControls()

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            // Create a new Image control.

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            Image _img = new Image();

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            //擷取資源檔案引用

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            _img.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "AspDemo.CustomComponents.Resources.AspDemo.CustomComponents.ResourceLabel.image1.jpg");

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            this.Controls.Add(_img);

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            // Create a new Label control.

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            Label _lab = new Label();

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            _lab.Text = "A composite control using the WebResourceAttribute class.";

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            this.Controls.Add(_lab);

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            // Create a new HtmlAnchor control linking to help.htm.

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            HtmlAnchor a = new HtmlAnchor();

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            a.HRef = this.Page.ClientScript.GetWebResourceUrl(typeof(ResourceLabel), "AspDemo.CustomComponents.Resources.AspDemo.CustomComponents.ResourceLabel.help.htm");

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            a.InnerText = "help link";

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            this.Controls.Add(new LiteralControl("</br>"));

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            this.Controls.Add(a);

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

        }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

    }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

}

注意點:

(1)跟上面第二點一樣

(2)路徑為以預設命名空間為根路徑,然後以點文法擷取檔案路徑(AspDemo.CustomComponents為命名空間,Resources為檔案夾,AspDemo.CustomComponents.ResourceLabel.help.htm此為檔案名稱)

OK,這樣就算完成了

二.持久性控件狀态

下面也隻給出部分代碼(來自MSDN),這方面資料我相信已經很多了,隻當補充

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

        protected override void OnInit(EventArgs e)

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            base.OnInit(e);

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            Page.RegisterRequiresControlState(this);

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

        }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

        protected override object SaveControlState()

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            object obj = base.SaveControlState();

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            if (indexValue != 0)

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                if (obj != null)

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                    return new Pair(obj, indexValue);

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                else

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                    return (indexValue);

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            else

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                return obj;

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

        }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

        protected override void LoadControlState(object state)

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            if (state != null)

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                Pair p = state as Pair;

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                if (p != null)

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                    base.LoadControlState(p.First);

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                    indexValue = (int)p.Second;

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                else

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                    if (state is int)

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                        indexValue = (int)state;

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                    }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                    else

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                        base.LoadControlState(state);

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                    }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

                }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

            }

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

        }

三.用戶端回調

ASP.NET 2.0 Unleashed單獨列出了一章來講JavaScript在自定義控件中的使用,我想大家還是看書上例子吧,個人感覺很好,非常容易了解.而且學會這個的話,還可以看的懂AtlasControlToolkit裡面的幾個控件,幾乎都用到了這種技術.

四.配置檔案

(1)在web.config中預先定義控件标簽和注冊控件,進而可以在每個頁面省去

使用 @ Register 指令

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

     < pages >

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

       < controls >

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

         < add  tagPrefix ="aspDemo"  namespace ="AspDemo.CustomComponents"  assembly ="AspDemo.CustomComponents" />

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

       </ controls >

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

     </ pages >

(2)控件映射

url可以映射,控件也可以,我們在配置Ajax環境的時候就用到了此方法

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

< pages >

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

  < tagMapping >

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

         < add  tagType ="System.Web.UI.WebControls.RequiredFieldValidator"  mappedTagType ="System.Web.UI.Compatibility.RequiredFieldValidator, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

         </ pages >

五.在工具欄上隐藏控件

再講一個小東西,當定義的控件,不需要在工具欄上顯示的話,可以用此中繼資料把控件隐藏起來

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

[ToolboxItem( false )]

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

        public   class  ImageControl : WebControl

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

    }

好了,寫完這一篇了,如哪裡有錯誤還請大家指出,以上全憑經驗寫的

以下提供所有例子的代碼,希望對大家有用

1。在控件中加入類屬性WebResourceAttribute

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

[assembly: WebResource( " My.WebForm.ExGridView.Files.ExGridView.js " ,  " text/javascript " )]

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

[assembly: WebResource( " My.WebForm.ExGridView.Files.add.gif " ,  " image/gif " )]

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

[assembly: WebResource( " My.WebForm.ExGridView.Files.cancel.gif " ,  " image/gif " )]

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

[assembly: WebResource( " My.WebForm.ExGridView.Files.delete.gif " ,  " image/gif " )]

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

namespace  My.WebForm.ExGridView

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

{

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

    [ToolboxData("<{0}:ExGridView runat=server></{0}:ExGridView>")]

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

    [ParseChildren(true)]

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

    public class ExGridView : GridView,IPostBackDataHandler

元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發
元件開發之ASP.NET中內建資源檔案的伺服器端控件開發

}

   這裡要注意的是My.WebForm.ExGridView.Files并不是實際的目錄名字,My.WebForm.ExGridView是控件的namespace,隻有Files是實際的想對于控件項目的根目錄的子目錄名稱,必須這樣全限定名引用,否則找不到資源!另外别忘了把這些資源檔案的編譯方式生成操作改成“嵌入得資源”

   2。在需要引用的地方使用CLientScriptManager.GetWebResourceUrl獲得資源的引用:

btn.CancelImageUrl  =   Page.ClientScript.GetWebResourceUrl( this .GetType(), " My.WebForm.ExGridView.Files.cancel.gif " );

同樣要注意使用全限定名,而且是大小寫區分的。好了,在asp.net2.0中就這麼簡單,從現在開始把資源檔案打包到控件中吧。

繼續閱讀