当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > Attribute应用:简化ANF自定义控件初始化过程

ASP.NET
如何在ASP.NET中使用SmtpMail发送邮件
在VB.NET中利用Split和Replace函数计算字数
Attribute应用:简化ANF自定义控件初始化过程
ASP.NET 2.0移动开发入门之使用样式
ASP.NET 2.0中使用OWC生成图表
ASP.NET 2.0中控件的简单异步回调
一个无法捕获ADO.NET Dataset的内存错误
深入解读ADO.NET2.0的十大最新特性
.Net平台下的分布式缓存设计
ASP.NET全局异常处理浅析
ASP.NET 2.0中文验证码的实现
浅析.NET平台编程语言的未来走向
.net 框架程序设计收藏
使用ASP.NET MVC Futures 中的异步Action
详解.NET中的XmlReader与XmlWriter
关于.NET中的Server push技术
asp.net页面执行机制
对比JSP和ASP.NET的存储过程
.NET 4.0不会包含System.Shell.CommandLine
ASP.NET十个有效性能优化的方法

ASP.NET 中的 Attribute应用:简化ANF自定义控件初始化过程


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 34 ::
收藏到网摘: n/a

Attribute应用,简化ANF自定义控件初始化过程

研究ANF的源码,让我获益良多。其中很多思想,都是非常值得学习的。其中换肤的方式,宝玉已经介绍过了,《Asp.Net Forums2.0深入分析》之 Asp.Net Forums是如何实现代码分离和换皮肤的。不过,当一个自定义控件中服务器端控件比较多的时候,InitializeSkin方法的实现代码就有点烦人了,比如看一下AdminSiteSettings的代码。实在是非常之烦人。模式都一样,如TextBox DisableSiteReason=skin.FindControl("DisableSiteReason") as TextBox之类。所以今天想利用Attribute来简化一下。

首先我们要添加一个Attribute类,暂且就叫做BindControlAttribute:

using System;using System.Collections.Generic;using System.Text;using System.Reflection;namespace AspNetForums.Controls{[AttributeUsage(AttributeTargets.Field|AttributeTargets.Property,AllowMultiple=false)]class BindControlAttribute:Attribute{string _ctrlID;public BindControlAttribute(string ctrlID){_ctrlID = ctrlID;}public string ControlID{get { return _ctrlID; }}}}

这个类Attribute功能比较简单,就是让这个Attribute记录字段要绑定到的控件的ID。

第二步就是修改SkinnedForumWebControl了,主要是添加一个方法:

private void InitializeFields(Control skin){FieldInfo[] fields = this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);foreach (FieldInfo fi in fields){if (fi.IsDefined(typeof(BindControlAttribute), false)){BindControlAttribute bind = fi.GetCustomAttributes(typeof(BindControlAttribute), false)[0] as BindControlAttribute;object ctrl = skin.FindControl(bind.ControlID);fi.SetValue(this, ctrl);}}}

其实在fi.IsDefined(typeof(BindControlAttribute), false)这里我本想再加一个条件的,就是限制字段的类型是System.Web.UI.Control或者它的子类,可是试了几种方法,都没能成功。请知道的指点一下...
记得要引用System.Reflection名称空间,还要改一下CreateChildControls方法的实现:

protected override void CreateChildControls(){Control skin = null;if (inlineSkin != null){inlineSkin.InstantiateIn(this);InitializeSkin(this);}else{// Load the skinskin = LoadSkin();//Initialize the fieldsInitializeFields(skin);//就加这一行// Initialize the skinInitializeSkin(skin);Controls.Add(skin);}}

到这里,实现的任务就完成了。下面就是应用了。应用是比较简单的,只需要在定义字段的时候,加上这个BindControlAttribute就行了。如:

uing System;using System.Collections;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using AspNetForums.Components;using AspNetForums.Enumerations;namespace AspNetForums.Controls{/// /// 论坛组列表服务器控件/// public class ForumGroupView : SkinnedForumWebControl{#region 成员字段private ForumContext forumContext = ForumContext.Current;private string skinFilename = "View-ForumGroupView.ascx";[BindControl("forumGroupRepeater")]//定义字段时加这么一行private Repeater repeater;#endregion public ForumGroupView(){// Assign a default template nameif (SkinFilename == null)SkinFilename = skinFilename;}#endregion #region 控件初始化// *********************************************************************//  Initializeskin///// /// Initializes the user control loaded in CreateChildControls. Initialization/// consists of finding well known control names and wiring up any necessary events./// /// // ********************************************************************/ protected override void InitializeSkin(Control skin){//repeater = (Repeater) skin.FindControl("forumGroupRepeater");//这一行就没有用了。DataBind();}

感觉是不是好点呢?

第一次用反射,着实费了我不小的功夫(主要是看书不认真:-))。我要获取私有字段的时候,试了好多次才试出来,后边三年BindingFlags貌似都得加上,少一个都不行。另外,我发现,Attribute构造函数是在调用GetCustomAttributes函数时才调用的。不知道是否有二班的情况呢?