ASP.NET控件开发基础之复合控件浅析

开发 后端
ASP.NET控件开发基础之复合控件是什么呢?本文向你介绍了ASP.NET复合控件的概念和ASP.NET复合控件的实现方法。

这次我们要讨论的是ASP.NET控件开发基础中ASP.NET复合控件.本文无法一步到位完整介绍,因为讨论的篇幅比较大,所以分两次写,这次就先讲些基本概念吧,剩着的下次写.

好象复合控件网上已经有很多教程了,相信大家也看过很多.如果看过的朋友就当我再废话一便,没看过的朋友希望能给你带来帮助.

ASP.NET控件开发基础呢首先我们来认识下ASP.NET控件开发基础中ASP.NET复合控件的情况:

1.ASP.NET复合控件概念

复合控件跟用户控件有很多相似点,***不同就是用户控件后缀为ascx,而复合控件编译后则为dll文件,还可以分发给大家使用,另外其他不同点还请参考MSDN吧,说白了,复合控件灵活性更大.

2.ASP.NET复合控件的呈现

(1)一般控件的呈现

从***篇到第六篇为止,我们用以呈现控件的方法介绍过的有Render方法和RenderContents方法.回顾一下吧,看以下其中的一小段代码.

示例一

  1.           public override void Render(HtmlTextWriter writer)  
  2.       {  
  3.  ..  
  4.               writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  5.           writer.AddAttribute(HtmlTextWriterAttribute.Name, "CreditCardNo");  
  6.           writer.AddAttribute(HtmlTextWriterAttribute.Id, "CreditCardNo");  
  7.           writer.AddAttribute(HtmlTextWriterAttribute.Type, "text");  
  8.           writer.RenderBeginTag(HtmlTextWriterTag.Input);  
  9.           writer.RenderEndTag();  
  10.           writer.RenderEndTag();  
  11.             

以前我们所做的控件都是上面这样的写法.我们可以认为在Render方法实现了以下两个功能.

一.标签布局(如td标签,让控件呈现的好看点-_-)

二.呈现的标签(如input标签)

(2)ASP.NET复合控件的呈现方法

我们知道asp.net控件库里面已经提供给了我们像TextBox这样的控件了,就如组装电脑一下,你可以组装.net提供你现有的控件,然后重新拼凑成一个新的控件,这样便成了复合控件.但其呈现方法却又不同.

复合控件是以包含子控件的形式呈现的,具体的呈现交给子控件自己去做,因为子控件自身都已经实现了其呈现方法(每个控件都继承自Control类).假设你还不明白就看下面的图吧.

LabelTextBox1为复合控件,LabelTextBox2则不是.两者的呈现方式是不同的.具体实现方法请看下文

复合控件实现方法 

3.完成基本ASP.NET复合控件基本呈现

(1)首先你要熟悉以下的属性和方法

Control.CreateChildControls 方法用于创建子控件

Control.EnsureChildControls 方法用于确认是否已创建子控件,如果未创建完成的话则调用CreateChildControls 方法创建子控件

Control.ChildControlsCreated 属性 获取一个值,是否已创建子控件

(2)了解并实现INamingContainer接口

用户控件UserControl类则继承了INamingContainer接口,确包保子控件具有唯一的ID名称,那复合控件也需要实现这个接口达到一样的目的,这个是值得注意的地方.

复合控件以类撰写的方法来添加控件即CreateChildControls 方法,而非在Render方法中以下面方式实现
writer.RenderBeginTag(HtmlTextWriterTag.Input);

在复合控件里Render方法的作用只是为我们提供布局的需要

下面看一个完成的代码,以微软的示例为例子.一个登录控件.

先看效果如下

控件效果 

再来看看代码吧,其实以下代码并不复杂.只不过属性多一点而已.看下面步骤


先定义控件类很简单.

然后定义几个公开的属性,注意每个属性都有一个EnsureChildControls 方法,因为返回的都是控件的属性,而我们又无法判断控件是否已经创建,所以须用此方法确保已创建控件,然后才可以使用其属性.

再通过类撰写方法CreateChildControls来添加子控件.

***在Render方法实现布局以及用控件的RenderControl方法呈现自身标签内容,***还要注意Render方法中的AddAttributesToRender方法,以前已经解释过这个方法的用处了,不调用此方法就无福享用WebControl类提供给你诸多样式属性了

以下注意的地方均以红字标出.说了一大堆了,看看下面代码,你明白了没?

示例二

  1. public class CompositeLogin : WebControl, INamingContainer  
  2.    {  
  3.  
  4.        private Button _button;  
  5.        private TextBox _nameTextBox;  
  6.        private Label _nameLabel;  
  7.        private TextBox _passwordTextBox;  
  8.        private Label _passwordLabel;  
  9.        private RequiredFieldValidator _nameValidator;  
  10.        private RequiredFieldValidator _passwordValidator;  
  11.  
  12.        属性#region 属性  
  13.        [  
  14.        Bindable(true),  
  15.        Category("Appearance"),  
  16.        DefaultValue(""),  
  17.        Description("按钮文本")  
  18.        ]  
  19.        public string ButtonText  
  20.        {  
  21.            get 
  22.            {  
  23.                EnsureChildControls();  
  24.                return _button.Text;  
  25.            }  
  26.            set 
  27.            {  
  28.                EnsureChildControls();  
  29.                _button.Text = value;  
  30.            }  
  31.        }  
  32.  
  33.        [  
  34.        Bindable(true),  
  35.        Category("Default"),  
  36.        DefaultValue(""),  
  37.        Description("姓名")  
  38.        ]  
  39.        public string Name  
  40.        {  
  41.            get 
  42.            {  
  43.                EnsureChildControls();  
  44.                return _nameTextBox.Text;  
  45.            }  
  46.            set 
  47.            {  
  48.                EnsureChildControls();  
  49.                _nameTextBox.Text = value;  
  50.            }  
  51.        }  
  52.  
  53.        [  
  54.        Bindable(true),  
  55.        Category("Appearance"),  
  56.        DefaultValue(""),  
  57.        Description(  
  58.            "必须输入姓名")  
  59.        ]  
  60.        public string NameErrorMessage  
  61.        {  
  62.            get 
  63.            {  
  64.                EnsureChildControls();  
  65.                return _nameValidator.ErrorMessage;  
  66.            }  
  67.            set 
  68.            {  
  69.                EnsureChildControls();  
  70.                _nameValidator.ErrorMessage = value;  
  71.                _nameValidator.ToolTip = value;  
  72.            }  
  73.        }  
  74.  
  75.        [  
  76.        Bindable(true),  
  77.        Category("Apperance"),  
  78.        DefaultValue(""),  
  79.        Description("姓名标签")  
  80.        ]  
  81.        public string NameLabel  
  82.        {  
  83.            get 
  84.            {  
  85.                EnsureChildControls();  
  86.                return _nameLabel.Text;  
  87.            }  
  88.            set 
  89.            {  
  90.                EnsureChildControls();  
  91.                _nameLabel.Text = value;  
  92.  
  93.            }  
  94.        }  
  95.  
  96.        [  
  97.        Browsable(false),  
  98.        DesignerSerializationVisibility(  
  99.            DesignerSerializationVisibility.Hidden)  
  100.        ]  
  101.        public string Password  
  102.        {  
  103.            get 
  104.            {  
  105.                EnsureChildControls();  
  106.                return _passwordTextBox.Text;  
  107.            }  
  108.        }  
  109.  
  110.        [  
  111.        Bindable(true),  
  112.        Category("Appearance"),  
  113.        DefaultValue(""),  
  114.        Description(  
  115.            "必须输入密码")  
  116.        ]  
  117.        public string PasswordErrorMessage  
  118.        {  
  119.            get 
  120.            {  
  121.                EnsureChildControls();  
  122.                return _passwordValidator.ErrorMessage;  
  123.            }  
  124.            set 
  125.            {  
  126.                EnsureChildControls();  
  127.                _passwordValidator.ErrorMessage = value;  
  128.                _passwordValidator.ToolTip = value;  
  129.            }  
  130.        }  
  131.  
  132.        [  
  133.        Bindable(true),  
  134.        Category("Appearance"),  
  135.        DefaultValue(""),  
  136.        Description("密码标签")  
  137.        ]  
  138.        public string PasswordLabel  
  139.        {  
  140.            get 
  141.            {  
  142.                EnsureChildControls();  
  143.                return _passwordLabel.Text;  
  144.            }  
  145.            set 
  146.            {  
  147.                EnsureChildControls();  
  148.                _passwordLabel.Text = value;  
  149.  
  150.            }  
  151.        }  
  152.        #endregion Properties delegated to child controls  
  153.  
  154.        方法#region 方法  
  155.        //撰写  
  156.        protected override void CreateChildControls()  
  157.        {  
  158.            Controls.Clear();  
  159.  
  160.            _nameLabel = new Label();  
  161.  
  162.            _nameTextBox = new TextBox();  
  163.            _nameTextBox.ID = "nameTextBox";  
  164.  
  165.            _nameValidator = new RequiredFieldValidator();  
  166.            _nameValidator.ID = "validator1";  
  167.            _nameValidator.ControlToValidate = _nameTextBox.ID;  
  168.            _nameValidator.Text = "*";  
  169.            _nameValidator.Display = ValidatorDisplay.Static;  
  170.  
  171.            _passwordLabel = new Label();  
  172.  
  173.            _passwordTextBox = new TextBox();  
  174.            _passwordTextBox.TextMode = TextBoxMode.Password;  
  175.            _passwordTextBox.ID = "passwordTextBox";  
  176.  
  177.            _passwordValidator = new RequiredFieldValidator();  
  178.            _passwordValidator.ID = "validator2";  
  179.            _passwordValidator.ControlToValidate = _passwordTextBox.ID;  
  180.            _passwordValidator.Text = "*";  
  181.            _passwordValidator.Display = ValidatorDisplay.Static;  
  182.  
  183.            _button = new Button();  
  184.            _button.ID = "button1";  
  185.  
  186.            this.Controls.Add(_nameLabel);  
  187.            this.Controls.Add(_nameTextBox);  
  188.            this.Controls.Add(_nameValidator);  
  189.            this.Controls.Add(_passwordLabel);  
  190.            this.Controls.Add(_passwordTextBox);  
  191.            this.Controls.Add(_passwordValidator);  
  192.            this.Controls.Add(_button);  
  193.        }  
  194.  
  195.        //布局  
  196.        protected override void Render(HtmlTextWriter writer)  
  197.        {  
  198.            AddAttributesToRender(writer);  
  199.  
  200.            writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding,  
  201.                "1"false);  
  202.            writer.RenderBeginTag(HtmlTextWriterTag.Table);  
  203.  
  204.            writer.RenderBeginTag(HtmlTextWriterTag.Tr);  
  205.            writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  206.            _nameLabel.RenderControl(writer);  
  207.            writer.RenderEndTag();  // Td  
  208.            writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  209.            _nameTextBox.RenderControl(writer);  
  210.            writer.RenderEndTag();  // Td  
  211.            writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  212.            _nameValidator.RenderControl(writer);  
  213.            writer.RenderEndTag();  // Td  
  214.            writer.RenderEndTag();  // Tr  
  215.  
  216.            writer.RenderBeginTag(HtmlTextWriterTag.Tr);  
  217.            writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  218.            _passwordLabel.RenderControl(writer);  
  219.            writer.RenderEndTag();  // Td  
  220.            writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  221.            _passwordTextBox.RenderControl(writer);  
  222.            writer.RenderEndTag();  // Td  
  223.            writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  224.            _passwordValidator.RenderControl(writer);  
  225.            writer.RenderEndTag();  // Td  
  226.            writer.RenderEndTag();  // Tr  
  227.  
  228.            writer.RenderBeginTag(HtmlTextWriterTag.Tr);  
  229.            writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2");  
  230.            writer.AddAttribute(HtmlTextWriterAttribute.Align, "right");  
  231.            writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  232.            _button.RenderControl(writer);  
  233.            writer.RenderEndTag();  // Td  
  234.            writer.RenderBeginTag(HtmlTextWriterTag.Td);  
  235.            writer.Write(" ");  
  236.            writer.RenderEndTag();  // Td  
  237.            writer.RenderEndTag();  // Tr  
  238.  
  239.            writer.RenderEndTag();  // Table  
  240.        }  
  241.        #endregion Overriden methods  
  242.    } 

