Skip to content
AgileLogics
7 min read

Windows Forms Basics

Prerequisites: Events

Windows Forms (WinForms) is .NET's classic toolkit for Windows desktop applications, and the place where Visual Basic has always been strongest. It runs on modern .NET (Windows only).

Creating a project

dotnet new winforms -lang VB -o InvoiceApp
cd InvoiceApp
dotnet run

In Visual Studio, choose Windows Forms App with Visual Basic. The designer lets you drag controls (buttons, text boxes, grids) from the Toolbox onto a form, set their properties in the Properties window, and double-click a control to create its event handler. The designer writes the layout code into Form1.Designer.vb for you.

A form written by hand

To see what the designer produces, here is a small form built in code:

' illustrative: a Windows Forms project (opens a window)
Public Class TipForm
    Inherits Form

    Private ReadOnly amountBox As New TextBox With {.Left = 120, .Top = 20, .Width = 120}
    Private ReadOnly percentBox As New NumericUpDown With {.Left = 120, .Top = 55, .Value = 15}
    Private ReadOnly resultLabel As New Label With {.Left = 20, .Top = 130, .Width = 260}
    Private WithEvents calculateButton As New Button With {.Text = "Calculate", .Left = 120, .Top = 90}

    Public Sub New()
        Text = "Tip Calculator"
        ClientSize = New Size(300, 170)
        Controls.Add(New Label With {.Text = "Bill amount:", .Left = 20, .Top = 23})
        Controls.Add(New Label With {.Text = "Tip %:", .Left = 20, .Top = 58})
        Controls.AddRange({amountBox, percentBox, calculateButton, resultLabel})
    End Sub

    Private Sub CalculateButton_Click(sender As Object, e As EventArgs) Handles calculateButton.Click
        Dim amount As Decimal
        If Not Decimal.TryParse(amountBox.Text, amount) OrElse amount < 0 Then
            MessageBox.Show("Please enter a valid amount.", "Tip Calculator", MessageBoxButtons.OK, MessageBoxIcon.Warning)
            Return
        End If
        Dim tip = amount * percentBox.Value / 100
        resultLabel.Text = $"Tip: {tip:C}   Total: {amount + tip:C}"
    End Sub
End Class

Module Program
    <STAThread>
    Sub Main()
        Application.EnableVisualStyles()
        Application.Run(New TipForm())
    End Sub
End Module
  • A form is a class that Inherits Form; controls are objects added to its Controls collection.
  • WithEvents + Handles calculateButton.Click connects the button's Click event to the handler — exactly what the designer generates.
  • MessageBox.Show displays a dialog; validate input before using it.
  • {tip:C} formats as currency in the user's regional settings.

Common controls

Control Use
Label, TextBox, Button text, input, actions
CheckBox, RadioButton, ComboBox, ListBox choices
NumericUpDown, DateTimePicker numbers and dates
DataGridView editable tables, often bound to a list or database
MenuStrip, ToolStrip, StatusStrip menus, toolbars, status bar
OpenFileDialog, SaveFileDialog picking files
Timer run code at intervals

Data binding

Controls can display data directly from your objects:

' illustrative: inside a form with a DataGridView named grid
Public Class Product
    Public Property Name As String
    Public Property Price As Decimal
End Class

Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Dim products As New ComponentModel.BindingList(Of Product) From {
        New Product With {.Name = "Tea", .Price = 3.5D},
        New Product With {.Name = "Coffee", .Price = 4.25D}
    }
    grid.DataSource = products
End Sub

A BindingList(Of T) updates the grid automatically when items are added or removed.

Good practice

  • Keep business logic out of the form: put calculations and data access in separate classes (ideally a class library) and call them from event handlers. That code can then be unit tested.
  • Use Async event handlers for slow work so the window doesn't freeze.
  • Set TabIndex and keyboard shortcuts (&Save makes Alt+S work) for accessibility.

WPF is the other VB-supported desktop framework (dotnet new wpf -lang VB): XAML-based layouts, styles, and data binding suited to richer UIs.