自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

ASP.NET服務(wù)器控件開(kāi)發(fā)之復(fù)合控件

開(kāi)發(fā) 后端
本文介紹了asp.net服務(wù)器控件開(kāi)發(fā)中復(fù)合控件的概念及基本功能等。

ASP.NET服務(wù)器控件:復(fù)合控件概念   

所謂復(fù)合控件:簡(jiǎn)單的理解就是將多個(gè)基本的控件組合成一個(gè)控件,從而實(shí)現(xiàn)自己想要的效果。微軟為asp.net2.0中推出的登錄控件等就是一個(gè)復(fù)合控件。從功能的實(shí)現(xiàn)上,復(fù)合式控件有點(diǎn)像用戶控件,只是一個(gè)是.ascx文件,一個(gè)是.dll文件。

呈現(xiàn)簡(jiǎn)單的復(fù)合控件:

要想呈現(xiàn)一個(gè)復(fù)合控件,需要了解以下幾個(gè)方面:

實(shí)現(xiàn)INamingContainer接口

任何實(shí)現(xiàn)該接口的控件都創(chuàng)建一個(gè)新的命名空間,在這個(gè)新的命名空間中,所有子控件 ID 屬性在整個(gè)應(yīng)用程序內(nèi)保證是唯一的。

Control.CreateChildControls 方法

由 asp.net 頁(yè)面框架調(diào)用,以通知使用基于合成的實(shí)現(xiàn)的服務(wù)器控件創(chuàng)建它們包含的任何子控件,以便為回發(fā)或呈現(xiàn)做準(zhǔn)備。 當(dāng)開(kāi)發(fā)復(fù)合服務(wù)器控件或模板服務(wù)器控件時(shí),必須重寫(xiě)此方法。重寫(xiě) CreateChildControls 方法的控件應(yīng)實(shí)現(xiàn) INamingContainer 接口以避免命名沖突。

Control.ChildControlsCreated 屬性

獲取一個(gè)值,該值指示是否已創(chuàng)建服務(wù)器控件的子控件。

Control.EnsureChildControls 方法

確定ASP.NET服務(wù)器控件是否包含子控件。如果不包含,則創(chuàng)建子控件。

下面就通過(guò)實(shí)例來(lái)呈現(xiàn)個(gè)簡(jiǎn)單的復(fù)合登陸控件:創(chuàng)建asp.net服務(wù)器控件工程。complexControl。

