国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
ASP.NET 2.0服務(wù)器控件之復(fù)合控件概述

ASP.NET 2.0服務(wù)器控件之復(fù)合控件概述

2006-08-07 07:00 作者: 金屬邊緣 出處: 天極開發(fā) 責(zé)任編輯:方舟
  下載本文源代碼

  在前面的文章中,主要介紹了服務(wù)器控件的基本概念、基本理論,這些內(nèi)容是構(gòu)建所有自定義服務(wù)器控件的基石。然而,僅僅依靠這些知識還不足以創(chuàng)建出優(yōu)秀的服務(wù)器控件。因為,不同類型的服務(wù)器控件具有不同的創(chuàng)建方法,開發(fā)人員必須在掌握基本概念和理論之后,掌握不同類型服務(wù)器控件的開發(fā)方法。本文及其隨后幾篇文章將詳細介紹與創(chuàng)建復(fù)合控件相關(guān)的內(nèi)容。本文重點介紹有關(guān)復(fù)合控件的概念、創(chuàng)建方法等理論,然后,通過一個典型示例加深讀者對于復(fù)合控件創(chuàng)建方法的理解。

  復(fù)合控件概述

  復(fù)合控件中的“復(fù)合”一詞表明該類型控件本質(zhì)上由多個組件組合而成。同時,復(fù)合控件對外暴露的成員對象通常由構(gòu)成組件的方法和屬性提供,并且可能加入一些新的成員。復(fù)合控件也可以實現(xiàn)自定義事件,并處理并引發(fā)子控件所引起的事件。就功能方面而言,復(fù)合控件的功能要比簡單組合幾個控件的功能要強大的多,而且很多時候具有一定的專項性。例如,ASP.NET 2.0新增的Login控件就是一個典型的復(fù)合控件。該控件用戶界面由多個單獨控件組合而成,并且使用單一的API對控件進行設(shè)置和訪問。另外,Login控件由于與成員資格等功能集成的原因,因此,其具有快速實現(xiàn)用戶登錄的功能。

  可能部分有經(jīng)驗的讀者在了解了復(fù)合控件的基本概念之后會有所疑惑:復(fù)合控件與用戶控件好像非常相似,那么它們之間有什么區(qū)別嗎?到底什么時候創(chuàng)建復(fù)合控件,什么時候創(chuàng)建用戶控件呢?回答這個問題,我們必須從用戶控件的基本概念入手進行研究。

  簡單而言,用戶控件是指在一個項目中,由于同樣一些功能模塊在多處引用,例如,導(dǎo)航菜單等,可以把這一塊代碼做成一個用戶控件,然后,在需要引用的頁面中注冊后,直接按控件使用的方式引用,省去了重復(fù)編寫相同代碼的工作。就復(fù)合控件與用戶控件的區(qū)別而言,主要可以總結(jié)為以下幾點:

  一、復(fù)合控件創(chuàng)作的最短設(shè)計時支持,用戶控件創(chuàng)作的完全設(shè)計時支持。在可視化設(shè)計器中,創(chuàng)作用戶控件與創(chuàng)作ASP.NET頁沒有差別。

  二、復(fù)合控件是以目標為公共語言運行庫的面向?qū)ο蟮木幊陶Z言,如C#,是用編程方式創(chuàng)作的用戶控件是使用ASP.NET頁語法和腳本塊聲明性地創(chuàng)作的。

  三、復(fù)合控件是作為程序集(.dll)編譯和保持的。用戶控件是帶有.ascx擴展名的文本文件。

  四、復(fù)合控件非常適于創(chuàng)作一般的可重新發(fā)布的控件,用戶控件適合應(yīng)用程序特定的功能。

  五、可將復(fù)合控件添加到可視化設(shè)計器的工具箱中并拖放到頁面上,使用時可以在屬性框中設(shè)計,用戶控件只能在HTML中編寫。

  通過以上內(nèi)容,相信讀者已經(jīng)能夠基本了解了復(fù)合控件。下面介紹一下創(chuàng)建復(fù)合控件的實現(xiàn)方法。在這個過程中,開發(fā)人員必須把握以下幾個要點:

  第一、通常情況,復(fù)合控件類必須派生自System.Web.UI.WebControls.CompositeControl類。這一點與ASP.NET 1.x環(huán)境下開發(fā)復(fù)合控件有些不同。在ASP.NET 1.x中,復(fù)合控件必須實現(xiàn)System.Web.UI.INamingContainer接口。然而,在ASP.NET 2.0下,復(fù)合控件類的基類則發(fā)生了變化。下面簡單介紹一下CompositeControl類。

  CompositeControl類是一個抽象類,該類可為自定義控件提供命名容器和控件設(shè)計器功能,并且可包含全部子控件或使用其他控件功能。CompositeControl類的聲明代碼如下所示:

