當我們在Visual Studio添加一個自訂控制項時,它都會給我們以下預設的代碼。
[DefaultProperty("Text")] [ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")] public class WebCustomControl1 : WebControl { [Bindable(true)] [Category("Appearance")] [DefaultValue("")] [Localizable(true)] public string Text { get { String s = (String)ViewState["Text"]; return ((s == null) ? String.Empty : s); } set { ViewState["Text"] = value; } } protected override void RenderContents(HtmlTextWriter output) { output.Write(Text); } } [DefaultProperty("Text")] [ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")] public class WebCustomControl1 : WebControl { [Bindable(true)] [Category("Appearance")] [DefaultValue("")] [Localizable(true)] public string Text { get { String s = (String)ViewState["Text"]; return ((s == null) ? String.Empty : s); } set { ViewState["Text"] = value; } } protected override void RenderContents(HtmlTextWriter output) { output.Write(Text); } }
在這個控制項中有個預設的屬性"Text",在這個屬性有[DefaultValue("")]相應的特性,來給該屬性設定預設值。以前一直
想不明白微軟是怎麼實現的,直到昨天看了《你必須知道的.Net》中講“特性”這一章受到了啟發。於是我馬上去試試,
還真的可以。廢話少說,來看看我的實現方法。
首先我們先建立一個自己預設值特性SelfDefaultValueAttribute:
[AttributeUsageAttribute(AttributeTargets.All, // 可以對任何應用程式元素應用屬性 AllowMultiple = true, // 允許指定多個執行個體 Inherited = false)] // 不繼承到衍生類別 public class SelfDefaultValueAttribute : System.Attribute { public SelfDefaultValueAttribute(object defaultVale) { this.AttrValue = defaultVale; } public object AttrValue { get; set; } } [AttributeUsageAttribute(AttributeTargets.All, // 可以對任何應用程式元素應用屬性 AllowMultiple = true, // 允許指定多個執行個體 Inherited = false)] // 不繼承到衍生類別 public class SelfDefaultValueAttribute : System.Attribute { public SelfDefaultValueAttribute(object defaultVale) { this.AttrValue = defaultVale; } public object AttrValue { get; set; } }
接著我們建立一個自己的控制項父類SelfControl
public class SelfControl { public SelfControl() { Type tp = this.GetType(); PropertyInfo[] propInfoList = tp.GetProperties(); //獲得所有的屬性 foreach (PropertyInfo p in propInfoList) { //獲得當前屬性的特性 SelfDefaultValueAttribute m = Attribute.GetCustomAttribute(p, typeof (SelfDefaultValueAttribute)) as SelfDefaultValueAttribute; //判斷該屬性是否有特性 if (m != null) { //設定預設值 p.SetValue(this, m.AttrValue, null); } else { //設定值為空白 p.SetValue(this, null, null); } } } [SelfDefaultValue("")] public virtual string Name { get; set; } } public class SelfControl { public SelfControl() { Type tp = this.GetType(); PropertyInfo[] propInfoList = tp.GetProperties(); //獲得所有的屬性 foreach (PropertyInfo p in propInfoList) { SelfDefaultValueAttribute m = Attribute.GetCustomAttribute(p, typeof(SelfDefaultValueAttribute)) as SelfDefaultValueAttribute; //獲得當前屬性的特性 /*判斷該屬性是否有特性*/ if (m != null) { /*設定預設值*/ p.SetValue(this, m.AttrValue, null); } else { /*設定值為空白*/ p.SetValue(this, null, null); } } } [SelfDefaultValue("")] public virtual string Name { get; set; } }
這個控制項只有一個屬性"Name"預設值為空白。說明一下的是,在這裡我們用到了反射的機制,所以我們要引入空間:
System.Reflection。
現在,我們就可以建立屬於自己定義的控制項了。
好了,終於完成了。那我們現在來測試一下。
public class Myrun { public static void Main(string[] args) { TestSelfControl selfCon = new TestSelfControl(); Console.WriteLine("控制項寬度:{0}",selfCon.Width); Console.WriteLine("控制項高度:{0}", selfCon.Height); Console.WriteLine("控制項名字:{0}", selfCon.Name); Console.WriteLine("控制項標籤:{0}", selfCon.HtmlTag); Console.WriteLine("控制項文本:{0}", selfCon.Text); Console.ReadLine(); } } public class Myrun { public static void Main(string[] args) { TestSelfControl selfCon = new TestSelfControl(); Console.WriteLine("控制項寬度:{0}",selfCon.Width); Console.WriteLine("控制項高度:{0}", selfCon.Height); Console.WriteLine("控制項名字:{0}", selfCon.Name); Console.WriteLine("控制項標籤:{0}", selfCon.HtmlTag); Console.WriteLine("控制項文本:{0}", selfCon.Text); Console.ReadLine(); } } 最後的結果就是:view plaincopy to clipboardprint?控制項寬度:100 控制項高度:0 控制項名字: 控制項標籤: 控制項文本:TestControl 控制項寬度:100控制項高度:0控制項名字:控制項標籤:控制項文本:TestControl
由於我們沒給控制項的高度設定預設值、高度類型Int,所以高度預設為0;而名字和標籤類型為String,所以為空白。