4.控件状态以及性能方面的选择

上面的例子你会发现,再点击按钮以后,textbox值状态被保存了下来,还记得以前以Render方法直接呈现input标签的控件吗?在点击按钮以后textbox值状态是无法保存的.

第三篇的时候,我们讨论了数据回传的一些知识,我们也定义了一个textbox控件,在点击按钮以后,可以***的保存其值状态.

至于原因,还请大家参考下文,作者已经分析的很清楚了.

ASP.NET控件开发速成教程:生成复合控件

关于性能方面的问题,以下引用MSDN,具体大家还须参考MSDN

虽然创作复合控件相对比较容易,但是由于在撰写时必须创建子控件,所以会出现性能系统开销。如果您想优化控件的性能,可以通过重写 Render 方法,自己实现呈现逻辑。另外,必须实现控件所需的任何回发数据处理和回发事件处理。

本来想一起把事件处理和样式也写完了,但想写好篇幅太多了,这次就先写到这里吧,因为想把自己心里的意思表达明白还真的需要费一定时间去想的.下次我们继续讨论复合控件的事件和样式。

ASP.NET控件开发基础之ASP.NET复合控件的基本情况就向你介绍到这里,希望对你了解ASP.NET复合控件有所帮助。

【编辑推荐】

  1. ASP.NET服务器控件之RenderContents简介
  2. ASP.NET服务器控件之RenderContents应用示例
  3. ASP.NET控件开发基础之RenderContents使用浅析
  4. ASP.NET自定义控件属性浅析
  5. ASP.NET控件开发基础之自定义控件样式属性浅析