public abstract class CompositeControl : WebControl, INamingContainer, ICompositeControlDesignerAccessor

  如上代碼所示,CompositeControl類基層自WebControl基類,并且實現(xiàn)INamingContainer和ICompositeControlDesignerAccessor接口。INamingContainer是一個沒有方法的標記接口。當(dāng)控件在實現(xiàn)INamingContainer時,頁框架可在該控件下創(chuàng)建新的命名范圍,因此,能夠確保子控件在控件的分層樹中具有唯一的名稱。當(dāng)復(fù)合控件公開模板屬性,提供數(shù)據(jù)綁定或需要傳送事件到子控件時,這是非常重要的。ICompositeControlDesignerAccessor接口使復(fù)合控件設(shè)計器可以在設(shè)計時重新創(chuàng)建其關(guān)聯(lián)控件的子控件。該接口包含一個需要實現(xiàn)的方法RecreateChildControls。該方法使復(fù)合控件的設(shè)計器可以在設(shè)計時重新創(chuàng)建該控件的子控件。

  另外,如果創(chuàng)建的是數(shù)據(jù)綁定復(fù)合控件,那么自定義控件類的基類應(yīng)該是CompositeDataBoundControl。有關(guān)該類的具體內(nèi)容,請讀者查閱相關(guān)資料。

  第二、必須重寫Control基類的CreateChildControls方法,以便對子控件進行初始化、實例化,并將其添加到控件樹中。CreateChildControls用于通知使用基于合成實現(xiàn)的服務(wù)器控件,創(chuàng)建它們包含的任何子控件,以便為回發(fā)或呈現(xiàn)做準備。重寫該方法是實現(xiàn)復(fù)合控件的關(guān)鍵所在。這種類撰寫的方法將通知.NET框架有關(guān)復(fù)合控件中包含哪些子控件,以及各個子控件在控件樹中的位置和關(guān)系等內(nèi)容。通過這種方法,復(fù)合控件將復(fù)用子控件提供的實現(xiàn)來進行呈現(xiàn)、事件處理、樣式及其他功能。

  在實現(xiàn)復(fù)合控件過程中,除了掌握CompositeControl基類和CreateChildControls方法之外,ASP.NET 2.0還提供了與復(fù)合控件相關(guān)的其他方法和屬性,掌握這些成員對于開發(fā)復(fù)合控件也很重要。下面列舉了這些常見方法和屬性。

  · protected virtual void EnsureChildControls()

  該方法用于確定服務(wù)器控件是否包含子控件。如果不包含,則創(chuàng)建子控件。該方法首先檢查 ChildControlsCreated 屬性的當(dāng)前值。如果此值為假,則調(diào)用CreateChildControls方法。當(dāng)需要確保已創(chuàng)建子控件時,將調(diào)用該方法。大多數(shù)情況下,自定義服務(wù)器控件的開發(fā)人員無需重寫此方法。如果確實重寫了此方法,請按與其默認行為相似的方式來使用。

  · public virtual Control FindControl(string)

  該方法用于在當(dāng)前的命名容器中搜索指定的服務(wù)器控件。

  · public virtual bool HasControls()

  該方法用于確定服務(wù)器控件是否包含任何子控件。如果控件包含其他控件,則為true;否則為 false。由于該方法僅確定是否存在任何子控件,它可以通過允許您避免不必要的Controls.Count屬性調(diào)用來改進性能。調(diào)用此屬性要求實例化ControlCollection對象。如果沒有子級,則創(chuàng)建該對象會浪費服務(wù)器資源。

  · protected virtual void DataBindChildren ()

  該方法是ASP.NET 2.0新增內(nèi)容,其用于將數(shù)據(jù)源綁定到服務(wù)器控件的子控件。這為開發(fā)數(shù)據(jù)綁定類型的復(fù)合控件提供了便利。然而,需要注意的是,在服務(wù)器控件上調(diào)用此方法時,此方法不會將數(shù)據(jù)綁定到控件。若要綁定服務(wù)器控件及其所有子控件,請調(diào)用DataBind方法。

  · protected bool HasEvents ()

  這也是一個ASP.NET 2.0新增的方法,其用于返回一個值,該值指示是否為控件或任何子控件注冊事件。如果注冊事件,則為true;否則為false。

  · Controls屬性

  該屬性的數(shù)據(jù)類型為ControlCollection,其用于獲取ControlCollection對象,該對象表示 UI 層次結(jié)構(gòu)中指定服務(wù)器控件的子控件。其屬性值指定服務(wù)器控件的子控件集合。

  · NamingContainer屬性

  該屬性的數(shù)據(jù)類型為Control,其用于獲取對服務(wù)器控件的命名容器的引用,此引用創(chuàng)建唯一的命名空間,以區(qū)分具有相同Control.ID屬性值的服務(wù)器控件。

  · ChildControlsCreated屬性

  該屬性的數(shù)據(jù)類型為bool,其用于獲取一個值,該值指示是否已創(chuàng)建服務(wù)器控件的子控件。如果已創(chuàng)建子控件則為true;否則為false。