先來(lái)看代碼:

  1. namespace complexControl  
  2. {  
  3.     [DefaultProperty("Text")]  
  4.     [ToolboxData("<  {0}:LoginControl runat=server ButtonText='登錄' NameLabel='用戶名:' PasswordLabel='用戶密碼:'><  /{0}:LoginControl>")]  
  5.     public class LoginControl : WebControl, INamingContainer, IPostBackEventHandler  
  6.     {  
  7.         private Button _button;  
  8.         private TextBox _nameTextBox;  
  9.         private Label _nameLabel;  
  10.         private TextBox _passwordTextBox;  
  11.         private Label _passwordLabel;  
  12.         private RequiredFieldValidator _nameValidator;  
  13.         private RequiredFieldValidator _passwordValidator;  
  14.  
  15.           
  16.           
  17.         [Bindable(true),Category("Appearance"),DefaultValue(""),Description("按鈕文本")]  
  18.         public string ButtonText  
  19.         {  
  20.             get 
  21.             {  
  22.                 EnsureChildControls();//確定服務(wù)器控件是否包含子控件  
  23.                 return _button.Text;  
  24.             }  
  25.             set 
  26.             {  
  27.                 EnsureChildControls();  
  28.                 _button.Text = value;  
  29.             }  
  30.         }  
  31.  
  32.         [Bindable(true),Category("Default"),DefaultValue(""),Description("姓名")]  
  33.         public string Name  
  34.         {  
  35.             get 
  36.             {  
  37.                 EnsureChildControls();  
  38.                 return _nameTextBox.Text;  
  39.             }  
  40.             set 
  41.             {  
  42.                 EnsureChildControls();  
  43.                 _nameTextBox.Text = value;  
  44.             }  
  45.         }  
  46.  
  47.         [Bindable(true),Category("Appearance"),DefaultValue(""),Description("必須輸入姓名")]  
  48.         public string NameErrorMessage  
  49.         {  
  50.             get 
  51.             {  
  52.                 EnsureChildControls();  
  53.                 return _nameValidator.ErrorMessage;  
  54.             }  
  55.             set 
  56.             {  
  57.                 EnsureChildControls();  
  58.                 _nameValidator.ErrorMessage = value;  
  59.                 _nameValidator.ToolTip = value;  
  60.             }  
  61.         }  
  62.  
  63.         [Bindable(true),Category("Apperance"),DefaultValue(""),Description("姓名標(biāo)簽")]  
  64.         public string NameLabel  
  65.         {  
  66.             get 
  67.             {  
  68.                 EnsureChildControls();  
  69.                 return _nameLabel.Text;  
  70.             }  
  71.             set 
  72.             {  
  73.                 EnsureChildControls();  
  74.                 _nameLabel.Text = value;  
  75.  
  76.             }  
  77.         }  
  78.  
  79.         [Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]  
  80.         public string Password  
  81.         {  
  82.             get 
  83.             {  
  84.                 EnsureChildControls();  
  85.                 return _passwordTextBox.Text;  
  86.             }  
  87.         }  
  88.  
  89.         [Bindable(true),Category("Appearance"),DefaultValue(""),Description("必須輸入密碼")]  
  90.         public string PasswordErrorMessage  
  91.         {  
  92.             get 
  93.             {  
  94.                 EnsureChildControls();  
  95.                 return _passwordValidator.ErrorMessage;  
  96.             }  
  97.             set 
  98.             {  
  99.                 EnsureChildControls();  
  100.                 _passwordValidator.ErrorMessage = value;  
  101.                 _passwordValidator.ToolTip = value;  
  102.             }  
  103.         }  
  104.  
  105.         [Bindable(true),Category("Appearance"),DefaultValue(""),Description("密碼標(biāo)簽")]  
  106.         public string PasswordLabel  
  107.         {  
  108.             get 
  109.             {  
  110.                 EnsureChildControls();  
  111.                 return _passwordLabel.Text;  
  112.             }  
  113.             set 
  114.             {  
  115.                 EnsureChildControls();  
  116.                 _passwordLabel.Text = value;  
  117.  
  118.             }  
  119.         }  
  120.  
  121.         protected override void CreateChildControls()  
  122.         {  
  123.             Controls.Clear();  
  124.  
  125.             _nameLabel = new Label();  
  126.  
  127.             _nameTextBox = new TextBox();  
  128.             _nameTextBox.ID = "nameTextBox";  
  129.  
  130.             _nameValidator = new RequiredFieldValidator();  
  131.             _nameValidator.ID = "validator1";  
  132.             _nameValidator.ControlToValidate = _nameTextBox.ID;  
  133.             _nameValidator.Text = "*";  
  134.             _nameValidator.Display = ValidatorDisplay.Static;  
  135.  
  136.             _passwordLabel = new Label();  
  137.  
  138.             _passwordTextBox = new TextBox();  
  139.             _passwordTextBox.TextMode = TextBoxMode.Password;  
  140.             _passwordTextBox.ID = "passwordTextBox";  
  141.  
  142.             _passwordValidator = new RequiredFieldValidator();  
  143.             _passwordValidator.ID = "validator2";  
  144.             _passwordValidator.ControlToValidate = _passwordTextBox.ID;  
  145.             _passwordValidator.Text = "*";  
  146.             _passwordValidator.Display = ValidatorDisplay.Static;  
  147.  
  148.             _button = new Button();  
  149.             _button.ID = "button1";  
  150.  
  151.             //_button.Click += new EventHandler(_button_Click);  
  152.             _button.CommandName = "ClickLogin";  
  153.             this.Controls.Add(_nameLabel);  
  154.             this.Controls.Add(_nameTextBox);  
  155.             this.Controls.Add(_nameValidator);  
  156.             this.Controls.Add(_passwordLabel);  
  157.             this.Controls.Add(_passwordTextBox);  
  158.             this.Controls.Add(_passwordValidator);  
  159.             this.Controls.Add(_button);  
  160.               
  161.         }  
  162.  
  163.         protected override void Render(HtmlTextWriter writer)  
  164.         {  
  165.             AddAttributesToRender(writer);  
  166.  
  167.             writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding,  
  168.                 "1"false);  
  169.             writer.RenderBeginTag(HtmlTextWriterTag.Table);  
  170.  
  171.             writer.RenderBeginTag(HtmlTextWriterTag.Tr);  
  172.             writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  173.             _nameLabel.RenderControl(writer);  
  174.             writer.RenderEndTag();  // Td  
  175.             writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  176.             _nameTextBox.RenderControl(writer);  
  177.             writer.RenderEndTag();  // Td  
  178.             writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  179.             _nameValidator.RenderControl(writer);  
  180.             writer.RenderEndTag();  // Td  
  181.             writer.RenderEndTag();  // Tr  
  182.  
  183.             writer.RenderBeginTag(HtmlTextWriterTag.Tr);  
  184.             writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  185.             _passwordLabel.RenderControl(writer);  
  186.             writer.RenderEndTag();  // Td  
  187.             writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  188.             _passwordTextBox.RenderControl(writer);  
  189.             writer.RenderEndTag();  // Td  
  190.             writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  191.             _passwordValidator.RenderControl(writer);  
  192.             writer.RenderEndTag();  // Td  
  193.             writer.RenderEndTag();  // Tr  
  194.  
  195.             writer.RenderBeginTag(HtmlTextWriterTag.Tr);  
  196.             writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");  
  197.             writer.AddAttribute(HtmlTextWriterAttribute.Align, "right");  
  198.             writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  199.             _button.RenderControl(writer);  
  200.             //writer.AddAttribute(HtmlTextWriterAttribute, Page.GetPostBackEventReference(_button));  
  201.             writer.RenderEndTag();  // Td  
  202.             writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  203.             writer.Write(" ");  
  204.             writer.RenderEndTag();  // Td  
  205.             writer.RenderEndTag();  // Tr  
  206.  
  207.             writer.RenderEndTag();  // Table  
  208.         }  
  209.  
  210.  
  211.     }  
  212. }  
  213.  