责任编辑:仲衡 来源: 博客园
相关推荐

2009-08-06 18:32:00

ASP.NET控件开发ASP.NET复合控件

2009-07-30 16:52:38

复合控件ASP.NET服务器控

2009-08-07 15:24:16

ASP.NET模板控件

2009-08-06 09:18:01

ASP.NET自定义控ASP.NET控件开发

2009-08-06 13:08:23

ASP.NET控件开发

2009-08-07 15:34:15

ASP.NET数据绑定

2009-07-27 17:25:53

ASP.NET验证控件

2009-08-07 14:05:21

ASP.NET控件

2009-08-06 17:52:45

ASP.NET控件开发自定义控件

2009-08-06 15:21:45

ASP.NET控件开发RenderConte

2009-07-28 09:32:41

ASP.NET自定义控

2009-08-07 15:40:10

CompositeCo复合控件

2009-08-07 15:32:28

ASP.NET复合控件

2009-08-07 17:49:44

控件设计器

2009-08-07 10:34:56

ASP.NET控件开发

2009-08-07 13:31:41

ASP.NET控件开发

2009-08-07 09:33:23

ASP.NET控件开发

2009-07-28 16:21:03

Asp.net AjaAutoComplet

2009-08-05 17:11:51

ASP.NET控件开发ASP.NET服务器控

2009-08-04 10:43:59

ASP.NET控件开发
点赞
收藏

51CTO技术栈公众号