共3頁。 1 2 3 :
典型應(yīng)用

  上文介紹了有關(guān)創(chuàng)建復(fù)合控件的一些基本知識,下面將通過一個典型應(yīng)用加深讀者對于復(fù)合控件實現(xiàn)方法的理解,其重點放在針對復(fù)合控件的呈現(xiàn)方法上。

  多數(shù)控件呈現(xiàn)通過重寫Render方法實現(xiàn),然而,在復(fù)合控件中則大有不同。復(fù)合控件由多個子控件組合而成,其呈現(xiàn)邏輯是由子控件提供的。

  據(jù)此,在少數(shù)較為簡單的情況下,復(fù)合控件不用重寫Render方法,例如,創(chuàng)建一個包含文本框和按鈕的復(fù)合控件,這時,只要通過類撰寫的方法在CreateChildControls中添加相關(guān)控件即可,而無需Render方法。但是,在多數(shù)情況下,復(fù)合控件中既包含子控件,又包含用于格式化和布局的HTML。

  針對這種情況,如果只采取類撰寫的實現(xiàn)方法,那么很容易造成錯誤,并且生成的復(fù)合控件性能受到很大影響。最好的解決方法是重寫CreateChildControls方法,同時也重寫Render方法。在CreateChildControls方法中,為復(fù)合控件添加子控件;在Render方法中,為HTTP輸出流添加用于格式化和布局的HTML。

  下面列舉了呈現(xiàn)復(fù)合控件的關(guān)鍵步驟:

  · 控件基類繼承自CompositeControl基類。這是在ASP.NET 2.0中創(chuàng)建復(fù)合控件的關(guān)鍵所在。

  · 重寫CreateChildControls方法,完成實例化、初始化子控件,并且將子控件添加到控件集合中。

  · 重寫ICompositeControlDesignerAccessor接口的RecreateChildContrls方法。

  · 如果復(fù)合控件中存在用于格式化和布局的HTML,那么建議將這些內(nèi)容寫入Render方法中,而不要在CreateChildControls方法中創(chuàng)建和添加所需的LiteralControl實例。另外,在添加相關(guān)HTML代碼過程中,為了讓子控件使用默認生成方法,必須使每個子控件調(diào)用RenderControl方法。

  為了便于讀者更好的理解以上內(nèi)容,下面舉例說明。在此示例中,Register控件使用子控件創(chuàng)建用戶界面(UI),用于輸入用戶信息,以向網(wǎng)站注冊。此用戶界面包括兩個TextBox控件(一個用于輸入用戶名,另一個用于輸入用戶的電子郵件地址)和一個用于提交信息的Button控件。Register還將RequiredFieldValidator控件與兩個TextBox控件關(guān)聯(lián)起來,以確保用戶輸入了名稱和電子郵件地址。復(fù)合控件Register源代碼如下所示:

