WinForm控件开发总结(十)-----为属性设置默认值

      本系列的前面几篇文章讲解了如何来定义属性以及更有效的编辑属性 , 接下来我要讲一下控件属性的默认值。如果我们希望自己开发的控件更易于被其它开发者使用,那么提供默认值是非常值得的。
      如果你为属性设定了默认值,那么当开发者修改了属性的值,这个值在 Property Explorer 中将会以粗体显示。 VS 为属性提供一个上下文菜单,允许程序员使用控件把值重置为默认值。当 VS 进行控件的串行化时,他会判断那些值不是默认值,只有不是默认值的属性才会被串行化,所以为属性提供默认值时可以大大减少串行化的属性数目,提高效率。
      那么 VS 怎么知道我们的属性值不是默认值了呢?我们需要一种机制来通知 VS 默认值。实现这种机制有两种方法:
      对于简单类型的属性,比如 Int32 , Boolean 等等这些 Primitive 类型,你可以在属性的声明前设置一个 DefaultValueAttribute ,在 Attribute 的构造函数里传入默认值。
      对于复杂的类型,比如 Font , Color ,你不能够直接将这些类型的值传递给 Attibute 的构造函数。相反你应该提供 Reset<PropertyName> 和 ShouldSerialize<PropertyName> 方法,比如 ResetBackgroundColor(),ShouldSerializeBackgroundColor() 。 VS 能够根据方法的名称来识别这种方法,比如 Reset<PropertyName> 方法把重置为默认值, ShouldSerialize<PropertyName> 方法检查属性是否是默认值。过去我们把它称之为魔术命名法,应该说是一种不好的编程习惯,可是现在微软依然使用这种机制。我还是以前面几篇文章使用的例子代码。
      
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
using  System.Windows.Forms;
None.gif
using  System.ComponentModel;
None.gif
using  System.Drawing;
None.gif
None.gif
namespace  CustomControlSample
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public class FirstControl : Control
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
InBlock.gif
private String _displayText=”Hello World!”;
InBlock.gif
private Color _textColor=Color.Red;
InBlock.gif
InBlock.gif  
public FirstControl()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
// ContentAlignment is an enumeration defined in the System.Drawing
InBlock.gif        
// namespace that specifies the alignment of content on a drawing 
InBlock.gif        
// surface.
InBlock.gif
        private ContentAlignment alignmentValue = ContentAlignment.MiddleLeft;
InBlock.gif
InBlock.gif        [
InBlock.gif        Category(
"Alignment"),
InBlock.gif        Description(
"Specifies the alignment of text.")
InBlock.gif        ]
InBlock.gif        
public ContentAlignment TextAlignment
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return alignmentValue;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                alignmentValue 
= value;
InBlock.gif
InBlock.gif                
// The Invalidate method invokes the OnPaint method described 
InBlock.gif                
// in step 3.
InBlock.gif
                Invalidate();
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif
InBlock.gif [Browsable(
true)]
InBlock.gif [DefaultValue(“Hello World”)]
InBlock.gif 
public String DisplayText
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
get
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
return _displayText;
ExpandedSubBlockEnd.gif}

InBlock.gif
set
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif     _displayText 
=value;
InBlock.gif    Invalidate();
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif[Browsable(
true)]
InBlock.gif
public Color TextColor
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
get
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    
return _textColor;
ExpandedSubBlockEnd.gif}

InBlock.gif
set
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    _textColor
=value;
InBlock.gifInvalidate();
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
public void ResetTextColor()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif    TextColor
=Color.Red;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
public bool ShouldSerializeTextColor()
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
return TextColor!=Color.Red;
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
protected override void OnPaint(PaintEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
base.OnPaint(e);
InBlock.gif            StringFormat style 
= new StringFormat();
InBlock.gif            style.Alignment 
= StringAlignment.Near;
InBlock.gif            
switch (alignmentValue)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
case ContentAlignment.MiddleLeft:
InBlock.gif                    style.Alignment 
= StringAlignment.Near;
InBlock.gif                    
break;
InBlock.gif                
case ContentAlignment.MiddleRight:
InBlock.gif                    style.Alignment 
= StringAlignment.Far;
InBlock.gif                    
break;
InBlock.gif                
case ContentAlignment.MiddleCenter:
InBlock.gif                    style.Alignment 
= StringAlignment.Center;
InBlock.gif                    
break;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            
// Call the DrawString method of the System.Drawing class to write   
InBlock.gif            
// text. Text and ClientRectangle are properties inherited from
InBlock.gif            
// Control.
InBlock.gif
            e.Graphics.DrawString(
InBlock.gif                DisplayText,
InBlock.gif                Font,
InBlock.gif                
new SolidBrush(TextColor),
InBlock.gif                ClientRectangle, style);
InBlock.gif
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

      在上面的代码中,我增加了两个属性,一个是DisplayText,这是一个简单属性,我们只需要在它的声明前添加一个DefaultValue Attribute就可以了。另外一个是TextColor属性,这个复杂类型的属性,所以我们提供了ResetTextColor和ShouldSerializeTextColor来实现默认值。
      默认值的实现就讲完了,但是有一点不要忽视了,你设定了默认值,就应该相应的初始化这些属性,比如我们例子中的代码:
      

None.gif private  String _displayText = ”Hello World ! ”;
None.gif
private  Color _textColor = Color.Red;
None.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值