首先我們實(shí)例化了幾個(gè)現(xiàn)有控件的對(duì)象。然后聲明了一大堆的屬性,要注意的:和平時(shí)定義屬性不同,我們?cè)诿恳粋€(gè)屬性中都添加了EnsureChildControls ()方法。其他的沒(méi)有任何變化,和一般的屬性聲明一樣。

接下來(lái)我們從寫(xiě)了重要的CreateChildControls()。將前面聲明好的實(shí)例化控件對(duì)象添加到controlcollection中。融合成一個(gè)控件。

***重寫(xiě)控件顯示的Render()方法。生成登錄窗體的樣式。效果如下:

 這樣,我們基本上就完成了復(fù)合控件的基本顯示功能。

復(fù)合控件的事件處理

由于復(fù)合控件中包含子控件,這就使得復(fù)合控件的事件處理變得復(fù)雜起來(lái)。由于不允許開(kāi)發(fā)人員直接訪問(wèn)子控件,如果子控件的事件不能作為***事件引發(fā),那么將無(wú)法實(shí)現(xiàn)子控件的事件處理。

我們可以以兩種形式來(lái)完成事件的處理:一是直接將事件封裝到控件中,顯然靈活性很差。二就是自定義事件,用戶來(lái)完成事件的代碼。

***種情況比較簡(jiǎn)單:就是在創(chuàng)建我們得控件時(shí),將要實(shí)現(xiàn)的效果直接封裝在dll中。這里就不做說(shuō)明了。

但是往往控件觸發(fā)時(shí),我們想做自己的事情,這就是第二種情況的事件處理。這就需要把事件交給主控件,由主控件統(tǒng)一暴露事件,這樣開(kāi)發(fā)人員在使用控件時(shí)僅需要為主控件注冊(cè)事件即可,剩下的由主控件負(fù)責(zé)引發(fā)子控件的事件或執(zhí)行子控件的某些功能,這里就涉及主控件與其子控件的事件銜接問(wèn)題,復(fù)合控件的這種事件處理,主要是實(shí)現(xiàn)子控件事件上傳的過(guò)程。一般分為:包含法和冒泡法兩種處理方式。

