七:理解控件的运行机制(例:基于CompositeControl命名空间的控件)

组合控件与WebControl控件的事件和属性相差不大
组合控件,顾名思义就是把一些控件组合起来形成一个控件
这个控件将包含这些控件称为他的子控件

CompositeControl类实现了INameContainer接口
这样使得复合控件下的子控件都根据各自的层级关系生成唯一的客户端标识
不至于产生重复的ID

组合控件比较重要的方法是:
1.EnsureChildControls
此方法判断属性ChildControlsCreated是否为true
如果不是将执行下面的事件
2.CreateChildControls
此方法创建并生成组合控件下的所有子控件
此方法执行完后应该设置ChildControlsCreated属性为true
避免重复调用CreateChildControls

我写了一个生成组合控件的类
但是这个类里没有对子控件进行组织

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.ComponentModel;

namespace hellowControl
{
    
public class HellowControl:CompositeControl
    {
        
//继承的类可以重写protected变量
        protected TextBox _input;
        
protected RegularExpressionValidator _regvalidator;
        
protected RequiredFieldValidator _rqrvalidatator;
        
protected override HtmlTextWriterTag TagKey
        {
            
get
            {
                
return HtmlTextWriterTag.Div;
            }
        }
        
//在此方法中创建子控件
        protected override void CreateChildControls()
        {
            
//必须先清除控件
            
//假设一个请求就是一个线程,那么这个线程创建了子控件
            Controls.Clear();
            _input 
= new TextBox();
            _input.ID 
= "mytxt";

            _rqrvalidatator 
= new RequiredFieldValidator();
            _rqrvalidatator.ID 
= "myrequire";
            _rqrvalidatator.ErrorMessage 
= "内容为空";
            _rqrvalidatator.Display 
= ValidatorDisplay.Dynamic;
            _rqrvalidatator.ControlToValidate 
= _input.ID;

            _regvalidator 
= new RegularExpressionValidator();
            _regvalidator.ID 
= "myExpression";
            _regvalidator.Display 
= ValidatorDisplay.Dynamic;
            _regvalidator.ErrorMessage 
= "格式错误";
            _regvalidator.ValidationExpression 
= @"\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*";
            _regvalidator.ControlToValidate 
= _input.ID;

            
this.Controls.Add(_input);
            
this.Controls.Add(_rqrvalidatator);
            
this.Controls.Add(_regvalidator);

            
//确认子控件已经创建,避免重复创建
            ChildControlsCreated = true;
        }
    }    
}
我重写了这个类
在我重写这个类的子类中,我对上面创建的子控件进行了组织
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;

namespace hellowControl
{
    
public class SunHellowControl : HellowControl
    {
        
protected override System.Web.UI.HtmlTextWriterTag TagKey
        {
            
get
            {
                
return HtmlTextWriterTag.Table;
            }
        }
        
//重写control类的RenderContents来组织父类中创建的控件
        protected override void RenderContents(HtmlTextWriter writer)
        {
            EnsureChildControls();
//如果ChildControlsCreated不为true则调用CreateChildControls
            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
            writer.AddAttribute(HtmlTextWriterAttribute.Align, 
"center");
            writer.AddAttribute(HtmlTextWriterAttribute.Width, 
"360px");
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            writer.Write(
"your name:");
            writer.RenderEndTag();

            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            _input.RenderControl(writer);
//输出第一子个控件
            writer.RenderEndTag();

            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            _rqrvalidatator.RenderControl(writer);
            _regvalidator.RenderControl(writer);
            writer.RenderEndTag();

            writer.RenderEndTag();

        }
    }
}
这样控件就按我们的要求输出了

我发现我的工具箱针对这个控件的图标是一个齿轮
我想把他换成我自己的个性化ICO图标
1:做一个16*16象素和控件同名的bmp图片,放在和控件相同的目录下
2:属性设置成"嵌入的资源",重新选择项...

如果想让控件拖到aspx页面上去的时候是这样的形式
<asp:SunHellowControl ID="SunHellowControl1" runat="server" />
那么我们可以在控件的AssemblyInfo.cs文件中
插入
[assembly: TagPrefix("hellowControl", "asp")]
第一个参数是类库的名称空间,第二个就不用说了
注意AssemblyInfo.cs要引用System.Web.UI名称空间
posted @ 2009-01-20 19:05  liulun  阅读(449)  评论(0编辑  收藏  举报