In Visual Basic 6.0, Control Arrays were a useful feature that allowed programmers to group a series of controls into an array structure, created and initialized by VB6. Event handling code for events raised by these controls could be written in a single event handler procedure for each event, and the index of the array element that triggered the event would be passed as a parameter to the handler procedure.
Visual Basic .NET and C# do not have the concept of Control Arrays as a native structure, maintained by the language itself. In order to convert this feature, the VBUC declares a new Array containing the controls that were included in the original VB6 Control Array and then adds extra coding to the Form Designer File to initialize those controls. The following example shows a VB6 application that has a Control Array called “Buttons”, which contains VB6 CommandButton objects, and how it is converted to C#.
Figure 1. VB6 Application showing the CommandButton controls contained in the “Buttons” array
The C# version of this form will contain the following code in the Form1.Designer.cs file, which declares all the Buttons contained in the original VB6 Control Array:
private System.Windows.Forms.Button _Buttons_4; private System.Windows.Forms.Button _Buttons_3; private System.Windows.Forms.Button _Buttons_2; private System.Windows.Forms.Button _Buttons_1; private System.Windows.Forms.Button _Buttons_0; public System.Windows.Forms.Button[] Buttons = new System.Windows.Forms.Button[5];
The VBUC will also include a new method that will explicitly add all these Button controls to the “Buttons” array:
void InitializeButtons() { this.Buttons[4] = _Buttons_4; this.Buttons[3] = _Buttons_3; this.Buttons[2] = _Buttons_2; this.Buttons[1] = _Buttons_1; this.Buttons[0] = _Buttons_0; }
This InitializeButtons method will be called right after InitializeComponent is called from the Form’s constructor. InitializeComponent will create the actual instances of the controls.
public Form1():base() { Additional code removed for clarity purposes //This call is required by the Windows Form Designer. InitializeComponent(); InitializeButton(); }
As mentioned before, in VB6 a single method could handle a specific event for all the members of the Control Array. In this example, an event handler is used to respond to the Click event of all the VB6 CommandButton controls contained in the “Buttons” Control Array:
Private Sub Buttons_Click(Index As Integer) Select Case Index Case 0 MsgBox ("Buttons(0) was clicked") Case 1 MsgBox ("Buttons(1) was clicked") Case 2 MsgBox ("Buttons(2) was clicked") Case 3 MsgBox ("Buttons(3) was clicked") Case 4 MsgBox ("Buttons(4) was clicked") End Select End Sub
In order to convert this Event Handler, the VBUC adds an “Index” variable, which corresponds to the actual index of the Button that raises the event. This completes the migration of the “Buttons” Control Array:
private void Buttons_Click( Object eventSender, EventArgs eventArgs) { int Index = Array.IndexOf(Buttons, eventSender); switch(Index) { case 0 : MessageBox.Show("Buttons(0) was clicked", …); break; case 1 : MessageBox.Show("Buttons(1) was clicked", …); break; case 2 : MessageBox.Show("Buttons(2) was clicked", …); break; case 3 : MessageBox.Show("Buttons(3) was clicked", …); break; case 4 : MessageBox.Show("Buttons(4) was clicked", …); break; } }
Figure 2. C# Application showing the Button controls contained in the “Buttons” array and responding to the Click event
The VBUC converts members of a VB6 control library to their .NET equivalents whenever possible. The corresponding .NET elements are chosen to provide functional equivalence on the target platform.
In particular scenarios, some class properties may not have a direct equivalent in .NET or may have not be mapped in the current release of the VBUC. The VBUC generates the 2064 EWI to inform the user about these specific cases.
If the Stub Generation optional feature is enabled the VBUC will create dummy declarations for these properties and reference them instead of the original reference to the not-supported property. This feature reduces the amount of compilation errors and provides the user with the possibility to manually implement the property's functionality in the stub-declaration.
It will be necessary to implement the original property functionality through other means. This goal can be achieved through one of the following approaches:
Public Sub SetComboDataSource(ByVal combo As ComboBox)
Dim rs As ADODB.Recordset
rs = CreateRecordset()
combo.DataSource = rs
End Sub
Public Sub SetComboDataSource(ByRef combo As ComboBox)
Dim CreateRecordset() As Object
Dim rs As ADODB.Recordset = CreateRecordset
'UPGRADE_ISSUE: (2064) ComboBox property combo.DataSource was not upgraded.
UpgradeStubs.VB_Control.setDataSource(combo, rs.Fields)
End Sub
Public Sub SetComboDataSource(ByRef combo As ComboBox)
Dim rs As ADODB.Recordset = TestCreateRecordset()
UpgradeStubs.VB_Control.setDataSource(combo, rs.Fields)
End Sub
Public Shared Sub setDataSource(ByVal instance As Control, ByVal DataSource As msdatasrc.DataSource)
' Include relevant implementation for application
End Sub
static public void SetComboDataSource( ComboBox combo)
{
ADODB.Recordset rs = TestDataSource.TestCreateRecordset();
//UPGRADE_ISSUE: (2064) ComboBox property combo.DataSource was not upgraded.
UpgradeStubs.VB_Control.setDataSource(combo, (msdatasrc.DataSource) rs);
}
If the target framework is .Net 3.5 an Extension Method may be used instead of the generated stub to provide cleaner looking code that more closely matches the original.
static public void SetComboDataSource( ComboBox combo)
{
ADODB.Recordset rs = TestDataSource.TestCreateRecordset();
UpgradeStubs.VB_Control.setDataSource(combo, (msdatasrc.DataSource) rs);
}
public static void setDataSource( Control instance, msdatasrc.DataSource DataSource)
{
// Include relevant implementation for application
}
8834 N Capital of Texas Hwy, Ste 302
Austin, TX 78759
Call us: +1 (425) 609-8458
info@wearegap.com