VB6 vs VB.NET controls - Controls (general)

This section describes the differences between VB6 and .NET controls and the problems you can find in migrating VB6 applications with user-interface. The differences that are common to most controls are described in the Controls (general) section.

For a list of differences between VB6 and VB.NET language, see here.

Unless otherwise stated, VB Migration Partner fully supports all the Visual Basic 6 features mentioned in this page. It is worth noticing that names of properties and methods are preserved, which ensures that those even late-bound references work correctly after the migration to VB.NET. For more information, please read the manual and the knowledge base section.

Controls (general)

Align property

A few VB6 controls – including the PictureBox and Data control – expose the Align property, which permit to automatically dock the control to one of the sides of the form border. Under VB.NET this property is replaced by the Dock property, which is exposed by all the controls in the System.Windows.Forms namespace.

Appearance property

Many VB6 controls support the Appearance property, which enables to select between flat and 3D appearance. VB.NET doesn’t support this property, because the control’s appearance is dictated by the operating system.

Controls in VB Migration Partner’s support library expose the Appearance property, which always returns the value 1-3D; any attempt to assign a different value is ignored (or throws an exception if VB6Config.ThrowOnUnsupportedMembers property is set to True).

AutoRedraw property

VB.NET doesn’t support the AutoRedraw property, therefore implementing double-buffered graphics requires manual code edits.

VB Migration Partner supports and replicates the exact behavior of the AutoRedraw property, thus you can easily convert VB6 applications that use double-buffering techniques and persistent graphic output. (As in VB6, no Paint event is raised when AutoRedraw is True.)

BackColor property

When you drop a VB6 Label control on a form, the initial value of its BackColor property is set to ButtonFace; when you drop a VB.NET Label control on a form, the initial value of its BackColor property is equal to the background color of the container control. This behavior is common to other VB.NET controls, such as Button.

Caption property

No VB.NET control exposes the Caption property, which has been converted to the Text property. Notice that assigning the Text property a string equal to Nothing causes a runtime exception.

VB Migration Partner support the Caption property, to ensure that converted code works as intended even if the control is accessed via late binding. Strings equal to Nothing are converted to empty strings before being assigned to the Text property, thus avoiding unexpected runtime exceptions.

ClipControls property

The VB6 Form, UserControl, and PictureBox objects expose the ClipControls property, which allows to developers to speed up the user interface in some circumstances. VB.NET doesn’t expose such a property.

Controls in VB Migration Partner’s support library expose this property, but it always returns False; attempts to assign a different value are ignored (or throw an exception if the VB6Config.ThrowOnUnsupportedMembers property is True).

Color values

VB6 assigns and manipulates color values and properties – such as ForeColor and BackColor - by means of 32-bit integers; VB.NET and all .NET Framework languages represent color values by means of instances of the System.Drawing.Color type. In most circumstances both the source and the destination of a color assignment become Color values after the migration to VB.NET, therefore you don’t need any specific fix to have the code compile correctly.

In some cases, however, you might have to convert a 32-bit integer to a color value, or vice versa. This explicit conversion is necessary, for example, if your application reads color values from a data file or a database, or if you dynamically calculate a color value by means of a method (e.g. when converting an image to gray scale). You can perform such conversions by means of the ToOle, FromOle, and FromWin32 methods of the System.Drawing.ColorTranslator type:

        txtName.BackColor = ColorTranslator.FromOle(integerColorValue)
        integerColorValue = ColorTranslator.ToOle(txtName.BackColor)

For uniformity and readability’s sake, VB Migration Partner generates calls to FromOleColor6 and ToOleColor6 methods, which in turn invoke the methods of the ColorTranslator type.

Container property

All visible VB6 controls expose the Container property, which returns a reference to the form or control that contains the current control. Interestingly, the Container property is writable under VB6, a feature that allows developers to move controls from one container to another container (on the same form) at runtime, as in this code:

        ' move the txtName control into the picFrame container (a PictureBox container)
        Set txtName.Container = picFrame

The Container property corresponds to the Parent property under VB.NET, but the two properties aren’t equivalent because the Parent property is readonly. You can change the container of a .NET control only by removing the control from the Controls collection of current container and adding it to the Controls collection of a different container:

        ' move the txtName control into the picFrame container (a PictureBox container)
        txtName.Parent.Controls.Remove(txtName)  ' remove from current container
        picFrame.Controls.Add(txtName)           ' add to new container

