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

ASP.NET
Internet Explorer 编程简述(二)在IE中编辑OLE嵌入文档
移动窗体
.NET 2.0获取数据库连接统计数据
VB.NET 拖动无边框的窗体
利用WH_CBT Hook将非模态对话框显示为模态对话框
Aspect#应用 - 权限验证
VB 从零开始编外挂(一)
【错误解决】Unable to find script library 'WebUIValidation.js'
VB 从零开始编外挂(四)
DTD指南(3)-DTD-Elements(元素)
知识库文章MDL9745154-File:Microsoft Visual Basic 运行时库
.net手机软件开发(六)OBEX应用:文件传输部分
在winform中使用WebBrowser控件时怎样去除IE的滚动条
WINZIP及WINRAR命令!!!!!
智能客户端相关Application Block结构功能分析(二)
如何在VB中操作EXCEL(一段代码,两个可以使用的过程)
在C#中用最简洁有效的代码执行存储过程并返回数据
.Net的Collection类的一些使用说明
ASP.NET实现数据图表c
用asp.net画饼图

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


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