Attribute高級應用:簡化ANF自定義控件初始化過程_.Net教程
推薦:如何在VB.NET中利用Split和Replace函數計算字數Split函數使你能夠將長字符串分離為單獨的字;但是如果在字與字之間不止一個空格,Split就會返回一個錯誤的結果。為了防止這種情況發生,你可以在使用Split之前用Replace函數來替換多個空格的出現。列表A給出了一個例子。 列表A Private Sub CountWords()Dim
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函數時才調用的。不知道是否有二班的情況呢?
分享:細說.Net開發中的Visual Basic.Net概要 VB正在不斷地發展中,它具備了以前VB編程人員作夢都想擁有的性能,想象一下你將隨心所欲的利用這些性能,是不是很令人激動?然而,這個計劃于2001年第四季度上市銷售的VB版本可能會給你帶來些小麻煩,因為要完全掌握它需要一個較長的學習周期,而且其中
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP發送Email實例(可帶附件)
- js實現廣告漂浮效果的小例子
- asp.net Repeater 數據綁定的具體實現
- Asp.Net 無刷新文件上傳并顯示進度條的實現方法及思路
- Asp.net獲取客戶端IP常見代碼存在的偽造IP問題探討
- VS2010 水晶報表的使用方法
- ASP.NET中操作SQL數據庫(連接字符串的配置及獲取)
- asp.net頁面傳值測試實例代碼
- DataGridView - DataGridViewCheckBoxCell的使用介紹
- asp.net中javascript的引用(直接引入和間接引入)
- 三層+存儲過程實現分頁示例代碼
- 相關鏈接:
- 教程說明:
.Net教程-Attribute高級應用:簡化ANF自定義控件初始化過程
。