新聞中心
這次我們要討論的是ASP.NET控件開發(fā)基礎(chǔ)中ASP.NET復(fù)合控件.本文無(wú)法一步到位完整介紹,因?yàn)橛懻摰钠容^大,所以分兩次寫,這次就先講些基本概念吧,剩著的下次寫.

好象復(fù)合控件網(wǎng)上已經(jīng)有很多教程了,相信大家也看過(guò)很多.如果看過(guò)的朋友就當(dāng)我再?gòu)U話一便,沒看過(guò)的朋友希望能給你帶來(lái)幫助.
ASP.NET控件開發(fā)基礎(chǔ)呢首先我們來(lái)認(rèn)識(shí)下ASP.NET控件開發(fā)基礎(chǔ)中ASP.NET復(fù)合控件的情況:
1.ASP.NET復(fù)合控件概念
復(fù)合控件跟用戶控件有很多相似點(diǎn),***不同就是用戶控件后綴為ascx,而復(fù)合控件編譯后則為dll文件,還可以分發(fā)給大家使用,另外其他不同點(diǎn)還請(qǐng)參考MSDN吧,說(shuō)白了,復(fù)合控件靈活性更大.
2.ASP.NET復(fù)合控件的呈現(xiàn)
(1)一般控件的呈現(xiàn)
從***篇到第六篇為止,我們用以呈現(xiàn)控件的方法介紹過(guò)的有Render方法和RenderContents方法.回顧一下吧,看以下其中的一小段代碼.
示例一
- public override void Render(HtmlTextWriter writer)
- {
- ..
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- writer.AddAttribute(HtmlTextWriterAttribute.Name, "CreditCardNo");
- writer.AddAttribute(HtmlTextWriterAttribute.Id, "CreditCardNo");
- writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");
- writer.RenderBeginTag(HtmlTextWriterTag.Input);
- writer.RenderEndTag();
- writer.RenderEndTag();
- }
以前我們所做的控件都是上面這樣的寫法.我們可以認(rèn)為在Render方法實(shí)現(xiàn)了以下兩個(gè)功能.
一.標(biāo)簽布局(如td標(biāo)簽,讓控件呈現(xiàn)的好看點(diǎn)-_-)
二.呈現(xiàn)的標(biāo)簽(如input標(biāo)簽)
(2)ASP.NET復(fù)合控件的呈現(xiàn)方法
我們知道asp.net控件庫(kù)里面已經(jīng)提供給了我們像TextBox這樣的控件了,就如組裝電腦一下,你可以組裝.net提供你現(xiàn)有的控件,然后重新拼湊成一個(gè)新的控件,這樣便成了復(fù)合控件.但其呈現(xiàn)方法卻又不同.
復(fù)合控件是以包含子控件的形式呈現(xiàn)的,具體的呈現(xiàn)交給子控件自己去做,因?yàn)樽涌丶陨矶家呀?jīng)實(shí)現(xiàn)了其呈現(xiàn)方法(每個(gè)控件都繼承自Control類).假設(shè)你還不明白就看下面的圖吧.
LabelTextBox1為復(fù)合控件,LabelTextBox2則不是.兩者的呈現(xiàn)方式是不同的.具體實(shí)現(xiàn)方法請(qǐng)看下文
3.完成基本ASP.NET復(fù)合控件基本呈現(xiàn)
(1)首先你要熟悉以下的屬性和方法
Control.CreateChildControls 方法用于創(chuàng)建子控件
Control.EnsureChildControls 方法用于確認(rèn)是否已創(chuàng)建子控件,如果未創(chuàng)建完成的話則調(diào)用CreateChildControls 方法創(chuàng)建子控件
Control.ChildControlsCreated 屬性 獲取一個(gè)值,是否已創(chuàng)建子控件
(2)了解并實(shí)現(xiàn)INamingContainer接口
用戶控件UserControl類則繼承了INamingContainer接口,確包保子控件具有唯一的ID名稱,那復(fù)合控件也需要實(shí)現(xiàn)這個(gè)接口達(dá)到一樣的目的,這個(gè)是值得注意的地方.
復(fù)合控件以類撰寫的方法來(lái)添加控件即CreateChildControls 方法,而非在Render方法中以下面方式實(shí)現(xiàn)
writer.RenderBeginTag(HtmlTextWriterTag.Input);
在復(fù)合控件里Render方法的作用只是為我們提供布局的需要
下面看一個(gè)完成的代碼,以微軟的示例為例子.一個(gè)登錄控件.
先看效果如下
再來(lái)看看代碼吧,其實(shí)以下代碼并不復(fù)雜.只不過(guò)屬性多一點(diǎn)而已.看下面步驟
先定義控件類很簡(jiǎn)單.
然后定義幾個(gè)公開的屬性,注意每個(gè)屬性都有一個(gè)EnsureChildControls 方法,因?yàn)榉祷氐亩际强丶膶傩?而我們又無(wú)法判斷控件是否已經(jīng)創(chuàng)建,所以須用此方法確保已創(chuàng)建控件,然后才可以使用其屬性.
再通過(guò)類撰寫方法CreateChildControls來(lái)添加子控件.
***在Render方法實(shí)現(xiàn)布局以及用控件的RenderControl方法呈現(xiàn)自身標(biāo)簽內(nèi)容,***還要注意Render方法中的AddAttributesToRender方法,以前已經(jīng)解釋過(guò)這個(gè)方法的用處了,不調(diào)用此方法就無(wú)福享用WebControl類提供給你諸多樣式屬性了
以下注意的地方均以紅字標(biāo)出.說(shuō)了一大堆了,看看下面代碼,你明白了沒?
示例二
- public class CompositeLogin : WebControl, INamingContainer
- {
- private Button _button;
- private TextBox _nameTextBox;
- private Label _nameLabel;
- private TextBox _passwordTextBox;
- private Label _passwordLabel;
- private RequiredFieldValidator _nameValidator;
- private RequiredFieldValidator _passwordValidator;
- 屬性#region 屬性
- [
- Bindable(true),
- Category("Appearance"),
- DefaultValue(""),
- Description("按鈕文本")
- ]
- public string ButtonText
- {
- get
- {
- EnsureChildControls();
- return _button.Text;
- }
- set
- {
- EnsureChildControls();
- _button.Text = value;
- }
- }
- [
- Bindable(true),
- Category("Default"),
- DefaultValue(""),
- Description("姓名")
- ]
- public string Name
- {
- get
- {
- EnsureChildControls();
- return _nameTextBox.Text;
- }
- set
- {
- EnsureChildControls();
- _nameTextBox.Text = value;
- }
- }
- [
- Bindable(true),
- Category("Appearance"),
- DefaultValue(""),
- Description(
- "必須輸入姓名")
- ]
- public string NameErrorMessage
- {
- get
- {
- EnsureChildControls();
- return _nameValidator.ErrorMessage;
- }
- set
- {
- EnsureChildControls();
- _nameValidator.ErrorMessage = value;
- _nameValidator.ToolTip = value;
- }
- }
- [
- Bindable(true),
- Category("Apperance"),
- DefaultValue(""),
- Description("姓名標(biāo)簽")
- ]
- public string NameLabel
- {
- get
- {
- EnsureChildControls();
- return _nameLabel.Text;
- }
- set
- {
- EnsureChildControls();
- _nameLabel.Text = value;
- }
- }
- [
- Browsable(false),
- DesignerSerializationVisibility(
- DesignerSerializationVisibility.Hidden)
- ]
- public string Password
- {
- get
- {
- EnsureChildControls();
- return _passwordTextBox.Text;
- }
- }
- [
- Bindable(true),
- Category("Appearance"),
- DefaultValue(""),
- Description(
- "必須輸入密碼")
- ]
- public string PasswordErrorMessage
- {
- get
- {
- EnsureChildControls();
- return _passwordValidator.ErrorMessage;
- }
- set
- {
- EnsureChildControls();
- _passwordValidator.ErrorMessage = value;
- _passwordValidator.ToolTip = value;
- }
- }
- [
- Bindable(true),
- Category("Appearance"),
- DefaultValue(""),
- Description("密碼標(biāo)簽")
- ]
- public string PasswordLabel
- {
- get
- {
- EnsureChildControls();
- return _passwordLabel.Text;
- }
- set
- {
- EnsureChildControls();
- _passwordLabel.Text = value;
- }
- }
- #endregion Properties delegated to child controls
- 方法#region 方法
- //撰寫
- protected override void CreateChildControls()
- {
- Controls.Clear();
- _nameLabel = new Label();
- _nameTextBox = new TextBox();
- _nameTextBox.ID = "nameTextBox";
- _nameValidator = new RequiredFieldValidator();
- _nameValidator.ID = "validator1";
- _nameValidator.ControlToValidate = _nameTextBox.ID;
- _nameValidator.Text = "*";
- _nameValidator.Display = ValidatorDisplay.Static;
- _passwordLabel = new Label();
- _passwordTextBox = new TextBox();
- _passwordTextBox.TextMode = TextBoxMode.Password;
- _passwordTextBox.ID = "passwordTextBox";
- _passwordValidator = new RequiredFieldValidator();
- _passwordValidator.ID = "validator2";
- _passwordValidator.ControlToValidate = _passwordTextBox.ID;
- _passwordValidator.Text = "*";
- _passwordValidator.Display = ValidatorDisplay.Static;
- _button = new Button();
- _button.ID = "button1";
- this.Controls.Add(_nameLabel);
- this.Controls.Add(_nameTextBox);
- this.Controls.Add(_nameValidator);
- this.Controls.Add(_passwordLabel);
- this.Controls.Add(_passwordTextBox);
- this.Controls.Add(_passwordValidator);
- this.Controls.Add(_button);
- }
- //布局
- protected override void Render(HtmlTextWriter writer)
- {
- AddAttributesToRender(writer);
- writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding,
- "1", false);
- writer.RenderBeginTag(HtmlTextWriterTag.Table);
- writer.RenderBeginTag(HtmlTextWriterTag.Tr);
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- _nameLabel.RenderControl(writer);
- writer.RenderEndTag(); // Td
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- _nameTextBox.RenderControl(writer);
- writer.RenderEndTag(); // Td
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- _nameValidator.RenderControl(writer);
- writer.RenderEndTag(); // Td
- writer.RenderEndTag(); // Tr
- writer.RenderBeginTag(HtmlTextWriterTag.Tr);
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- _passwordLabel.RenderControl(writer);
- writer.RenderEndTag(); // Td
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- _passwordTextBox.RenderControl(writer);
- writer.RenderEndTag(); // Td
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- _passwordValidator.RenderControl(writer);
- writer.RenderEndTag(); // Td
- writer.RenderEndTag(); // Tr
- writer.RenderBeginTag(HtmlTextWriterTag.Tr);
- writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");
- writer.AddAttribute(HtmlTextWriterAttribute.Align, "right");
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- _button.RenderControl(writer);
- writer.RenderEndTag(); // Td
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- writer.Write(" ");
- writer.RenderEndTag(); // Td
- writer.RenderEndTag(); // Tr
- writer.RenderEndTag(); // Table
- }
- #endregion Overriden methods
- }
4.控件狀態(tài)以及性能方面的選擇
上面的例子你會(huì)發(fā)現(xiàn),再點(diǎn)擊按鈕以后,textbox值狀態(tài)被保存了下來(lái),還記得以前以Render方法直接呈現(xiàn)input標(biāo)簽的控件嗎?在點(diǎn)擊按鈕以后textbox值狀態(tài)是無(wú)法保存的.
第三篇的時(shí)候,我們討論了數(shù)據(jù)回傳的一些知識(shí),我們也定義了一個(gè)textbox控件,在點(diǎn)擊按鈕以后,可以***的保存其值狀態(tài).
至于原因,還請(qǐng)大家參考下文,作者已經(jīng)分析的很清楚了.
ASP.NET控件開發(fā)速成教程:生成復(fù)合控件
關(guān)于性能方面的問(wèn)題,以下引用MSDN,具體大家還須參考MSDN
雖然創(chuàng)作復(fù)合控件相對(duì)比較容易,但是由于在撰寫時(shí)必須創(chuàng)建子控件,所以會(huì)出現(xiàn)性能系統(tǒng)開銷。如果您想優(yōu)化控件的性能,可以通過(guò)重寫 Render 方法,自己實(shí)現(xiàn)呈現(xiàn)邏輯。另外,必須實(shí)現(xiàn)控件所需的任何回發(fā)數(shù)據(jù)處理和回發(fā)事件處理。
本來(lái)想一起把事件處理和樣式也寫完了,但想寫好篇幅太多了,這次就先寫到這里吧,因?yàn)橄氚炎约盒睦锏囊馑急磉_(dá)明白還真的需要費(fèi)一定時(shí)間去想的.下次我們繼續(xù)討論復(fù)合控件的事件和樣式。
ASP.NET控件開發(fā)基礎(chǔ)之ASP.NET復(fù)合控件的基本情況就向你介紹到這里,希望對(duì)你了解ASP.NET復(fù)合控件有所幫助。
網(wǎng)站題目:ASP.NET控件開發(fā)基礎(chǔ)之復(fù)合控件淺析
分享URL:http://www.5511xx.com/article/dpoipss.html


咨詢
建站咨詢
