自定义控件开发知识点
声明:部分代码及图片来自:http://www.cnblogs.com/holywolf/archive/2008/12/15/1355299.html
1.自定义控件开发,需要继承Control(在System.Web.UI命名空间下)或WebControl(在System.Web.UI.WebControls命名空间下)或CompositeControl(在System.Web.UI.WebControls命名空间下)
2.重写CreateChildControls方法(ascx不一定要重写),该类在Control类上定义,此方法用于创建控件层次,以便为回发和呈现做准备。
3.重写父类的Render方法,在该方法中将服务器控件的内容传递给HtmlTextWriter对象以在客户端呈现内容
更多说明点击:http://msdn.microsoft.com/zh-cn/library/ms178472.aspx#lifecycle_events
=================== 以上是开发自定义控件必须要做的 =========================
4.在.NET中,System.Web.UI.WebControls.Style类封装了Web服务器外观的属性,例如可以设置背景色、前景色或边框等,TableStyle类和TableItemStyle类均扩展了Style类,从它们的名字就可以想到TableStyle类用于设置表格控样的样式,而TableItemStyle类用于设置TableRow或TableCell的样式,它们之间的关系如图所示:
4.1当该属性修改时需要通知其他类中的样式属性以应用新的样式,所以需要使用NotifyParentProperty属性修饰
5.System.Web.UI.IStateManager接口,定义了任何类为支持服务器控件的视图状态管理而必须实现的属性和方法,服务器控件的视图状态由控件属性的累计值组成。该接口包括保存并加载服务器控件的视图状态值的方法,以及一个指示控件跟踪其视图状态的更改的方法。此接口的成员与Control类中的对应方法具有相同的语义。其定义的成员有:
6.使用视图(ViewState)保存自定义控件属性,ViewState实际上是一个StateBag对象,开发人员使用键/值的方法向视图中保存或读取设置,最终发送给用户的HTML页面中会包含一个隐藏域,该隐藏域中保存了经过序列化后的值。如果过分使用视图的话,会导致页面急剧增大,虽然现在网络带宽已经不是限制条件,但这仍然是一个不太好的设计,对于自定义控件来说,如果禁用视图状态可能导致控件不能够正常工作。在ASP.NET2.0里,出现了一个新的概念——控件状态。控件状态实际上是一种特殊的视图状态,它仍然保存在客户端的隐藏域中,但是它并不会受视图状态启用/禁用的影响,也就是说,即使将ViewState禁用,运行时仍然能正确的恢复在控件状态中保存的数据。为了使用控件状态,仅仅需要做额外的几个工作:
- 向页面注册使用控件状态
- 在控件状态保存事件(Control类的SaveControlState方法)中保存相关数据
- 在控件状态读取事件(Control类的LoadControlState方法)中读取保存的数据
需要说明的一点是,正因为控件状态始终都会发送到客户端,所以将大量数据保存到控件状态中显然不是一件太好的事件,始终应该只保存影响控件使用的关键的核心的数据。
7.由于Panel可以看作一个容器控件,那么当页面上使用多个该控件时会产生什么样的结果,容器中的子控件还能保证是唯一的吗?当在页面上放置两个这样的自定义控件时会生成了两个文本框(毫无疑问,因为是两个自定义控件),但是它们的id属性均为txt。自定义控件也需要实现INamingContainer接口,以确保所有子控件ID属性唯一。只需要标记实现INamingContainer接口而不需要编写任何额外的方法,这也就是所谓的“标记接口”,与此类似的还有ISerializable等。
7.1 .NET中的事件基于委托,在ASP.NET中可以使用EventHandler委托(与此相关还定义了泛型委托)定义事件,事件参数包含了与事件有关的数据。有关委托和事件及泛型的知识请参阅相关书籍。
7.2 对属性使用Themable特性进行定义,该特性指定属性不受到主题和控件外观的影响。
7.3/* 由于服务器端控件均是引用类型,所以不能直接将控件添加到某个控件集合中, * 而必须调用Controls.CopyTo将原有控件复制到目标控件数组中,否则在调用Controls.Clear方法时仍然会将控件移除而导致错误的运行结果。 */ Control[] rg = new Control[Controls.Count]; Controls.CopyTo(rg, 0);
foreach (Control ctl in rg) body.Controls.Add(ctl);
Controls.Clear(); Controls.Add(t);