Hello,朋友們,新年快樂(lè ).很長(cháng)時(shí)間沒(méi)寫(xiě)博客了,一直在想寫(xiě)這一篇,可沒(méi)想好怎么寫(xiě),就一直放著(zhù).現在終于有時(shí)間了,那么來(lái)繼續我們的話(huà)題吧.自定義控件.如果你還不熟悉自定義控件開(kāi)發(fā)的話(huà),還請看看我以前寫(xiě)了幾篇,希望對你有幫助
1.1何處繼承
自定義控件一般從以下幾個(gè)基類(lèi)(此處不包含數據控件)
一.Control類(lèi)(所有服務(wù)器控件的基類(lèi),算是比較底層的類(lèi),如果控件功能比較簡(jiǎn)單,要求不多,可直接繼承此類(lèi).)
二.WebControl類(lèi)(標準控件的基類(lèi),繼承此類(lèi),你可以繼承其豐富的公共屬性,若標準控件中的控件沒(méi)有你需要的控件,你可以繼承此類(lèi))
三.CompositeControl 類(lèi)(2.0新增的類(lèi),此類(lèi)繼承自WebControl類(lèi),如果你需要制作復合控件,請從繼承此類(lèi)開(kāi)始)
四.直接從內置控件繼承(我們知道輪子只需要發(fā)明一遍,你的需求跟內置差不多的話(huà),請考慮這么做)
1.2呈現控件
Control類(lèi)Render方法為基本呈現方法,RenderContent方法是在Render方法之上的,其為控件加了一個(gè)標簽,我認為RenderContent方法是為WebControl類(lèi)中屬性準備的.基本的方法繼續深刻的去了解.
1.3與用戶(hù)交互
純粹的呈現控件還不夠,我們需要傳遞數據,這就必然讓我們了解自定義控件事件處理
1.4接觸屬性(見(jiàn)第五,九,十篇)
屬性相對而言比較簡(jiǎn)單,也比較好理解,但其又比較麻煩.
當控件屬性太多,很容易亂,因此我們又認識了元數據,
把屬性進(jìn)行了分類(lèi),如下圖
為了更清晰了,把
屬性分好類(lèi)別,我們又用另外做法,把多種同類(lèi)型的屬性,定義在一個(gè)大的屬性里面,稱(chēng)之為
復雜屬性,如下圖
屬性已經(jīng)夠多了,不緊如此,我們還知道屬性的每種類(lèi)型可能不一樣,而在呈現之后都是呈現字符串形式,簡(jiǎn)單屬性.net已為你處理好轉換,當你自定義復雜屬性以后,你則需要自己為你定義的復雜屬性定義一個(gè)
類(lèi)型轉換器(見(jiàn)第九篇)
屬性還有另外一種做法,就是可以把屬性當成
集合屬性來(lái)用.可以說(shuō)是特殊話(huà)的
復雜控件,這樣做可以提供給一些列表控件使用
(見(jiàn)第10篇) 屬性用途還真不少
1.5控件樣式
控件怎么能缺樣式,我們自然需要它,在此我們再次認識到了
WebControl類(lèi).當然也了解到了
Style類(lèi)及其子類(lèi)
,只要你了解了其中的幾個(gè)方法你就可以自定義控件樣式了
1.6復合控件
復合控件的功能往往比較強大,它利用當前已經(jīng)存在的控件進(jìn)行
組裝成一個(gè)新的控件,在此過(guò)程中我們學(xué)習了在復合控件中定義事件以及定義樣式.
1.7視圖狀態(tài)
不得不談的一個(gè)話(huà)題
一般我們?yōu)榭丶x的屬性都以視圖狀態(tài)的形式保存,
然而復雜屬性的定義和控件樣式定義則需要你了解如何自定義視圖狀態(tài)
最后我們還討論了如何為控件
添加客戶(hù)端功能,還有為控件
定義生成器.
好了,總結終于告一段落,以上寫(xiě)了兩遍,第一遍寫(xiě)的時(shí)候保存后數據居然丟失了,痛苦啊.
下面我們分享一些小技巧,或許大家早已經(jīng)知道了,為了以后更好的學(xué)習,我把命名控件全部更改為
AspDemo.CustomComponents
此次下載的源碼包括1-16篇的全部的示例代碼,如果有什么錯誤還請大家指出
補充
一.嵌入資源的使用
1.嵌入控件圖標
內置控件都有自己的圖標,很多人也很喜歡為自己的控件做個(gè)圖標,那如何做呢?
我們只需要使用
ToolboxBitmap元數據就可以了,你需要了解其構造函數,用法如下
namespace AspDemo.CustomComponents
{
[ToolboxBitmap(typeof(ImageControl), "Resources.Image.bmp")]
public class ImageControl : WebControl
{
}
} 注意點(diǎn):
(1)圖標的位置位于,以你默認命名空間為根目錄,以點(diǎn)語(yǔ)法的方式來(lái)指定圖標位置,(即圖標路徑為/Resources)
否則的話(huà)以你控件類(lèi)型命名控件為根目錄,(即圖標路徑為CustomComponents/Resources),大家可以嘗試一下
(2)在屬性面板指明圖標文件為嵌入的資源,如下圖
2.嵌入其他資源文件
記得以前我們做了一個(gè)控件需要一個(gè)js文件,當需要使用這個(gè)控件的話(huà),則也需要使用js文件,這樣給別人用的話(huà)很不方面,我們可以把js文件作為嵌入資源使用來(lái)解決這一問(wèn)題.以下例子來(lái)自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);
}
}
} 注意點(diǎn):
(1)跟上面第二點(diǎn)一樣
(2)路徑為以默認命名空間為根路徑,然后以點(diǎn)語(yǔ)法獲取文件路徑(
AspDemo.CustomComponents為命名空間,Resources為文件夾,AspDemo.CustomComponents.ResourceLabel.help.htm此為文件名稱(chēng))
OK,這樣就算完成了
二.持久性控件狀態(tài)下面也只給出部分代碼(來(lái)自MSDN),這方面資料我相信已經(jīng)很多了,只當補充
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);
}
}
}
} 三.客戶(hù)端回調
ASP.NET 2.0 Unleashed單獨列出了一章來(lái)講JavaScript在自定義控件中的使用,我想大家還是看書(shū)上例子吧,個(gè)人感覺(jué)很好,非常容易理解.而且學(xué)會(huì )這個(gè)的話(huà),還可以看的懂AtlasControlToolkit里面的幾個(gè)控件,幾乎都用到了這種技術(shù).
四.配置文件
(1)在web.config中預先定義控件標簽和注冊控件,從而可以在每個(gè)頁(yè)面省去
使用 @ Register 指令 <pages>
<controls>
<add tagPrefix="aspDemo" namespace="AspDemo.CustomComponents" assembly="AspDemo.CustomComponents"/>
</controls>
</pages>
(2)控件映射
url可以映射,控件也可以,我們在配置Ajax環(huán)境的時(shí)候就用到了此方法
<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> 五.在工具欄上隱藏控件
再講一個(gè)小東西,當定義的控件,不需要在工具欄上顯示的話(huà),可以用此元數據把控件隱藏起來(lái)
[ToolboxItem(false)]
public class ImageControl : WebControl
{
} 好了,寫(xiě)完這一篇了,如哪里有錯誤還請大家指出,以上全憑經(jīng)驗寫(xiě)的
以下提供所有例子的代碼,希望對大家有用
示例代碼下載