VB Migration Partner fully supports the Container property, including the ability to assign it for moving the control to another control.

Control accelerator keys

Both in VB6 and VB.NET, you assign a control accelerator key by inserting an & (ampersand) character in the control Caption (VB6) or Text (VB.NET) property:

       lblName.Caption = "&Name"

However, VB.NET controls running under Windows XP or Vista don’t display the accelerator key when the form loads. It becomes visible when the end user presses the Alt key.

The only documented way to always display control accelerators is by sending a WM_CHANGEUISTATE to the parent form, using the SendMessage API method. However, things are quite intricate because you must send this message after the form has initialized but before the form becomes visible. You must do this for each form in your application.

VB Migration Partner makes things easier, in that you only need to assign the VB6Form.ShowAccelerators property to True when the program starts. Then you can forget about the whole thing.

Control arrays

VB.NET doesn’t support control arrays, therefore it is required that replace them with native .NET code. A VB6 developer typically use control arrays for two reasons: to create a new control at runtime and to centralize event handling, so that a single method can handle events coming from multiple controls.

VB.NET offers solutions for both tasks: you can create a new control simply by using the New operator and you can centralize event handling by means of the AddHandler operator. However, such techniques are quite different from the original control array concept and prevent from using an automatic code translator to migrate existing VB6 code.

To reduce the need for manual fixes, both the Upgrade Wizard and VB Migration Partner provide one or more objects that behave like the VB6 control and allow you to both generate new controls and centralize event handling. The main difference between the two tools is that the Upgrade Wizard uses one distinct class for each VB6 control, whereas VB Migration Partner uses the VB6ControlArray(Of T) generic type, which can handle all existing controls, including those provided by 3rd-party companies.

Control variables

The Upgrade Wizard converts VB6 Control variables to System.Windows.Forms.Control variables. However, the VB6 Control type is actually an IDispatch variable; in other words, it supports late binding and it is more akin to an Object variable than to a System.Windows.Forms.Control object. In fact, consider the following code snippet:

        Dim ctrl As Control
        For Each ctrl In Form1.Controls
            If Type ctrl Is CheckBox Then ctrl.Value = 0

If the ctrl variable is converted to a .NET Control variable, then the ctrl.Value reference causes a compilation error, because the System.Windows.Forms.Control class doesn’t expose a member named Value. Additionally, VB6 allows you to store invisible controls to a Control variable – for example, Timer and ImageList controls. These controls are translated to .NET components and can’t be assigned to a System.Windows.Forms.Control variable.

For all the above mentioned reasons, VB Migration Partner converts Control variables to Object variables. For the same reason, the ActiveControl property of the Form and Screen classes return an Object value instead of a Control reference.

Coordinate systems in forms with menus

The (0,0) point in a VB6 form that contains a visible menu bar corresponds to the left-most point immediately below the menu bar; if the menu bar becomes invisible, the coordinate original is shifted accordingly and all controls are automatically moved up so that their Left and Top properties don’t change. By contrast, VB.NET system coordinates ignore the presence of a menu bar; if the menu becomes invisible, controls aren’t shifted.

VB Migration Studio accounts for this important detail, both during the migration process and when the converted VB.NET program is running. Forms migrated with the Upgrade Wizard do not.

CurrentX, CurrentY properties

GDI+ doesn’t support the notion of the “current point” and the methods that draw lines and polygons must always specify the starting point and the ending point. For this reason, no VB.NET control supports the CurrentX and CurrentY properties.

VB Migration Partner supports all the graphics methods as well as the CurrentX and CurrentY properties, which are correctly scaled according to the current ScaleMode setting.

Data binding

Both VB6 and VB.NET support data-binding for their controls, but the actual mechanism differs greatly between the two languages. VB6 supports data binding to different data sources, namely DAO Data controls, RDO Data controls, ADO Data control (ADODC), DataEnvironment objects, ADO Recordsets, and ADO data source objects. Data-binding can be further refined by means of the StdDataFormat object and its Parse and Format events.

By contrast, VB.NET supports data binding with any object, because the actual binding capabilities are offered by the System.Windows.Forms.Binding object; this mechanism isn’t compatible with the VB6 way of doing data binding.

