Theory
Workers you cannot see
Drag a Timer from the Toolbox onto ShopKeeper's form and something odd happens: it refuses to sit ON the form. It drops into a tray below the designer instead.
Not a bug. You have just met your first component: a Toolbox citizen with no face. Controls occupy screen space; components do their work invisibly: keeping time, stocking images, flagging errors, answering F1. The till needs 4 of them, and the tray is where they live.
Theory
Component vs control, formally
A control is visible: it has a position, a size, a place in the user's view (Button, TextBox, DataGrid).
A component provides functionality WITHOUT its own screen presence; at design time it sits in the component tray beneath the form.
The exam's favourite phrasing: all controls are components, but not all components are controls: the visible ones inherit extra machinery for drawing themselves. If it has no face, look for it in the tray, and configure it through the Properties window like anything else.
At a glance
The tray's 4 workers
| Component | Job | The one call to remember |
|---|---|---|
| ImageList | Stocks same-sized images others borrow | ImageList1.Images.Add(...); used by index |
| ErrorProvider | Blinking icon + tooltip beside bad input | ErrorProvider1.SetError(txtPrice, "Price must be a number") |
| HelpProvider | F1 help text per control | HelpProvider1.SetHelpString(txtQty, "Enter quantity") |
| Timer | Fires Tick every Interval milliseconds | Timer1.Interval = 1000 : Timer1.Start() |
Practical
A living clock and a polite error
Public Class BillingForm
Private Sub BillingForm_Load(sender As Object, e As EventArgs) _
Handles MyBase.Load
tmrClock.Interval = 1000 ' milliseconds: 1 second
tmrClock.Start()
End Sub
Private Sub tmrClock_Tick(sender As Object, e As EventArgs) _
Handles tmrClock.Tick
lblClock.Text = Now.ToString("HH:mm:ss") ' beats once a second
End Sub
Private Sub btnAdd_Click(sender As Object, e As EventArgs) _
Handles btnAdd.Click
If IsNumeric(txtPrice.Text) Then
errProv.SetError(txtPrice, "") ' clear: input is fine
Else
errProv.SetError(txtPrice, "Price must be a number")
End If
End Sub
End Class
Quiz
Timer1.Interval = 5000 and Timer1.Start() have run. What happens next?
- The Tick event fires every 5 seconds until Stop() is called
- The Tick event fires once, after 5 seconds, then the timer stops
- The program pauses for 5 seconds, like a Sleep call
- Tick fires 5000 times per second
Show the answer
The Tick event fires every 5 seconds until Stop() is called
Interval is the gap in MILLISECONDS between Ticks, and a started WinForms Timer keeps ticking on that rhythm until you call Stop(): 5000 means every 5 seconds, repeatedly. Option B describes a one-shot timer, which you would build yourself by calling Stop() inside the first Tick. Option C is the crucial misreading: a Timer never blocks; the program stays fully responsive between Ticks, which is exactly why it beats a pause loop. Option D reads the milliseconds upside down.
Think first
Why not just MsgBox the error?
Both are 1 line: MsgBox("Price must be a number") versus errProv.SetError(txtPrice, "..."). Picture the cashier mid-rush with 6 customers queuing. Argue for the ErrorProvider before tapping.
Show the answer
The MsgBox halts everything: a modal box demands a click before any other work continues, once per mistake, with the queue watching. The ErrorProvider annotates instead of interrupting: a blinking icon appears beside the exact guilty field, the message waits in its tooltip, the cashier fixes it when their hands are free, and SetError(ctrl, "") clears it. Same information, opposite manners. Design rule worth keeping beyond this exam: point at problems where they live; do not stop the world to announce them.
Watch out
Tray traps
Interval is milliseconds: writing 1 and expecting 1 second gives a Tick storm at millisecond pace; 1 second = 1000.
A stopped Timer is silent: forgetting Start() (or Enabled = True) is the most common "my clock is frozen" bug.
ErrorProvider errors do not clear themselves: after the user fixes the input, call SetError(ctrl, "") or the icon blinks forever at innocent data.
ImageList images must share one size: it scales everything to its ImageSize; mixed originals come out distorted.
Theory
A polished till, for free
Notice how cheaply professionalism arrived: a live clock (Timer + 1 line), inline validation that never interrupts (ErrorProvider), F1 answers for the new employee (HelpProvider), and consistent icons everywhere (ImageList). None needed a visible control or 10 lines of code. And file the Timer beside BCA403's reminder thread in your head: both solve "do something on a schedule"; the WinForms Timer is the UI-friendly, single-threaded cousin. Next lesson: menus and dialog boxes, plus VB.NET's 2 styles of error handling.
Summary
Key takeaways
- Components work without screen presence and live in the component tray; controls are their visible cousins.
- ImageList stocks same-sized images that TreeView, ListView and buttons reference by index.
- ErrorProvider.SetError(ctrl, msg) blinks beside bad input; SetError(ctrl, "") clears it: validation without modal interruptions.
- HelpProvider attaches per-control F1 help via SetHelpString.
- Timer fires Tick every Interval MILLISECONDS after Start(), repeatedly, without blocking the program.
- 1 second = Interval 1000; a never-started Timer never ticks.
- Memory hook: no face, in the tray, still on the payroll.