By Tim Daniels, ASNA US

This article provides an example of a Windows Form application that navigates between two forms and shows a way to pass data from a parent form to a child form. The program performs the following functions:

A screenshot of the two forms is shown below in Figure 1.

Figure 1. The Customer List Form and the Customer Details Form

Two Windows forms are used in this application. The Customer List form contains a DataGridView to display a list of customer numbers and names. The second form, the Customer Details form, uses labels and text boxes to display the selected customer information.

Selecting a row in the DataGridView

The DataGridView is a useful component for displaying a list of data elements in a grid or spreadsheet style. This example uses two DataGridView events to display the child form:

Although the row header is handy, it’s not always intuitive to users to click only in this area to select a row, so it’s often a good idea to also observe the CellDoubleClick event for row selection. The event handlers for these two events are shown below. Because they both need the exact same action, they both call the ShowDetailsForm() method, passing it the row selected.

Capturing the Selected Customer Information

The ShowDetailsForm() subroutine, shown below, is charged with capturing customer data, instancing the details form, and then showing it. The two lines that assign values to customerNumber and customerName are arbitrarily wrapped, using the -> symbol, in the figure below to avoid unusual text wrapping in the displayed text. In your code, these two lines should be two single lines of code.

The RowNumber parameter indicates what row was selected, then two intermediate fields are declared: customerNumber and customerName. These will be passed as arguments to the constructor of the CustomerDetails form. Another field called details is defined as an instance of the class CustomerDetails. Derived from System.Windows.Forms.Form, CustomerDetails is the child form.

Next, the two intermediate fields are populated with data from the selected row of the DataGridView. This is accomplished by interrogating two collections in the DataGridView; the SelectedRows collection and its Cells collection. Since only one row can be selected by clicking on the row header or a row, the selected row is at index zero of the SelectedRows collection. The customer number cell in the DataGridView is named “CustomerNumber” and the customer name cell is named “CustomerName.” These indices are used with the Row’s Cells property to fetch the corresponding values. The screenshow below in Figure 2 shows the DataGridView’s column properties where the column name is assigned (in this case you can see the CustomerNumber column in yellow).

Figure 2. The DataGridView’s column properties

The ToString () method is used to convert the object values of the DataGridView selected row into strings, before they are assigned to customerNumber and customerName. As long as the customer number string has all numeric data, AVR’s direct assignment operator (the = sign) coerces the source value to the *Packed target value type (just as the MOVE operation code would do). (If the implicitness of AVR’s assignment operator offends your convictions about writing strongly-typed code you can also manually convert the string value with .NET’s Convert.ToInt32() method.)

Finally, the *NEW keyword creates a new instance of the CustomerDetails form. The intermediate fields customerNumber and customerName are passed to the constructor subroutine of the details instance of the CustomerDetails class. The last line of code in the subroutine, details.Show (), executes the Show() method of the CustomerDetails Form class, which displays the form nonmodally. Because Show() is nonmodal, this means the user can display more than one instance of the CustomerDetails form concurrently. A user might want to do this to see two results side-by-side (for example, comparing two graphs). An additional feature of the Show() method is that the .NET runtime implicitly closes (or disposes) the form–no programmer cleanup required for forms displayed with Show().

Passing Data to the Customer Details Form

A way is needed to get the customer name and number to the Customer Details form. A way to do this is through the form’s constructor (which is a special-case subroutine, that every AVR class has available, that runs when the class is instanced). In some ways, the constructor is functionally similar to green-screen RPG’s *INZSR subroutine in that both are implicitly called at program (or class) startup time. The code below shows the Customer Details form’s constructor with the two necessary parameters added. In Windows System.Windows.Forms.Form classes  you’ll notice that their constructors always have a call to InitializeComponent(). This routine writes up all of the internals of the controls on a Windows form. Always add your constructor-specific code after this line. In this case, the incoming customer number and name are assigned to corresponding textboxes on the form.

This is but one pattern you can use to instance Windows forms and pass data to them. Future articles will look at others to accomplish this task.