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

ASP.NET
asp.net css注释的影响
ASP.NET与数据库相关技巧
关于HtmlForm控件
三色交替的下拉列表框
精通ASP.NET中弹出窗口技术
ASP.NET Forums与现有系统整合方案示例
ASP.NET操作IIS中的虚拟目录
DataGrid与SQL Server 2000数据绑定
如何让Web应用程序在Client端实现导出报表功能
如何保证web app中的Send Email线程稳定性
关于用ASP.Net识别远程主机服务器种类
ASP.NET中上传下载文件
提高ASP.NET性能的方法
asp.net StreamReader 创建文件
asp.net如何生成图片验证码(简单)
一个.net 压缩位图至JPEG的代码
简单的SQL Server数据库数据读取与数据操作
获取网站的RSS聚合到自己的网页
.Net程序中整站通用的防SQL注入函数
asp.net生成缩略图及给原始图加水印的函数

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-08-14   浏览: 58 ::
收藏到网摘: 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函数时才调用的。不知道是否有二班的情况呢?