【.Net码农】[asp.net]自定义控件(支持模板)2
2015-08-21 17:18
555 查看
[asp.net]自定义控件(支持模板)2
接着上一篇,今天来做支持数据绑定的模板控件。 使用支持数据绑定控件的一般模式为private void Page_Load(object sender, System.EventArgs e) { if(!this.IsPostBack) { this.tm.DataSource=new string[]{"one","two"}; this.tm.DataBind(); } }
先指定数据源,当确认数据源正确后调用DataBind方法进行数据绑定。然后就开始调用控件自己的DataBinding事件的处理程序,一般是OnDataBinding,在这个方法里对数据源进行操作。
前面已经有文章分析了数据源,可以想到,和一般的控件不同的是,支持模板的控件在进行数据绑定时需要多做一步,除了要把数据从数据源取出,还要把这些数据绑到模板上。
还有,数据源一般都是在初次加载页面时用到,回发后就不再提供数据源,而是依靠viewstate来维持。因此“把数据绑到模板”这一步操作要放到OnDataBinding进行(因为DataBind只被使用一次),而CreateChildControls则要做一些维持状态的工作。
先要做的,是准备一个接收数据源的属性。
然后要有一个“把数据绑到模板”的方法,就像下面这个
private void createTemplate() { if(this.itemTemplate!=null) { if(this.dataSource!=null) { //计算创建了多少子模板 int itemCount=1; //只是为了方便而做的假设dataSource是string[] foreach(string text in (string[])this.dataSource) { ContainerControl cc=new ContainerControl(text); this.itemTemplate.InstantiateIn(cc); this.Controls.Add(cc); itemCount++; } //保存数量到ViewState this.ViewState["itemCount"]=itemCount; } else this.Controls.Add(new LiteralControl("no itemtemplate!1")); this.ChildControlsCreated=true; } else this.Controls.Add(new LiteralControl("no itemtemplate!")); }
在上面的方法中,使用遍历数据源的方法来循环添加模板容器。不明白可以去看上一篇笔记。
viewstate可以维持模板内控件的状态,但是它却不负责创建控件,因此我们在这里保存了模板的数量itemCount,然后在CreateChildControls中创建itemCount个空模板,这样viewstate就可以给这些空模板附加上状态。
protected override void CreateChildControls() { if(this.itemTemplate!=null) { int itemCount=(int)this.ViewState["itemCount"]; for(int i=1;i<itemCount;i++) { ContainerControl cc=new ContainerControl(string.Empty); this.itemTemplate.InstantiateIn(cc); this.Controls.Add(cc); } } else this.Controls.Add(new LiteralControl("no itemtemplate!")); base.CreateChildControls(); }
然后就成了,下面是全部的代码。
using System; using System.Web.UI; using System.ComponentModel; using System.Collections; using System.Data; namespace CC { /// <summary> /// 模板练习 /// </summary> //分析控件内的xml元素标记 [ParseChildren(true)] public class TemplateControl : Control, INamingContainer { //模板 private ITemplate itemTemplate; //指定存放模板的容器控件 [TemplateContainer(typeof(ContainerControl)), Browsable(false)] public ITemplate ItemTemplate { get { return this.itemTemplate; } set { this.itemTemplate = value; } } //数据源 private object dataSource; [Browsable(false)] public object DataSource { get { return this.dataSource; } set { this.dataSource = value; } } /// <summary> /// 创建子控件,在这里创建的只是空壳,其内容根据ViewState来填充 /// </summary> protected override void CreateChildControls() { if (this.itemTemplate != null) { int itemCount = (int)this.ViewState["itemCount"]; for (int i = 1; i < itemCount; i++) { ContainerControl cc = new ContainerControl(string.Empty); //将模板添加到专门的容器中 this.itemTemplate.InstantiateIn(cc); //将容器加到父控件中 this.Controls.Add(cc); } } else this.Controls.Add(new LiteralControl("no itemtemplate!")); base.CreateChildControls(); } /// <summary> /// 当用户端调用DataBind,则表示准备好了数据源,此时可以开始创建子模板 /// </summary> /// <param name="e"></param> protected override void OnDataBinding(EventArgs e) { //确定服务器控件是否包含子控件。如果不包含,则创建子控件。 //this.EnsureChildControls(); this.createTemplate(); base.OnDataBinding(e); } //手动创建子模板 private void createTemplate() { if (this.itemTemplate != null) { //当由类实现时,定义子控件和模板所属的 Control 对象。然后在内联模板中定义这些子控件 //this.itemTemplate.InstantiateIn(this); if (this.dataSource != null) { //计算创建了多少子模板 int itemCount = 1; //只是为了方便而做的假设dataSource是string[] foreach (string text in (string[])this.dataSource) { ContainerControl cc = new ContainerControl(text); //将模板添加到专门的容器中 this.itemTemplate.InstantiateIn(cc); //将容器加到父控件中 this.Controls.Add(cc); itemCount++; } //保存数量到ViewState this.ViewState["itemCount"] = itemCount; } else this.Controls.Add(new LiteralControl("no itemtemplate!1")); //确认子模板创建完毕 this.ChildControlsCreated = true; } else this.Controls.Add(new LiteralControl("no itemtemplate!")); } } /// <summary> /// 容器控件,用来存放模板 /// </summary> public class ContainerControl : Control, INamingContainer { private string text; public string Text { get { return this.text; } } public ContainerControl(string text) { this.text = text; } } }
完成了这个,接下来我们就可以自己写一个Repeater控件!
相关文章推荐
- ApsCMS AspCms_SettingFun.asp、AspCms-qqkfFun.asp、AspCms_Slide.asp、AspCms_StyleFun.asp、login.asp、AspCms_CommonFun.asp Vul
- ASP.NET文件上传大小II限制修改
- 【.Net码农】ASP.NET数据控件的自定义模板
- Jasper Report(3)--- 用JavaBean Collection做为数据源
- asp.net ajax
- Jasper Report (2)--- 用JDBC做为数据源
- Asp.net mvc项目分页功能
- Jasper Report (1)--- Eclipse集成Ireport插件
- asp.net图片分布式存储
- CasperJS,基于PhantomJS的工具包
- ASP入门(十九)- SELECT 语句
- ASP入门(十八)-访问Access中的数据库
- IIS网站或系统验证码不显示问题——"使用了托管的处理程序,但是未安装或未完整安装 ASP.NET"
- Phantomjs 根据Casperjs源码拓展download方法
- ASP.Net零碎
- Asp.net+MVC
- 简单记录在Visual Studio 2013中创建ASP.NET Web API 2
- Win10 兼容性 Visual studio web应用程序 ASP.NET 4.0 尚未在 Web 服务器上注册
- asp网站后台里嵌入kindeditor在线编辑器问题
- NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式