Controls in VB Migration Partner’s support library expose all the usual data-binding properties – that is, DataField, DataSource, DataMember, DataFormant, and DataChanged – and can be bound to the same data sources that VB6 supports, including the various flavors of Data controls, DataEnvironment objects, ADO Recordsets, and ADO data source classes. VB Migration Partner even supports UserControls that work as ADO data sources, therefore it can migrate custom Data controls written in VB6. StdDataFormat objects and their Format and Parse events are also supported.

Default form instances

Both VB6 and VB.NET support the so-called default form instances: in other words, you don’t need to explicitly create a form object and can reference the form by means of a special global variable that is named after the form itself:

        Form1.Left = 200
        Form1.Top = 300

However, VB.NET doesn’t support such references inside the form itself. In other words, previous code causes a compilation error if it is located inside the Form1 class.

VB Migration Partner solves this problem by replacing the form reference with a reference to the Me object:

        Me.Left = 200
        Me.Top = 300

A special case occurs when the current form is unloaded and then set to Nothing:

        Unload Form1
        Set Form1 = Nothing

However, if the form being referenced is the current form then the default form reference must be replaced by the Me keyword, which in turn causes the generation of an invalid statement. For this reason, VB Migration Partner generates a remarked assignment:

        'EXCLUDED:  Set Me = Nothing

Default form instances (assignments)

VB6 allows you to assign Nothing to the default form instance as well a fresh new instance:

        Set Form1 = Nothing
        Set Form1 = New Form1

Interestingly, the latter syntax is equivalent to the former syntax: in fact, if you set a default form instance to Nothing and then reference again the variable, a new form is created automatically. In VB.NET only the former assignment is valid; assigning a non-Nothing object to a default form instance causes a compilation error.

VB Migration Partner takes advantage of the abovementioned equivalence and converts the latter syntax to the former one.

Drag-and-drop features

VB6 offers two flavors of drag-and-drop features: the “classic” VB3-style drag-and-drop and the more modern OLE drag-and-drop. The former allows you to drag and drop items within a VB application only and is based on the DragMode property, Drag method, and DragOver and DragDrop events. The latter was introduced in VB5, allows to drag items from and to other Windows applications (including Windows Explorer), and is based on the OLEDragMode and OLEDropMode properties, the OLEDrag method, and the OLEStartDrag, OLESetData, OLEDragOver, OLEDragDrop, OLECompleteDrag, and OLEGiveFeedback events.

Both models support “automatic” and “manual” drag-and-drop: in automatic mode a control can start a drag-and-drop operation autonomously when the user drags the mouse over the control itself, whereas in manual mode the drag-and-drop operation begins when the developer invokes either the Drag or OLEDrag method.

VB.NET drag-and-drop programming model differs from both “classic” and OLE drag-and-drop model. In general, converting drag-and-drop code from VB6 to VB.NET isn’t a trivial task. In fact, the Upgrade Wizard tool doesn’t even attempt to convert drag-and-drop properties, methods, and event handlers.

VB Migration Partner manages to successfully convert both “classic” and OLE drag-and-drop code, in automatic and manual mode.

Dynamic Data Exchange (DDE)

VB.NET doesn’t support DDE and the Upgrade Wizard can’t migrate any member that is related to DDE, namely LinkMode, LinkTopic, LinkItem and LinkTimeout properties; LinkExecute, LinkPoke, LinkRequest, and LinkSend methods; LinkOpen, LinkClose, LinkNotify, LinkExecute, and LinkError events.

VB Migration Partner fully supports DDE communications between two or more converted VB.NET applications, but not between a VB.NET application and another (non migrated) application, such as Microsoft Excel. Also, the LinkEvent event and LinkTimeout property aren’t supported.

Font inheritance

Both VB6 and VB.NET controls inherit their default font settings from their container (e.g. the parent form), however “inheritance” works differently in the two cases. A VB6 control that doesn’t use a specific value for its Font property is assigned a copy of the font used by its container; in VB.NET a control that doesn’t define a custom font is assigned a reference to the font used by its container. It seems a minor difference, but it isn’t.

In VB6 you can later change a font attribute – name, size, bold, italics, etc. – of the container and nothing else happens; in VB.NET changing a font attribute of the container affects all the child controls that have inherited the Font property from the container.

