When defining a property of a Windows Forms control, you typically need to define its default value. Such a default value fulfills two goals: first, it reduces the amount of code that Visual Studio generates in the *.Designer.vb file, which in turn speeds up form instantiation; second, it allows developers to quickly reset the property to its default value by right-clicking on the property inside Visual Studio’s Property Grid and then selecting the Reset menu command. All property values that aren’t equal to the default value appear in boldface, therefore the Reset command restores a non-boldface value.
You can declare the default value of a property by means of the System.ComponentModel.DefaultValue attribute, as in:
Private m_ScaleLeft As Single = 0
<DefaultValue(0.0!)> _
Public Property ScaleLeft() As Single
Get
Return m_ScaleLeft
End Get
Set(ByVal Value As Single)
m_ScaleLeft = Value
End Set
End Property
Unfortunately, VB.NET has a bug and doesn’t allow you to select a default value for enumerated properties. For example, consider the ScaleMode enumerated property, which is exposed by the VB6Form in VB Migration Partner’s support library:
Private m_ScaleMode As ScaleModeConstants = ScaleModeConstants.vbTwips
<DefaultValue(ScaleModeConstants.vbTwips)> _
Public Property ScaleMode() As ScaleModeConstants
Get
Return m_ScaleMode
End Get
Set(ByVal value As ScaleModeConstants)
m_ScaleMode = value
End Set
End Property
The problem is, this code doesn’t work in VB 2005. More precisely, you can reset the ScaleMode property to its default value using the Reset command, but the property value is always displayed in boldface and is always serialized in the *.Designer.vb file. It turns out that all enumerated properties manifest this bug. (I consider it as a VB.NET bug because C# doesn’t exhibit this odd behavior.)
I tried all the techniques I was aware of to fix the problem, including adding a ShouldSerialize* method, as in:
Public Function ShouldSerializeScaleMode() As Boolean
Return Me.ScaleMode <> ScaleModeConstants.vbTwips
End Function
I had always given up, when I discovered an overload of the DefaultValue attribute, which takes a System.Type and a string argument. To my great surprise, it worked!
<DefaultValue(GetType(ScaleModeConstants), "1")> _
Public Property ScaleMode() As ScaleModeConstants
…
End Property
Thanks to this fix, all the controls in VB Migration Partner’s library now serialize only the properties that have been set to a nondefault value. I haven’t checked yet whether Microsoft fixed this bug in VB2008, but for sure the VB2005 workaround is so counterintuitive that I felt the urge to document it here.