WinForm控件開發(fā)總結(jié)(十)-為屬性設(shè)置默認(rèn)值
本系列的前面幾篇文章講解了如何來(lái)定義屬性以及更有效的編輯屬性,接下來(lái)我要講一下控件屬性的默認(rèn)值。如果我們希望自己開發(fā)的控件更易于被其它開發(fā)者使用,那么提供默認(rèn)值是非常值得的。
如果你為屬性設(shè)定了默認(rèn)值,那么當(dāng)開發(fā)者修改了屬性的值,這個(gè)值在Property Explorer中將會(huì)以粗體顯示。VS為屬性提供一個(gè)上下文菜單,允許程序員使用控件把值重置為默認(rèn)值。當(dāng)VS進(jìn)行控件的串行化時(shí),他會(huì)判斷那些值不是默認(rèn)值,只有不是默認(rèn)值的屬性才會(huì)被串行化,所以為屬性提供默認(rèn)值時(shí)可以大大減少串行化的屬性數(shù)目,提高效率。 那么VS怎么知道我們的屬性值不是默認(rèn)值了呢?我們需要一種機(jī)制來(lái)通知VS默認(rèn)值。實(shí)現(xiàn)這種機(jī)制有兩種方法: 對(duì)于簡(jiǎn)單類型的屬性,比如Int32,Boolean等等這些Primitive類型,你可以在屬性的聲明前設(shè)置一個(gè)DefaultValueAttribute,在Attribute的構(gòu)造函數(shù)里傳入默認(rèn)值。 對(duì)于復(fù)雜的類型,比如Font,Color,你不能夠直接將這些類型的值傳遞給Attibute的構(gòu)造函數(shù)。相反你應(yīng)該提供Reset<PropertyName> 和ShouldSerialize<PropertyName>方法,比如ResetBackgroundColor(),ShouldSerializeBackgroundColor()。VS能夠根據(jù)方法的名稱來(lái)識(shí)別這種方法,比如Reset<PropertyName>方法把重置為默認(rèn)值,ShouldSerialize<PropertyName>方法檢查屬性是否是默認(rèn)值。過(guò)去我們把它稱之為魔術(shù)命名法,應(yīng)該說(shuō)是一種不好的編程習(xí)慣,可是現(xiàn)在微軟依然使用這種機(jī)制。我還是以前面幾篇文章使用的例子代碼。 using System;
using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.ComponentModel; using System.Drawing; namespace CustomControlSample { public class FirstControl : Control { private String _displayText=”Hello World!”; private Color _textColor=Color.Red; public FirstControl() { } // ContentAlignment is an enumeration defined in the System.Drawing // namespace that specifies the alignment of content on a drawing // surface. private ContentAlignment alignmentValue = ContentAlignment.MiddleLeft; [ Category("Alignment"), Description("Specifies the alignment of text.") ] public ContentAlignment TextAlignment { get { return alignmentValue; } set { alignmentValue = value; // The Invalidate method invokes the OnPaint method described // in step 3. Invalidate(); } } [Browsable(true)] [DefaultValue(“Hello World”)] public String DisplayText { get { return _displayText; } set { _displayText =value; Invalidate(); } } [Browsable(true)] public Color TextColor { get { return _textColor; } set { _textColor=value; Invalidate(); } } public void ResetTextColor() { TextColor=Color.Red; } public bool ShouldSerializeTextColor() { return TextColor!=Color.Red; } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); StringFormat style = new StringFormat(); style.Alignment = StringAlignment.Near; switch (alignmentValue) { case ContentAlignment.MiddleLeft: style.Alignment = StringAlignment.Near; break; case ContentAlignment.MiddleRight: style.Alignment = StringAlignment.Far; break; case ContentAlignment.MiddleCenter: style.Alignment = StringAlignment.Center; break; } // Call the DrawString method of the System.Drawing class to write // text. Text and ClientRectangle are properties inherited from // Control. e.Graphics.DrawString( DisplayText, Font, new SolidBrush(TextColor), ClientRectangle, style); } } } 在上面的代碼中,我增加了兩個(gè)屬性,一個(gè)是DisplayText,這是一個(gè)簡(jiǎn)單屬性,我們只需要在它的聲明前添加一個(gè)DefaultValue Attribute就可以了。另外一個(gè)是TextColor屬性,這個(gè)復(fù)雜類型的屬性,所以我們提供了ResetTextColor和ShouldSerializeTextColor來(lái)實(shí)現(xiàn)默認(rèn)值。 private String _displayText=”Hello World!”;
private Color _textColor=Color.Red;
作者:綸巾客
|
|