VB Migration Partner offers a special method named FreezeControlsFont6 which forces VB.NET controls to receive a copy of their container’s font and therefore to behave as in VB6.

Font object

VB6 applications can use the StdFont object – defined in the stdole2 type library. This object broadly corresponds to the System.Drawing.Font object in the .NET Framework, but the two objects aren’t perfectly equivalent. For example, the VB6 Strikethrough property must be translated to the .NET Strikeout property; the VB6 Weight property can only approximated by means of the Bold property. Finally, the VB6 FontChanged event has no equivalent in VB.NET, because .NET fonts are immutable objects and can’t be changed.

The fact that .NET font are immutable means that a VB6 statement such as:

        txtName.Font.Bold = True

can’t be translated directly to VB.NET, because the Bold property is readonly, as are all the other properties of the System.Drawing.Font class.

VB Migration Partner solves this problem by automatically generating a call to the FontChangeBold6 special method:

        FontChangeBold6(txtName.Font, True)

Similar support methods exist for the Name, Size, Italic, Strikeout, and Underline properties.

Support for the Weight property is ensured by the GetFontWeight6 and SetFontWeight6 methods. For example, the following VB6 statement:

        txtName.Font.Weight = txtName.Font.Weight + 200

is translated to this VB.NET code:

        SetFontWeight6(txtName.Font,  GetFontWeight6(txtName.Font) + 200)

VB Migration Partner emits a warning if the VB6 application being converted handles the FontChanged event of a Font object. As mentioned above, no simple workaround for this problem exists.

Font property (assignments)

The VB6 StdFont type maps to the System.Drawing.Font type under VB.NET. However, the two types differ for an important detail: the .NET Font type is immutable, which means that you must set all its properties when you create the font and can’t re-assign them later. In other words, the following VB6 statement is illegal under VB.NET:

        txtName.Font.Bold = True

The Upgrade Wizard fixes this problem by performing the assignment by means of helper methods defined in the Microsoft.VisualBasic.Compatibility.dll assembly:

        FontChangeBold(txtName.Font, True)

The VB Migration Partner adopts a similar approach, except it uses methods in the proprietary support library.

Another problem you might face is that the .NET Font object has no property that corresponds to the StdFont.Weight property. VB Migration Partner (but not the Upgrade Wizard) solves this minor problem by means of the GetFontWeight6 and SetFontWeight6 helper methods.

Font-related properties

VB6 controls expose several font-related properties - including FontName, FontSize, FontBold, FontItalic, FontStrikethru, and FontUnderline – in addition to the Font property that takes a StdFont object. VB.NET controls only support the Font property.

Form chaining

VB6 supports form chaining, a fancy term that means that any VB6 form – including the startup form - can unload itself and load another form. For example, VB6 applications often use form chaining techniques to display a splash screen

VB.NET supports this mechanism only for forms that aren’t the startup form. You should implement splash screens under VB.NET by enabling the related option in the Application tab of the My Project property page.

VB Migration Partner allows you to load a special VB6HiddenStartupForm object that works as the startup form, so that all other forms can use form chaining without any restriction. You can leverage this hidden form by inserting the InitializeFormChaining6 method at the top of the Sub Main method.

Form reuse

VB6 allows you to reuse a variable that references a form that has been unloaded:

        Unload Form1
        Load Form1

No similar sequence is available in VB.NET: if a form is closed, the variable can’t be reused, because all associated Windows resources have been disposed of.

VB Migration Partner keeps track of whether a form has been closed and correctly re-initializes if it is loaded. Code generated by the Upgrade Wizard must be manually revised to ensure that it loads correctly.

Forms collection

The VB6 Forms collection contains all the loaded forms, including those that are loaded but not visible yet (or that have been hidden). By contrast, the VB.NET OpenForms collection contains only the forms that are visible.

Code generated by the Upgrade Wizard might deliver incorrect results at runtime.VB Migration Partner supports a Forms6 collection that behaves exactly like the original VB6 collection.

GotFocus and LostFocus events

VB.NET controls support the GotFocus and LostFocus events, however Microsoft recommends that you use the Enter and Leave events instead.

Moreover, there are minor differences in the sequence in which the LostFocus, GotFocus, and Validating event fire. In .NET the actual sequence depends on whether the focus is moved by means of the Tab key, an Alt+hotkey combination, or the mouse. In most cases, these differences are really negligible. If they aren’t, however, under VB Migration Partner you can set the VB6Config.FocusEventSupport to True for full emulation of the VB6 behavior.

