Previous | Index | Next 

[HOWTO] Leverage the features of native .NET controls

The majority of controls in VB Migration Partner’s support library derive from a “native” .NET control and therefore they inherit all their properties, methods, and events. After you have successfully migrated the existing VB6 code, you can leverage these inherited members to add new features to your VB.NET application.

For example, the VB6TextBox control inherits from the System.Windows.Forms.TextBox control, which has several features that are missing in the VB6 TextBox controls, including the Dock and Anchor properties (which allow smart resizing), the CharacterCasing property (for automatic conversions to upper and lower cases), and so forth.

For example, let’s assume that you have a TextBox control named txtName and that the original VB6 project includes the following code to ensure that all keys typed inside the control are converted to uppercase:

        Private Sub txtName_KeyPress(keyascii As Integer)
            keyascii = Asc(UCase(Chr(keyascii)))
        End Sub

This code works correctly after the migration to VB.NET, however you might want to leverage the new CharacterCasing property. First, you need to exclude the above code from the parsing step, which you do by means of a pair of ParseMode pragmas:

        '## ParseMode Off
        Private Sub txtName_KeyPress(keyascii As Integer)
            keyascii = Asc(UCase(Chr(keyascii)))
        End Sub
        '## ParseMode On

Next, you need to set the CharacterCasing property to the correct value, which would be the CharacterCasing.Upper enumerated value (which is equal to 1). You do this by means of the WriteProperty pragma:

        '## txtName.WriteProperty CharacterCasing, 1

In very few cases, a member of the inner .NET control is shadowed by a property or method with same name and different meaning or behavior. For example, all .NET controls expose the Left, Right, Width, and Height properties (which are expressed in pixels), but all the controls in the support library shadow these members with properties that take or return a value that is expressed in twips or, more precisely, in the current ScaleMode unit.

If you want to access a shadowed .NET property or method, all you need to do is casting the object to the .NET base control, as in this example:

        ' move the txtEditor control 10 pixels to the right
        DirectCast(txtEditor, TextBox).Left += 10

Conveniently, most controls in the support library expose a property named NetObject, which returns a reference to the inner .NET control. Thanks to this property, the above code can be simplified as follows:

        ' move the txtEditor control 10 pixels to the right
        txtEditorNetObject.Left += 10

The NetObject property is also useful for intercepting events from the .NET control, if the event has been shadowed. For example, many controls in the support library shadow the Click, KeyDown, KeyUp, KeyPress, MouseDown, MouseUp, and MouseMove events of the inner .NET control, because these events have a different syntax in VB6.

However, you might want to handle the .NET event – instead of or in addition to handling the VB6-like event – because the .NET event receives extra arguments and provides more flexibility. For example, the MouseEventArgs argument passed to mouse events exposes the Delta property, which allows you to detect whether the mouse wheel has been rotated.

        Private Sub txtName_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
            If e.Delta <> 0 Then
                ' the mouse wheel has been rotated
                ' ...
            End If
        End Sub

Notice that you can’t use the Handles keyword to bind the txtName_MouseMove method to the MouseMove .NET event, because the MouseMove event exposed by the txtName control has a different syntax (it receives four arguments, as in VB6). Instead, you should register this handler dynamically, for example inside the Form_Load event:

        AddHandler txtName.NetObject.MouseMove, AddressOf txtName_MouseMove

You can achieve this result exclusively by means of migration pragmas, so that you don’t need to manually edit the VB.NET code after each migration:

        Private Sub Form_Load()
            '## InsertStatement AddHandler txtName.NetObject.MouseMove, AddressOf txtName_MouseMove
            ' ...
        End Sub
		
        '## OutputMode Uncomment
        Private Sub txtName_MouseMove(ByVal  sender As Object, ByVal e As MouseEventArgs)
            If e.Delta <> 0 Then
                ' the mouse wheel has been rotated
                ' ...
            End If
        End Sub
        '## OutputMode On

Note: not all the controls in VB Migration Partner’s support library expose the NetObject property. For example, the following controls don’t expose it because they inherit from an ActiveX control: INet, Winsock, MAPIMessages, MAPISession, MSComm, DataGrid, MSHFlexGrid, MSChart, MMControl, and Calendar.

Other controls don’t expose the NetObject property because there is no equivalent.NET control: DriveListBox, DirListBox, FileListBox, Data, RDODC, ADODC, CommonDialog, Animation, FlatScrollBar, and UpDown.

Finally, in some cases the NetObject property returns a .NET control whose type might not be the one you are expecting. For example, the VB6PictureBox.NetObject property returns a System.Windows.Forms.UserControl object (and not a System.Windows.Forms.PictureBox control, as you might expect). The VB6Frame.NetObject property returns either a GroupBox or a Panel control, depending on whether the original VB6 Frame control had a border.

 

Previous | Index | Next