using System;
using System.ComponentModel;
using System.Drawing;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebControlLibrary{
[
 DefaultProperty("ButtonText"),
 ToolboxData("<{0}:Register runat=\"server\"> </{0}:Register>"),
]

public class Register : CompositeControl {
// 定義私有字段
private Button submitButton;
private TextBox nameTextBox;
private Label nameLabel;
private TextBox emailTextBox;
private Label emailLabel;
private RequiredFieldValidator emailValidator;
private RequiredFieldValidator nameValidator;
// 實現(xiàn)屬性ButtonText

[
 Bindable(true),
 Category("Appearance"),
 DefaultValue(""),
 Description("按鈕上的文字內(nèi)容.")
]

public string ButtonText {
 get {
  EnsureChildControls();
  return submitButton.Text;
 }
 set {
  EnsureChildControls();
  submitButton.Text = value;
 }
}

// 實現(xiàn)屬性Name

[
 Bindable(true),
 Category("Default"),
 DefaultValue(""),
 Description("用戶名.")
]

public string Name {
 get {
  EnsureChildControls();
  return nameTextBox.Text;
 }
 set {
  EnsureChildControls();
  nameTextBox.Text = value;
 }
}

// 實現(xiàn)屬性NameErrorMessage

[
 Bindable(true),
 Category("Appearance"),
 DefaultValue(""),
 Description("用戶名驗證錯誤信息.")
]

public string NameErrorMessage {
 get {
  EnsureChildControls();
  return nameValidator.ErrorMessage;
 }
 set {
  EnsureChildControls();
  nameValidator.ErrorMessage = value;
  nameValidator.ToolTip = value;
 }
}

// 實現(xiàn)屬性NameLabelText

[
 Bindable(true),
 Category("Appearance"),
 DefaultValue(""),
 Description("用戶名文本框旁的文字.")
]

public string NameLabelText {
 get {
  EnsureChildControls();
  return nameLabel.Text;
 }
 set {
  EnsureChildControls();
  nameLabel.Text = value;
 }
}

// 實現(xiàn)屬性Email

[
 Bindable(true),
 Category("Default"),
 DefaultValue(""),
 Description("郵件地址.")
]

public string Email {
 get {
  EnsureChildControls();
  return emailTextBox.Text;
 }
 set {
  EnsureChildControls();
  emailTextBox.Text = value;
 }
}

// 實現(xiàn)屬性EmailErrorMessage

[
 Bindable(true),
 Category("Appearance"),
 DefaultValue(""),
 Description("郵件地址驗證錯誤信息.")
]

public string EmailErrorMessage {
 get {
  EnsureChildControls();
  return emailValidator.ErrorMessage;
 }
 set {
  EnsureChildControls();
  emailValidator.ErrorMessage = value;
  emailValidator.ToolTip = value;
 }
}

// 實現(xiàn)屬性EmailLabelText

[
 Bindable(true),
 Category("Appearance"),
 DefaultValue(""),
 Description("電子郵件文本框旁的文字.")
]

public string EmailLabelText {
 get {
  EnsureChildControls();
  return emailLabel.Text;
 }
 set {
  EnsureChildControls();
  emailLabel.Text = value;
 }
}

// 重寫ICompositeControlDesignerAccessor接口的RecreateChildContrls方法

protected override void RecreateChildControls() {
 EnsureChildControls();
}

// 重寫Control基類的CreateChildControls方法

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 = NameErrorMessage;
 nameValidator.Display = ValidatorDisplay.Static;
 emailLabel = new Label();
 emailTextBox = new TextBox();
 emailTextBox.ID = "emailTextBox";
 emailValidator = new RequiredFieldValidator();
 emailValidator.ID = "validator2";
 emailValidator.ControlToValidate = emailTextBox.ID;
 emailValidator.Text = EmailErrorMessage;
 emailValidator.Display = ValidatorDisplay.Static;
 submitButton = new Button();
 submitButton.ID = "button1";
 this.Controls.Add(nameLabel);
 this.Controls.Add(nameTextBox);
 this.Controls.Add(nameValidator);
 this.Controls.Add(emailLabel);
 this.Controls.Add(emailTextBox);
 this.Controls.Add(emailValidator);
 this.Controls.Add(submitButton);
}

// 重寫Render方法

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();
 writer.RenderBeginTag(HtmlTextWriterTag.Td);
 nameTextBox.RenderControl(writer);
 writer.RenderEndTag();
 writer.RenderBeginTag(HtmlTextWriterTag.Td);
 nameValidator.RenderControl(writer);
 writer.RenderEndTag();
 writer.RenderEndTag();
 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 writer.RenderBeginTag(HtmlTextWriterTag.Td);
 emailLabel.RenderControl(writer);
 writer.RenderEndTag();
 writer.RenderBeginTag(HtmlTextWriterTag.Td);
 emailTextBox.RenderControl(writer);
 writer.RenderEndTag();
 writer.RenderBeginTag(HtmlTextWriterTag.Td);
 emailValidator.RenderControl(writer);
 writer.RenderEndTag();
 writer.RenderEndTag();
 writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2", false);
 writer.AddAttribute(HtmlTextWriterAttribute.Align, "right", false);
 writer.RenderBeginTag(HtmlTextWriterTag.Td);
 submitButton.RenderControl(writer);
 writer.RenderEndTag();
 writer.RenderBeginTag(HtmlTextWriterTag.Td);
 writer.Write(" ");
 writer.RenderEndTag();
 writer.RenderEndTag();
 writer.RenderEndTag();
}
}
}

  以上列舉了復(fù)合控件類Register的源代碼。雖然代碼有些冗長,然而還是比較容易理解的。下圖1列舉了Register類結(jié)構(gòu)圖。