Graphic-related properties and methods

You can dynamically produce graphic output on a VB6 form, usercontrol, or PictureBox control by means of methods such as Cls, PSet, Line, Circle, Print, and PaintPicture. The output of such methods can be affected by means of many properties, such as AutoRedraw, CurrentX, CurrentY, DrawMode, DrawStyle, DrawWidth, FillColor, and FillStyle. VB6 supports a few other graphic-related methods, such as Point, TextWidth, and TextHeight.

None of these properties and methods is exposed by VB.NET forms or controls. A .NET Framework application produces graphic output by means of GDI+ objects and methods, and the two programming models are completely different. In general, translating a graphic-intensive piece of VB6 code to VB.NET is a major effort that requires in-depth knowledge of the two languages. Bear in mind, for example, that VB6 graphic methods are affected by the current ScaleMode setting and that experienced VB6 developers can leverage the ScaleLeft, ScaleTop, ScaleWidth, and ScaleHeight properties to create custom coordinate systems so that the graphic output appears mirrored along the X- or Y-axis, or even rotated by 180 degrees.

VB Migration Partner fully supports all the graphic properties and methods, with the only exception of the DrawMode property. (The reason: GDI+ doesn’t support an equivalent feature.) Custom ScaleMode settings are fully supported, as are the various fill modes with hatched brushes, arcs, pies, and so forth.

hDC property

The Form, PictureBox, and UserControl classes expose the hDC readonly property, which returns the handle of the control’s device context. No similar property exists for .NET Framework. If you really need a device context handle to be passed to a Windows API method, you should use the following code sequence:

        Dim gr As Graphics = txtName.CreateGraphics()
        Dim handle As IntPtr = gr.GetHdc()
        Dim hDc As Integer = handle.ToInt32()
        ' use the hDC value here ...' release the handle and destroy the device context

It is essential that you release both the handle (with the ReleaseHdc method) before doing any other operation on the control, including a simple refresh.

Controls in VB Migration Partner’s library expose the hDC property and don’t require you to go through the previous sequence, except that you should invoke the ReleaseHdc method that the Form, PictureBox, and UserControl classes expose.

Help formats

VB6 applications can use help files in two different formats: .hlp files and .chm files. VB.NET doesn’t support the .hlp format, though.

VB Migration Partner solves this problem by using Windows API methods to display help pages.

Help-related properties and methods

Most VB6 controls can be associated to a help page by means of the HelpContextID and WhatsThisHelpID properties, and can use the ShowWhatsThis method to display help. None of these properties are supported by VB.NET controls, which in fact can display help only by means of an HelpProvider control.

VB Migration Partner correctly supports all the help-related properties and methods in converted applications.

hWnd property

The VB6 hWnd property maps to the Handle property under VB.NET. However, the Handle property returns an IntPtr value, therefore you might need to convert it to an integer during the migration process.

Image and Picture properties

A few VB6 objects – namely, the Form, UserControl, and PictureBox objects – support both the Picture property and the Image property. The difference between the two is subtle: the Picture property is writeable and allows you to load a bitmap on object’s background, for example by means of a LoadPicture method; the Image property is readonly and returns the current image contained in the object. (It may differ from the Picture property if you’ve used graphic methods to draw lines and circles on the object’s surface.)

To make matters more complicated, the actual behavior of these properties is further influenced by the AutoRedraw property. For example, consider the following sequence of actions under VB6:

  1. set AutoRedraw to True
  2. produce graphic output by means of Circle and Line methods
  3. reset AutoRedraw to False
  4. produce more graphic output with Circle and Line methods
  5. invoke the Cls method.

As surprising as it may sound, the Cls method doesn’t really clear all graphic output, because the lines and circles produced in step 2 have become part of the persistent background image: the Cls method simply restores such background image and has therefore the effect to delete only the lines and circles produced at step 4.

VB Migration Partner fully supports both the Image and Picture properties, including their relation with the AutoRedraw property. In fact, the previous sequence is translated correctly to VB.NET and behaves as intended.

Index property

VB.NET doesn’t support control arrays and consequently doesn’t support the Index property.

