Previous | Index | Next 

[PRB] Serializable properties in UserControls using system objects may crash Visual Studio

Consider the following property added to a VB6 UserControl:

        Private m_AppVersion As String

        Property Get AppVersion() As String
            ' if not explicitly set, return the application’s version
            AppVersion = App.Major & "." & App.Minor & "." & App.Revision
        End Property
  
        Property Let AppVersion(ByVal value As String)
            m_AppVersion = value
        End Property

The above property is translated to VB.NET as follows:

        Private m_AppVersion As String

        Public Property AppVersion() As String
            Get
                Return App6.Major & "." & App6.Minor & "." & App6.Revision
            End Get
            Set(ByVal value As String)
                m_AppVersion = value
            End Set
        End Property

As innocent as it may look, this code can crash Visual Studio. In fact, if you migrate a VB6 form that contains this user control, then load the migrated form into Visual Studio and attempt to modify the form (for example, by resizing it or moving one of its controls), then Visual Studio is forced to serialize all the UserControl’s properties in the code-behind sections of the form.

The crash occurs because, when Visual Studio is in design-mode, the App6 object isn’t initialized and any reference to it causes an exception (usually a NullReference exception). In fact, the App6 object is valid only when the project is running.

You can solve this problem in a couple ways. The first solution: you specify that the property should not be serialized, by decorating it with the following attributes:

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        <Browsable(False)> _
        Public Property AppVersion() As String
            ' ...
        End Property

If the property must be serialized somehow, you should modify the code inside the Get block so that the App6 object isn’t referenced if the project is in design-mode, as follows:

        Public Property AppVersion() As String
            Get
                ' if in design mode, return a dummy value
                If Me.DesignMode Then Return "1.0.0"
                Return App6.Major & "." & App6.Minor & "." & App6.Revision
            End Get
            Set(ByVal value As String)
                m_AppVersion = value
            End Set
        End Property

NOTE: the same problem can occur with other system objects, such as Screen or Printers.

 

Previous | Index | Next