asp.net控件開發基礎(15) --------總結和補充

Hello,朋友們,新年快樂.很長時間沒寫博客了,一直在想寫這一篇,可沒想好怎麼寫,就一直放着.現在終於有時間了,那麼來繼續我們的話題吧.自定義控件.如果你還不熟悉自定義控件開發的話,還請看看我以前寫了幾篇,希望對你有幫助
1.1何處繼承
自定義控件一般從以下幾個基類(此處不包含數據控件)
一.Control類
(所有服務器控件的基類,算是比較底層的類,如果控件功能比較簡單,要求不多,可直接繼承此類.)
二.WebControl類(標準控件的基類,繼承此類,你可以繼承其豐富的公共屬性,若標準控件中的控件沒有你需要的控件,你可以繼承此類)
三.CompositeControl 類(2.0新增的類,此類繼承自WebControl類,如果你需要製作複合控件,請從繼承此類開始)
四.直接從內置控件繼承(我們知道輪子只需要發明一遍,你的需求跟內置差不多的話,請考慮這麼做)

1.2呈現控件

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

1.3與用戶交互

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

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

屬性相對而言比較簡單,也比較好理解,但其又比較麻煩.
當控件屬性太多,很容易亂,因此我們又認識了元數據,
把屬性進行了分類,如下圖  
   border=

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


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

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

1.5控件樣式

控件怎麼能缺樣式,我們自然需要它,在此我們再次認識到了WebControl類.當然也瞭解到了Style類及其子類
,只要你瞭解了其中的幾個方法你就可以自定義控件樣式了

1.6複合控件

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

1.7視圖狀態

不得不談的一個話題

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

最後我們還討論瞭如何爲控件添加客戶端功能,還有爲控件定義生成器.
好了,總結終於告一段落,以上寫了兩遍,第一遍寫的時候保存後數據居然丟失了,痛苦啊.

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

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

補充

一.嵌入資源的使用

1.嵌入控件圖標
內置控件都有自己的圖標,很多人也很喜歡爲自己的控件做個圖標,那如何做呢?


我們只需要使用ToolboxBitmap元數據就可以了,你需要了解其構造函數,用法如下

namespace AspDemo.CustomComponents
{
        [ToolboxBitmap(
typeof(ImageControl), "Resources.Image.bmp")]
   
public class ImageControl : WebControl
    
{
    }

}

注意點:

(1)圖標的位置位於,以你默認命名空間爲根目錄,以點語法的方式來指定圖標位置,(即圖標路徑爲/Resources)
否則的話以你控件類型命名控件爲根目錄,(即圖標路徑爲CustomComponents/Resources),大家可以嘗試一下
(2)在屬性面板指明圖標文件爲嵌入的資源,如下圖


2.嵌入其他資源文件

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

[assembly: WebResource("AspDemo.CustomComponents.Resources.AspDemo.CustomComponents.ResourceLabel.image1.jpg""image/jpeg")]
[assembly: WebResource(
"AspDemo.CustomComponents.Resources.AspDemo.CustomComponents.ResourceLabel.help.htm""text/html", PerformSubstitution = true)]
namespace AspDemo.CustomComponents
{

    
public class ResourceLabel : Control
    
{
        
protected override void CreateChildControls()
        
{

            
// Create a new Image control.
            Image _img = new Image();
            
//獲取資源文件引用
            _img.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "AspDemo.CustomComponents.Resources.AspDemo.CustomComponents.ResourceLabel.image1.jpg");
            
this.Controls.Add(_img);

            
// Create a new Label control.
            Label _lab = new Label();
            _lab.Text 
= "A composite control using the WebResourceAttribute class.";
            
this.Controls.Add(_lab);

            
// Create a new HtmlAnchor control linking to help.htm.
            HtmlAnchor a = new HtmlAnchor();
            a.HRef 
= this.Page.ClientScript.GetWebResourceUrl(typeof(ResourceLabel), "AspDemo.CustomComponents.Resources.AspDemo.CustomComponents.ResourceLabel.help.htm");
            a.InnerText 
= "help link";
            
this.Controls.Add(new LiteralControl("</br>"));
            
this.Controls.Add(a);

        }

    }

}

注意點:
(1)跟上面第二點一樣
(2)路徑爲以默認命名空間爲根路徑,然後以點語法獲取文件路徑
(AspDemo.CustomComponents爲命名空間,Resources爲文件夾,AspDemo.CustomComponents.ResourceLabel.help.htm此爲文件名稱)

OK,這樣就算完成了

二.持久性控件狀態

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


        protected override void OnInit(EventArgs e)
        
{
            
base.OnInit(e);
            Page.RegisterRequiresControlState(
this);
        }


        
protected override object SaveControlState()
        
{

            
object obj = base.SaveControlState();

            
if (indexValue != 0)
            
{
                
if (obj != null)
                
{
                    
return new Pair(obj, indexValue);
                }

                
else
                
{
                    
return (indexValue);
                }

            }

            
else
            
{
                
return obj;
            }

        }


        
protected override void LoadControlState(object state)
        
{
            
if (state != null)
            
{
                Pair p 
= state as Pair;
                
if (p != null)
                
{
                    
base.LoadControlState(p.First);
                    indexValue 
= (int)p.Second;
                }

                
else
                
{
                    
if (state is int)
                    
{
                        indexValue 
= (int)state;
                    }

                    
else
                    
{
                        
base.LoadControlState(state);
                    }

                }

            }

        }

三.客戶端回調

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

四.配置文件

(1)在web.config中預先定義控件標籤和註冊控件,從而可以在每個頁面省去
使用 @ Register 指令

    <pages>
      
<controls>

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

    
</pages>


(2)控件映射

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

<pages>
 
<tagMapping>
        
<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"/>
        
        </pages>

五.在工具欄上隱藏控件

再講一個小東西,當定義的控件,不需要在工具欄上顯示的話,可以用此元數據把控件隱藏起來
[ToolboxItem(false)]
       
public class ImageControl : WebControl
    
{
    }
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章