包含法:

基本思想是:通過(guò)在子控件的事件處理程序中調(diào)用復(fù)合控件的頂層事件處理程序,以完成子控件的事件上傳。 在CreateChildControls方法中,為子控件添加事件處理程序。

接著上面登陸控件的例子,來(lái)實(shí)現(xiàn)下登錄按鈕的事件。

首先在CreateChildControls()中,為_(kāi)button添加單擊事件。(其他代碼略)

  1. _button = new Button();  
  2.             _button.ID = "button1";  
  3.  
  4.             _button.Click += new EventHandler(_button_Click);  

然后創(chuàng)建主控件對(duì)外的處理函數(shù):

  1. void _button_Click(Object source, EventArgs e)  
  2.         {  
  3.             OnClickLogin(EventArgs.Empty);  
  4.         }  
  5.  
  6.  
  7.         private static readonly object EventClickLogin = new object();  
  8.  
  9.         public event EventHandler ClickLogin  
  10.         {  
  11.             add  
  12.             {  
  13.                 Events.AddHandler(EventClickLogin, value);  
  14.             }  
  15.             remove  
  16.             {  
  17.                 Events.RemoveHandler(EventClickLogin, value);  
  18.             }  
  19.         }  
  20.  
  21.         protected virtual void OnClickLogin(EventArgs e)  
  22.         {  
  23.             EventHandler clickLoginHandler = (EventHandler)Events[EventClickLogin];  
  24.             if (clickLoginHandler != null)  
  25.             {  
  26.                 clickLoginHandler(this, e);  
  27.             }  
  28.         }  
  29.  
  30.         public void RaisePostBackEvent(string eventArgument)//處理回發(fā)事件  
  31.         {  
  32.             OnClickLogin(new EventArgs());  
  33.         }  
  34.  

事件的詳細(xì)處理請(qǐng)參看上一篇。這里要說(shuō)明的是:在按鈕的單擊事件處理函數(shù)中,將我們?cè)谥骺丶新暶鞯氖录魅脒M(jìn)去:

  1. void _button_Click(Object source, EventArgs e)  
  2. {  
  3.      OnClickLogin(EventArgs.Empty);  
  4. }  
  5.  

這樣,我們就實(shí)現(xiàn)了***種方法。測(cè)試一下:

  1. protected void LoginControl1_ClickLogin1(object sender, EventArgs e)  
  2. {  
  3.      Label1.Text = "sssssssssssssssqwwssss";  
  4. }  

單擊按鈕,將觸發(fā)上面的事件。

冒泡法:

基本思想:使用asp.net 2.0框架提供的事件上傳機(jī)制。這種機(jī)制允許子控件將事件沿其包容層次結(jié)構(gòu)向上傳播到合適的位置引發(fā),并且允許將事件處理程序附加到原始控件以及公開(kāi)冒泡的事件的控件上。

冒泡法的實(shí)現(xiàn),使用Control基類中專門用于事件上傳的兩個(gè)方法:OnBubbleEvent和RaiseBubbleEvent。OnBubbleEvent方法用于確定子控件的事件是否沿復(fù)合控件層次結(jié)構(gòu)向上傳遞。在該方法中,參數(shù)source表示事件源,參數(shù)args表示包含事件數(shù)據(jù)的EventArgs對(duì)象。如果子控件的事件向上傳遞,則為true;否則為false。默認(rèn)值為false。RaiseBubbleEvent方法用于將所有事件源及其信息分配給控件的父級(jí),并且不能被重寫(xiě)。盡管無(wú)法重寫(xiě)此方法,但創(chuàng)作的控件可以通過(guò)重寫(xiě) OnBubbleEvent 方法處理或引發(fā)冒泡事件。

還是通過(guò)例子說(shuō)明一下:

首先在CreateChildControls()中聲明commandname屬性。

_button.CommandName = "ClickLogin";