VB Migration Partner supports both control arrays and the Index property. If a VB.NET control was originally part of a VB6 control array, its name embeds the Index value in its last three characters. For example, the control belonging to the txtFields control array and whose Index property is 10 is named txtFields_010.

KepPress event

VB.NET supports the KeyPress event, but the mechanism for ignoring a key press is different: in VB6 you can ignore a key by setting the KeyAscii argument to zero; in VB.NET you have to set the Handled property of the KeyPressEventArgs object to True:

        Private Sub txtName_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) _
         Handles txtName.KeyPress
            ' ignore spaces
            If e.KeyChar = " "c Then e.Handled = True
        End Sub

The Upgrade Wizard converts correctly KeyPress event handlers, but generates extra code to correctly set the Handle property on exiting the event; VB Migration Partner produces readable and maintainable VB.NET code that preserves the structure and simplicity of the original VB6 code.

Left, Top, Height, and Width properties

The position and size of VB6 controls is determined by their Left, Top, Width, and Height properties; these properties are supported by VB.NET controls, but the form designer expects that these values be expressed by means of the Position and Size properties, which take a Point and a Size object, respectively.

In addition to using different properties, VB6 and VB.NET differ in how position and size values are calculated. By default, in VB6 you specify these values as twips (1 pixel = 15 twips) but the actual unit being used depends on the form’s ScaleMode property. This property can take seven values: Twips, Point, Pixel, Character, Inch, Millimeter, Centimeter, plus a special value User; when User is specified, the coordinate system is user-defined and is affected by the ScaleLeft, ScaleTop, ScaleWidth, and ScaleHeight properties. (In VB6 you can set all these properties in one step by means of the Scale method.)

VB Migration Partner fully supports all the ScaleMode variants, including the special User value, the ScaleLeft, ScaleTop, ScaleWidth, and ScaleHeight properties, and the Scale method. More precisely, the Left, Top, Width, and Height properties exposed by all the controls in the support library return a value that accounts for the current ScaleMode. Likewise, VB Migration Partner ensures that all coordinates passed as parameters or returned by methods – for example the Move, PSet, Line, Circle, TextWidth, TextHeight, ScaleX, and ScaleY methods – are interpreted correctly and work as in VB6.

Locked property

A few VB6 controls – namely the TextBox, ComboBox, RichTextBox, ImageCombo, DataCombo, and DataList – expose the Locked property. While this name isn’t reserved under VB.NET, it interferes with Visual Studio’s form designer, and in fact if a .NET control exposes such a property, then the property is shadowed by the Locked property that the form designer adds to all .NET controls. For this reason, .NET controls expose the ReadOnly instead of the Locked property.

MouseDown, MouseMove, and MouseUp events

VB.NET supports the Click, DblClick, MouseDown, MouseMove, and MouseUp events. However, the DblClick event has been renamed as DoubleClick and the coordinates passed to the MouseDown, MouseMove, and MouseUp events are always in pixels. (In VB6 these coordinates are in the current ScaleMode coordinate system.)

The Upgrade Wizard converts correctly mouse event handlers, but generates extra code to extract information out of the MouseEventArgs object passed to these events; VB Migration Partner produces readable and maintainable VB.NET code that preserves the structure and simplicity of the original VB6 code.

MousePointer and MouseIcon properties

VB.NET controls doesn’t support the MousePointer and MouseIcon properties, which have been replaced by the Cursor property.

Paint event

Form, PictureBox, and UserControl objects raise the Paint event under VB6 only if the AutoRedraw is set to False; VB.NET doesn’t support the AutoRedraw property, therefore these objects always raise the Paint event.

Controls in VB Migration Partner’s library raise the Paint property only if AutoRedraw is set to False, as in VB6.

Parent property

All visible VB6 controls expose the Parent property, which returns a reference to the form or the UserControl that contains the control, either directly or through a chain of container controls. VB.NET controls do expose a property named Parent, but it has a different meaning and returns the control’s direct container. You can often replace the Parent property with a call to the FindForm method under VB.NET, but the FindForm method returns the top-level form even when the control is hosted inside a UserControl, therefore it isn’t perfectly equivalent to the Parent property.

VB Migration Partner fully support the Parent property, which works as the original VB6 property also when the current control is hosted inside a UserControl.

Print method

VB.NET doesn’t support this method. Instead, you should use the DrawString method of the System.Drawing.Graphics object. This latter method only works with pixels, so you should convert from the current ScaleMode settings.

