.net控件开发之复合控件

【内容导航】
  • 第1页:概念
  • 第2页:继承INamingContainer接口
  • 第3页:例子

    复合控件是什么呢?说白了就是包含了两个或多个已存在控件的集合,复用现有的那些控件。并且来进行生成,回传处理等等。例如,复合控件就像一个团队,它包括了各种各样的人才。通过这个团队来完成所需任务(这里的生成,回传处理等)

    复合控件是一个功能强大的工具,可以生成丰富复杂的组件,这些组件产生自活动对象的相互作用而不是某些字符串生成器对象的标记输出。复合控件以构成控件树 的形式呈现,每个构成控件都有其自己的生命周期和事件,并且所有构成控件都联合构成一个全新的 API,并按需要尽可能地抽象化

   实现目的:简化控件开发,通过复合在一起,可以把许多任务委托到子控件上。就用上一例说事吧,组合团队的目的是干什么,大家都知道是为了高效的工作,集大 家之所长,复合控件也如此,提高开发效率,将各个子控件的能力综合发挥。例如说。当控件包含处理回传数据控件textbox时,可以不必实现 IPostBackDataHandler接口,同理,包含Button时,不必实现IPostBackEventHandler接口。

    实现复合控件的要点:复合控件可以派生自control类或WebControl类,但在.net2.0中通常派生于CompositeControl 类,这与.net 1.x环境下开发复合控件有些不同,在.net 1.x中,复合控件必须实现INamingContainer接口,CompositeControl类表述:

public abstract class CompositeControl : WebControl, INamingContainer, ICompositeControlDesignerAccessor 
{ 

}

   CompositeControl类是一个抽象类,为自定义控件提供命名容器和控件设计器功能,该自定义包含全部子控件或使用其他控件功能。

   此类实现了INamingContainer接口,该接口没有任何方法,为什么要继承此接口呢? 

   答案是:它会使页面在控件下创建一个新的命保范围,当实现该接口时,控件包含的任何子控件的表示符,保证页面中确定是唯一的。例如,如果页面上有两个gridview控件,第一个gridview的子控件和第二个gridview子控件会有不同的唯一标表示符。

    事例:就如我们团队有一个团队号(001)[复合控件ID],个人标识(suiqi)[指子控件ID],当我们在团队的标识通常为001-suiqi

   开发复合控件不得不去说说两个方法,一个是CreateChildControls方法,一个是EnsureChildControls方法。

    先说一下CreateChildControls方法:CreateChildControls方法来对子控件进行实例化、初始化、并把这些子控件添加到控件树中.

    但一定不能在构造器或OnInit方法中执行该逻辑. 必须在CreateChildControls方法中创建子控件,而不是在诸如实例化或初始化这样的特定阶段创建,这样可以在控件生命周期中任何需要的时 候来创建子控件.当创建一个复合控件且由其子控件来处理回传数据时,这样做特别重要.

【内容导航】

  • 第1页:概念
  • 第2页:继承INamingContainer接口
  • 第3页:例子

    CompositeControl类是一个抽象类,为自定义控件提供命名容器和控件设计器功能,该自定义包含全部子控件或使用其他控件功能。

    此类实现了INamingContainer接口,该接口没有任何方法,为什么要继承此接口呢?

    答案是:它会使页面在控件下创建一个新的命保范围,当实现该接口时,控件包含的任何子控件的表示符,保证页面中确定是唯一的。例如,如果页面上有两个gridview控件,第一个gridview的子控件和第二个gridview子控件会有不同的唯一标表示符。

    事例:就如我们团队有一个团队号(001)[复合控件ID],个人标识(suiqi)[指子控件ID],当我们在团队的标识通常为001-suiqi

    开发复合控件不得不去说说两个方法,一个是CreateChildControls方法,一个是EnsureChildControls方法。

    先说一下CreateChildControls方法:CreateChildControls方法来对子控件进行实例化、初始化、并把这些子控件添加到控件树中.

    但一定不能在构造器或OnInit方法中执行该逻辑. 必须在CreateChildControls方法中创建子控件,而不是在诸如实例化或初始化这样的特定阶段创建,这样可以在控件生命周期中任何需要的时 候来创建子控件.当创建一个复合控件且由其子控件来处理回传数据时,这样做特别重要.

    再详解一下EnsureChildControls方法。该方法为了确保子控件在代码访问它们之前创建好了,该方法来创建军子控件,控件实现中的任何需要 访问子控件代码必须先调用EnsureChildControls方法,例如,页面用来定位子控件的FindControl方法的默认实现,就先调用了 EnsureChildControls方法.注意,如果子控件没有在控件生命周期中的预先成阶段之前被创建,那么它们会在这个时候根据要求创建.这是因 为在PreRender方法的默认实现中调用了所有其Visible属性值为true的控件的EnsureChildcontrols方法。 

   我们知道它的作用,但还要了解为什么,什么时候调用EnsureChildControls的。

    什么时候被调用:在PreRender过程中页面会自动调用EnsureChildControls,这个方法就会自动调用CreateChildControls方法重新建立控件内容。

【内容导航】

  • 第1页:概念
  • 第2页:继承INamingContainer接口
  • 第3页:例子

   我们先举一个例一个,假如我们要开发一个ShowList类,它有一个字串符属性Text.我们在ShowList类中添加这样一个属性ShowTitle

Private ShowList _sl; 

Public string ShowTitle 
{ 
	get{ return _sl.Text;} 
	set{ _sl.Text=value}
}

    当我们在CreateChildControls时实例化一个_sl时,这个代码将抛出空指针异常,这个问题是我们在设计器试图设置ShowTitle值引起的。

<Yourcontrol runat=server id="newcontrol" ShowTitle="this will cause a null reference"/>

    在设计器中设置属性将在运行时被设置,也在调用CreateChildControls方法之前被调用,如果某些属性在你调用CreateChildControl之前被设置,在.net引擎将实现如下代码:

YourControl newControl=new YourControl(); 

Newcontrol.ShowTitle="this will cause a null reference"; 

ParentControl.Controls.Add(newControl);

    在创建子控件时,任何时候被初始化,你应该在你的属性访问器中加入一条EnsureChildControls.还可以这样做:

Private ShowList _sl=new ShowList(); 

Public string ShowTitle 
{ 
	get{ return _sl.Text;} 
	set{ _sl.Text=value} 
}

    如果你在CreateChildControls方法,设置ShowTitle值时,这个值将有一个默认的Text 值,当创建一个控件时,加上EnsureChildControls() 确保其被创建

Private ShowList _sl; 
Public string ShowTitle 
{ 
	get{
		EnsureChildcontrols(); 
		return _sl.Text;
	} 
	set{ 
		EnsureChildcontrols(); 
		_sl.Text=value
	} 
}

转载于:https://my.oschina.net/Yamazaki/blog/80501

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值