然后定義事件:

      

  1. private static readonly object EventClickLogin = new object();  
  2.  
  3.         public event EventHandler ClickLogin  
  4.         {  
  5.             add  
  6.             {  
  7.                 Events.AddHandler(EventClickLogin, value);  
  8.             }  
  9.             remove  
  10.             {  
  11.                 Events.RemoveHandler(EventClickLogin, value);  
  12.             }  
  13.         }  
  14.  
  15.         protected virtual void OnClickLogin(EventArgs e)  
  16.         {  
  17.             EventHandler clickLoginHandler = (EventHandler)Events[EventClickLogin];  
  18.             if (clickLoginHandler != null)  
  19.             {  
  20.                 clickLoginHandler(this, e);  
  21.             }  
  22.         }  
  23.  
  24.         protected override bool OnBubbleEvent(object source, EventArgs e)  
  25.         {  
  26.             bool handled = false;  
  27.             if (e is CommandEventArgs)  
  28.             {  
  29.                 CommandEventArgs ce = (CommandEventArgs)e;  
  30.                 if (ce.CommandName == "ClickLogin")  
  31.                 {  
  32.                     OnClickLogin(EventArgs.Empty);  
  33.                     handled = true;  
  34.                 }  
  35.             }  
  36.             return handled;  
  37.         }  
  38.  
  39.         public void RaisePostBackEvent(string eventArgument)//處理回發(fā)事件  
  40.         {  
  41.             OnClickLogin(new EventArgs());  
  42.         }  
  43.  

里主要要注意的是:OnBubbleEvent()的使用。通過(guò)CommandName的值,來(lái)相應(yīng)的找到處理事件的控件。

測(cè)試一下:

  1. protected void LoginControl1_ClickLogin1(object sender, EventArgs e)  
  2. {  
  3.      Label1.Text = "sssssssssssssssqwwssss";  
  4. }  

單擊按鈕,將觸發(fā)上面的事件。

小結(jié):這樣,ASP.NET服務(wù)器控件中復(fù)合控件的基本使用就介紹完了,不是很難。只要記住特定的一些東西,就可以很容易的創(chuàng)造出復(fù)合控件。值得大家注意的是復(fù)合控件中事件的兩種處理方法。希望對(duì)新手有幫助。

【編輯推薦】

  1. ASP.NET中的“三層結(jié)構(gòu)”簡(jiǎn)介
  2. ASP.NET中優(yōu)化性能方法26則
  3. 比較ASP.NET中的html控件和web控件
  4. ASP.NET中的對(duì)象描述
  5. 在ASP.NET中使用Session常見(jiàn)問(wèn)題總結(jié)
責(zé)任編輯:book05 來(lái)源: cnblogs
相關(guān)推薦

2009-08-06 18:18:27

ASP.NET控件開(kāi)發(fā)ASP.NET復(fù)合控件

2009-08-06 18:32:00

ASP.NET控件開(kāi)發(fā)ASP.NET復(fù)合控件

2009-08-04 13:10:05

ASP.NET服務(wù)器控

2009-08-05 17:11:51

ASP.NET控件開(kāi)發(fā)ASP.NET服務(wù)器控

2009-08-10 14:25:33

ASP.NET服務(wù)器控

2009-08-03 18:00:00

ASP.NET服務(wù)器控

2011-07-12 15:17:02

ASP.net服務(wù)器控件

2009-08-04 17:18:37

2009-08-03 15:43:22

asp.net控件

2009-08-10 14:08:15

ASP.NET服務(wù)器控ASP.NET組件設(shè)計(jì)

2009-08-07 15:32:28

ASP.NET復(fù)合控件

2009-08-07 13:56:46

ASP.NET控件開(kāi)發(fā)

2009-08-07 15:40:10

CompositeCo復(fù)合控件

2009-08-06 14:16:04

ASP.NET服務(wù)器控

2009-08-06 10:49:45

ASP.NET服務(wù)器控

2009-08-04 13:39:43

ASP.NET 2.0

2009-08-04 15:13:38

2009-07-27 12:56:27

控件CheckBoxLASP.NET服務(wù)器

2009-08-04 10:43:59

ASP.NET控件開(kāi)發(fā)

2009-08-07 15:45:26

ASP.NET復(fù)合控件數(shù)據(jù)綁定
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)