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.