VB Migration Partner fully supports the Print method, including all its variations and separators (commas, semicolons, TAB() and SPC() functions, and accounts for the current ScaleMode value.

RightToLeft property

Both VB6 and VB.NET support the RightToLeft property; however, this property is a Boolean under VB6 and an enumerated value under VB.NET.

Scale, ScaleX, and ScaleY methods.

VB.NET only supports control size and position expressed in pixels, therefore these methods aren’t supported.

VB Migration Partner fully supports these methods and all the VB6 ScaleMode values, including user-defined coordinate systems, both a design-time and at runtime.

ScaleMode, ScaleLeft, ScaleTop, ScaleWidth, and ScaleHeight properties

VB.NET only supports control size and position expressed in pixels, therefore these properties aren’t supported.

VB Migration Partner fully supports these properties and all the VB6 ScaleMode values, including user-defined coordinate systems, both a design-time and at runtime. It even supports negative values for the ScaleWidth and ScaleHeight properties, so that you can create mirrored graphic motifs as you do in VB6.

SetFocus method

The SetFocus method has been renamed as Focus under VB.NET; when applied to forms, the SetFocus method maps to the Activate method.

TabIndex property

All controls on a VB6 form have a unique TabIndex value: if you assign a TabIndex value that is already in use, the Visual Basic runtime automatically adjust the TabIndex of other controls so that no duplicate value exists.

The TabIndex property works in a different manner under .NET forms. First, the TabIndex value of a control is relative to the TabIndex value of all other controls inside the same container (e.g. a Panel control). Second, two controls can have the same TabIndex value even if they are located in the same container. This difference in behavior can be confusing and can cause malfunctioning at runtime. For example, a VB6 developer can give a control the input focus simply by assigning zero to its TabIndex property; such code doesn’t work after the migration to VB.NET.

VB Migration Partner’s support library exposes the SetTabIndex6 method, which correctly replicates VB6’s behavior.

ToolTipText property

All VB6 controls expose the ToolTipText property. VB.NET controls don’t expose such a property; developers must manually add a ToolTip extender control to the form and then use the ToolTip property that the extender control adds to all controls.

Transparent controls (Label and Image)

Under VB6 you can use a Label or an Image control with a transparent background to create a rectangular “hot spot”, so that you can detect mouse activity over a portion of a larger image. Such controls are fully transparent, yet they capture all the mouse events. Many expert VB6 developers have used this feature to design forms with non-standard shapes and appearance, or irregularly-shaped controls.

This feature isn’t easily achievable under VB.NET, because you can’t create a control with transparent background. Nevertheless, VB Migration Partner manages to replicate this behavior. All the VB6 code that uses transparent controls to define hot spots works correctly after the conversion to VB.NET.

Validate event

VB.NET doesn’t support the Validate event, which has been replaced by the Validating and Validated pair of events. In practice, you should replace the VB6 Validate event handler with the VB.NET Validating event handler.

There is also a subtler behavioral difference, though: when a VB6 form is being closed – either by the end user or programmatically - no Validate event fires for the control that has the input focus. Conversely, the VB.NET form always fires a Validating event on the control that has the focus when its form is being closed.

VB Migration Partner exactly duplicates the VB6 behavior under VB.NET.

ZOrder method

All VB6 controls expose the ZOrder method. Under VB.NET, the ZOrder method is replaced by the BringToFront and SendToBack methods.

Follow Francesco Balena on VB6 migration’s group on


Read Microsoft Corp’s official case study of a VB6 conversion using VB Migration Partner.

Code Architects and its partners offers remote and onsite migration services.

More details

Subscribe to our free newsletter for useful VB6 migration tips and techniques.


To learn more about your VB6 applications, run VB6 Analyzer on your source code and send us the generated text file. You will receive a detailed report about your VB6 applications and how VB Migration Partner can help you to quickly and effectively migrate it to .NET.

Get free advice

A fully-working, time-limited Trial Edition of VB Migration Partner allows you to test it against your actual code

Get the Trial

The price of VB Migration Partner depends on the size of the VB6 application, the type of license, and other factors

Request a quote

Migrating a VB6 application in 10 easy steps

Comparing VB Migration Partner with Upgrade Wizard

Migration tools: Feature Comparison Table

All whitepapers