A Windows Client Using Windows Forms

All the examples so far have been command-line programs that wrote to the system console. Now that you have seen the entire development process, you will rewrite your client application to use the new Windows Forms library, which is available to all .NET languages. The example uses Visual Basic, and here is the full source-code listing:

Listing 1. Windows Forms Client in Visual Basic (ClientWinForms.vb)

Option Explicit
Option Strict

Imports System
Imports System.Collections
Imports System.Drawing
Imports System.Threading
Imports System.Windows.Forms

Imports CompCS
Imports CompVB
Imports CompVC

Public Module modmain
   Public Const vbCrLf as String = 
      Microsoft.VisualBasic.ControlChars.CrLf
   Public Class Client
      Inherits Form

      ' This code is required by the Windows Forms Designer.
      Private components As 
         System.ComponentModel.Container
      Private Button2 As System.Windows.Forms.Button
      Private Button1 As System.Windows.Forms.Button
      Private Label1 As System.Windows.Forms.Label

      Public Sub New()
         MyBase.New
         InitForm  'Required by the Windows Forms Designer.
      End Sub

      'Form overrides Dispose(Boolean) to clean up component list
      '(this Form has no components), then disposes of the base class
      Protected Overloads Overrides Sub Dispose(disposing As Boolean)
            If disposing Then
                  If Not (components Is Nothing) Then 
                        components.Dispose()
                  End If
            End If
            MyBase.Dispose(disposing)
      End Sub 

      ' This is the Main entry point for the application.
      Shared Sub Main()
         Application.Run(New Client)
      End Sub

      ' This procedure is required by the Windows Forms Designer.
      ' It can be modified using the Windows Forms Designer.  
      ' Do not modify it using the code editor.
      Private Sub InitForm()
          Me.Button1 = New Button
          Me.Button2 = New Button
          Me.Label1 = New Label

          Button1.Location = new Point(200, 230)
          Button1.TabIndex = 1
          Button1.Text = "&Close"
          Button1.Size = new Size(75, 23)
          AddHandler Button1.Click, New 
             System.EventHandler(AddressOf 
             Me.Button1_Click)

          Button2.Location = new Point(120, 230)
          Button2.TabIndex = 2
          Button2.Text = "&Execute"
          Button2.Size = new Size(75, 23)
          AddHandler Button2.Click, New 
             System.EventHandler(AddressOf 
             Me.Button2_Click)

          Label1.Location = new Point(8, 8)
          Label1.TabIndex = 0
          Label1.TabStop = False
          Label1.Text = ""
          Label1.Size = new Size(272, 232)

          Me.Text = "Client"

          Me.Controls.Add(Button2)
          Me.Controls.Add(Button1)
          Me.Controls.Add(Label1)

      End Sub

      Private Sub Button1_Click(ByVal sender As 
         System.Object, ByVal e As System.EventArgs) 
          Me.Close
      End Sub

      Private Sub Button2_Click(ByVal sender As 
         System.Object, ByVal e As System.EventArgs)
         
          ' Declare the local variables.
          Dim myCompCS As New CompCS.StringComponent
          Dim myCompVB As New CompVB.StringComponent
          Dim myCompVC As New CompVC.StringComponent

          Dim StringCount As Integer

          ' Clear the label. 
          Label1.Text = ""

          ' Display the results from the C# component.
          For StringCount = 0 To CInt(myCompCS.Count) - 1
            Label1.Text &= 
               MyCompCS.GetString(StringCount) & vbCrLf
          Next        
          Label1.Text &= vbCrLf

          ' Display the results from the Visual Basic component.
          For StringCount = 0 to CInt(MyCompVB.Count) - 1
              Label1.Text &= 
                 myCompVB.GetString(StringCount) & vbCrLf
          Next
          Label1.Text &= vbCrLf

          ' Display the results from the Visual C++ component.
          For StringCount = 0 To CInt(myCompVC.Count) - 1
              Label1.Text &= 
                 myCompVC.GetString(StringCount) & vbCrLf
          Next        
      End Sub
   End Class
End Module

In the .NET Framework SDK, the Windows Forms library is located in the System.Windows.Forms namespace. The following statement incorporates the System.Windows.Forms namespace into the program.

Imports System.Windows.Forms

By importing the namespaces, you can refer to included types, such as Button, without having to use the fully qualified type name, such as System.Windows.Forms.Button.

This next interesting line of code illustrates inheritance, one of the most powerful features of the common language runtime:

Inherits Form

With this one statement, you specify that the client class inherits all the functionality from the Form class in the Windows Forms library. Language independence is an important aspect of the runtime's inheritance model — not only can you inherit from the runtime, you can inherit from classes written in any .NET language.

Next, you declare the object types that you will be using on your form, as shown by the following line:

Private Button1 As System.Windows.Forms.Button

Now you are finally ready to execute some code. Here is the constructor for the Client form that creates an instance of the base class and calls the InitForm method:

Sub New()
   MyBase.New
   ' InitForm is required by the Windows Forms Designer.
   InitForm
End Sub

Here is the entry point for the program itself that starts everything off by creating a new instance of the Client form:

Shared Sub Main()
   Application.Run(New Client)
End Sub

The InitForm method sets up the form and all its controls. For Button1, for example, InitForm creates a new button from the Button type:

Me.Button1 = New Button

InitForm then moves it, set its caption (or Text property), and resizes it:

Button1.SetLocation(200, 248)
Button1.TabIndex = 1
Button1.Text = "&Close"
Button1.SetSize(75, 23)

Then comes the tricky part: connecting Click, which is just one of the Button type's many events, to the sample's own subroutine:

AddHandler Button1.Click, New  
   System.EventHandler(AddressOf Me.Button1_Click)

Finally, InitForm adds the button to the form's Controls collection:

Me.Controls.Add(Button1)

The following code highlights the event handler that executes when the user clicks Button1:

Private Sub Button1_Click(ByVal sender As System.Object, 
      ByVal e As System.EventArgs)
   Me.Close
End Sub

Actually, the only thing that happens here is that the form's Close method is called, thus ending the application. This particular subroutine ignores the arguments.

The essence of the program is located in the Button2_Click event handler, which uses the same code that you saw in the Visual Basic client example. Instead of writing to the console, however, the Windows Forms sample adds to the Text property of the label on the form:

Label1.Text &= 
   myCompVC.GetString(StringCount) & vbCrLf

The build process is definitely more complex. Not only do you have to specify the components that you have already built, but you also need to reference all assemblies that are required by Windows Forms:

vbc.exe /t:winexe /debug+ /optionstrict+ 
   /reference:..\Bin\CompCS.dll 
   /reference:..\Bin\CompVB.dll 
   /reference:..\Bin\CompVC.dll 
   /reference:System.dll, 
   System.Windows.Forms.dll, 
   System.Data.DLL,system.drawing.dll 
   /out:..\bin\ClientWinForms.exe ClientWinForms.vb

Running the application creates the following dialog box. When the Execute button is clicked, the strings are written to the label on the form:

See Also

A Client Using ASP.NET | Summary of Development Tutorial | Appendix A: Tools for Exploring Namespaces