A single-form C# login & registration system — tab-based navigation, a live password-strength checklist, a 3-attempt lockout timer, and system-tray notifications, built entirely with native WinForms controls.
Ninth project in the WinForms self-practice series.
Three "screens" — Login, Register, Main Program — but only one form.
No Show(), no Close() between them this time. Just a TabControl switching pages, and two Panels turning whole sections on and off at once.
Login checks a username and password against whatever was saved at registration. Three wrong attempts and the login panel locks itself for 30 seconds. Registration won't let you submit until every password rule is green. And every meaningful action — a successful login, a successful registration, a logout — gets a small system-tray balloon tip to go with it.
frmLogin
├── tabControl1
│ ├── tabPage_Login → panel_Login
│ │ ├── txtLoginUsername · txtLoginPassword
│ │ ├── chkLoginShowPassword · chkRememberMe
│ │ ├── [Login] → Login()
│ │ │ ├── IsValidLogin() → ShowSuccessfulLoginMessage() → AccessSystem()
│ │ │ └── else → ShowInvalidLoginMessage() → attempts-- → 0 left → EnableTimer()
│ │ └── linkLabel_CreateAccount → SelectRegistrationPage()
│ │
│ ├── tabPage_Register → panel1
│ │ ├── txtRegisterUsername · txtRegisterPassword · txtRegisterConfirmedPassword
│ │ ├── TextChanged → ValidatePasswordRegisteration()
│ │ │ ├── 5× Check...() → Mark/UnMarkSecurityLayer() → colored Label + PictureBox
│ │ │ ├── UpdateProgressBar() → progBar_PasswordStrength + lblCompletePercentage
│ │ │ └── all 5 pass → btnRegister.Enabled = true
│ │ └── [Register] → confirm (Cancel default) → SaveRegistrationAccount() → SelectLoginPage()
│ │
│ └── tabPage_MainProgram
│ └── [Logout] → Logout() → SelectLoginPage()
│
├── timer1_Tick → TimerCount-- → 0 → DisableTimer()
└── menuStrip_App "App" → ToolStripMenuItem_Click
├── Logout (Alt+Shift+L)
└── Exit Program (Alt+Shift+E)
| Section | Feature |
|---|---|
| Login | Username/password check, 3 attempts before a 30-second lockout, Show Password, Remember Me |
| Register | Live password-strength checklist (length, digits, upper/lower case, symbols, match), confirm dialog, Register button only enabled once every rule passes |
| Main Program | Landing page, Logout, and an App menu with Logout / Exit Program shortcuts |
World Explorer switched screens with separate forms and Show()/Close(). Here, all three screens live in one TabControl, switched with tabControl1.SelectedTab = .... No new form instance, no state to pass between windows — useful when the screens need to share the same in-memory session, like the credentials that only exist for as long as the app is open.
private void SelectMainPage()
{
tabControl1.SelectedTab = tabPage_MainProgram;
panel_Logout.Enabled = true;
}Earlier projects checked string.IsNullOrWhiteSpace() by hand before acting. This one hooks into WinForms' own Validating event and lets ErrorProvider do the flagging:
private void txt_Validating(object sender, CancelEventArgs e)
{
if (string.IsNullOrWhiteSpace(((TextBox)sender).Text))
{
e.Cancel = true;
((TextBox)sender).Focus();
errorProvider1.SetError(((TextBox)sender), "Text Field Should have a Value!");
}
else
{
e.Cancel = false;
errorProvider1.SetError(((TextBox)sender), "");
}
}e.Cancel = true keeps focus trapped on the field until it's actually filled in — the control enforces the rule itself instead of the code checking after the fact.
Five independent rules — length, digits, upper/lower case, symbols, confirmed match — each toggle their own colored Label and PictureBox through one shared pair of helpers:
private void MarkSecurityLayer(Label lbl, PictureBox PicBox)
{
ChangeLabelToGreen(lbl);
ChangePictureBoxToTrue(PicBox);
}Same instinct as the Tag-based button handler from earlier projects — one small helper, reused five times — but here it drives a progress bar too: each passing rule adds 20%, so UpdateProgressBar() and the Register button's enabled state both fall out of the same five checks.
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
switch (((ToolStripMenuItem)sender).Tag)
{
case "Logout": Logout(); break;
case "Exit": Exit(); break;
}
}Same Tag-and-switch idiom as btn_Click, just pointed at ToolStripMenuItem instead of Button. The pattern generalizes past the control type it started on.
private DialogResult ShowConfirmRegisterationMessage()
{
return (MessageBox.Show("Are you sure you want to Register ?",
"Confirm!", MessageBoxButtons.OKCancel,
MessageBoxIcon.Question, MessageBoxDefaultButton.Button2));
}Same MessageBoxDefaultButton.Button2 habit from World Explorer and the To Do List, now guarding account creation instead of a delete.
Credentials live only in memory, on the login textboxes' Tag properties, for as long as the form is open — there's no file, no database, no hashing. That's fine here: the project is practicing UI state, validation, and event patterns, not building a real authentication backend. Worth keeping in mind before this pattern gets reused somewhere it needs to actually be secure.
| Control | First used here | Purpose |
|---|---|---|
| TabControl / TabPage | ✅ Yes | Switches between Login / Register / Main Program without separate forms |
| CheckBox | ✅ Yes | Remember Me, Show Password toggles |
| Panel | ✅ Yes | Enables/disables the Login and Logout sections as a unit |
| ProgressBar | ✅ Yes | Live password-strength meter |
| ErrorProvider | ✅ Yes | Required-field validation icons via the Validating event |
| Timer | ✅ Yes | 30-second login lockout countdown |
| NotifyIcon | ✅ Yes | System-tray balloon tips on login / register / logout |
| MenuStrip / ToolStripMenuItem | ✅ Yes | App menu (Logout, Exit Program) with keyboard shortcuts |
| PictureBox | Reused | Green/red check icons for each password rule |
| LinkLabel | Reused | "Create Account" link |
| MessageBox | Reused | Login errors, confirm-register dialog |
| Language | C# |
| Framework | .NET Framework |
| UI | Windows Forms (WinForms) |
| IDE | Visual Studio |
| Type | Desktop Application — Single-Form |
| Controls Used | Form · Label · TextBox · Button · CheckBox · LinkLabel · TabControl · Panel · ProgressBar · PictureBox · ErrorProvider · Timer · NotifyIcon · MenuStrip · MessageBox |
| Project | Application |
|---|---|
| Project 25 — Tax Calculator | Tax computation + session history |
| Project 26 — Text Encryption | Caesar Cipher encrypt/decrypt |
| Project 27 — Password Generator | GUID + Key + Password generator |
| Project 28 — Age Calculator | Full age breakdown with time lived |
| Project 29 — String Manipulation | Live string operations toolkit |
| Project 30 — Simple Calculator | Full calculator with theme toggle |
| Project 31 — World Explorer | Multi-form geography encyclopedia |
| Project 32 — To Do List | Task manager with priorities, due dates, and live stats |
| Project 33 — Login Form (you are here) | Login/registration system with live validation and a lockout timer |
| More projects | Next control groups 🔄 |
- ✅ Course 14 — C# Level 1 (Stage Two, in progress)
- ✅ Ninth project in the WinForms self-practice series
- ✅ First use of TabControl, CheckBox, Panel, ProgressBar, ErrorProvider, Timer, NotifyIcon, and MenuStrip
- ✅ Part of the Programming Advices Roadmap — Stage Two
Thank you to:
Next control group.
Next project.