圖1 類結(jié)構(gòu)圖

  如圖1并結(jié)合代碼可知,Register類繼承自CompositeControl基類,其實現(xiàn)了7個屬性和3個方法。屬性包括ButtonText、Email、EmailErrorMessage、EmailLabelText、Name、NameErrorMessage和NameLabelText。這些屬性通過命名,相信讀者基本可以了解其意義。
另外,Register類中重寫了來自不同對象的3個方法。

 ?。?)Render方法隸屬于Control基類,在本例中主要在該方法中定義了一些與控件布局相關(guān)的HTML等內(nèi)容。

 ?。?)CreateChildControls方法隸屬于Control基類。在本示例中通過重寫該方法,實現(xiàn)了將子控件添加到復(fù)合控件樹中的任務(wù)。請讀者牢記:每當(dāng)需要Controls集合時,例如,在數(shù)據(jù)綁定期間(如果適用),服務(wù)器控件結(jié)構(gòu)都會依賴對CreateChildControls的調(diào)用。為此,必須在CreateChildControls方法中添加子控件。

 ?。?)RecreateChildControls方法來自CompositeControl基類的ICompositeControlDesignerAccessor接口。通過實現(xiàn)這個方法可使復(fù)合控件的設(shè)計器可以在設(shè)計時重新創(chuàng)建該控件的子控件。

  下面列舉了為測試Register控件而創(chuàng)建的Default.aspx頁面源代碼。

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register TagPrefix="Sample" Assembly="WebControlLibrary" Namespace="WebControlLibrary" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>實現(xiàn)復(fù)合控件呈現(xiàn)</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<Sample:Register id="demo1" runat="server" ButtonText="注冊" EmailLabelText="電子郵件" NameLabelText="用戶名" EmailErrorMessage="不能為空" NameErrorMessage="不能為空" />
</div>
</form>
</body>
</html>

  示例效果如圖2所示。


圖2 應(yīng)用程序效果圖

  如圖2所示,復(fù)合控件Register在頁面中顯示了文本、文本框、按鈕等,同時,還提供了輸入驗證功能。然而,當(dāng)用戶單擊“注冊”按鈕之后,即使在用戶名和電子郵件的輸入都通過驗證的情況下,頁面仍然沒有引發(fā)相應(yīng)的事件處理程序。這是由于在本例中沒有實現(xiàn)按鈕的事件處理內(nèi)容。有關(guān)復(fù)合控件的事件實現(xiàn)將在隨后的文章中進行詳細講解。

  小結(jié)

  復(fù)合控件是通過將其他控件聚合在某一公用API下創(chuàng)建而成的控件。復(fù)合控件將保留自己子控件的活動實例,并且不僅限于呈現(xiàn)這些實例。使用復(fù)合控件可以帶來幾點好處,例如可以簡化對事件和回發(fā)的處理。然而,本文并沒有對復(fù)合控件的事件實現(xiàn)等相關(guān)內(nèi)容進行講解,請讀者繼續(xù)關(guān)注本系列的隨后文章。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
從零開始開發(fā)服務(wù)器控件
自定義控件
四種方法在PPT中插入Flash動畫
ASP.NET服務(wù)器控件開發(fā)(2)
在PowerPoint中插入視頻文件的方法
通過創(chuàng)建MOSS2007自定義字段類來實現(xiàn)和基于TREEVIEW的OU組織結(jié)構(gòu)菜單
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服