C# WinForms Tutorial
A Windows Forms (WinForms) a Microsoft .NET keretrendszerének része, amely asztali alkalmazások grafikus felületének (GUI) fejlesztését teszi lehetővé.
Ebből a tutorialból megtanulhatod, hogyan építs gyorsan és hatékonyan Windows szoftvereket C# nyelven, használva a beépített Toolbox vizuális vezérlőit (Controls).
Tudtad? Bár a WinForms egy régebbi technológia a WPF-hez (Windows Presentation Foundation) képest, hatalmas elterjedtsége és rendkívül gyors "Drag & Drop" (húzd és ejtsd) fejlesztési modellje miatt a mai napig az egyik legnépszerűbb választás belső céges szoftverek és prototípusok fejlesztéséhez.
Hogyan kezdj neki?
1. Visual Studio Telepítése
1. Látogass el a visualstudio.microsoft.com oldalra.
2. Töltsd le a Visual Studio Community verziót (ingyenes).
3. A telepítőben (Visual Studio Installer) pipáld be a .NET desktop development csomagot.
4. Kattints az Install gombra.
2. Első Projekt Létrehozása
1. Nyisd meg a Visual Studio-t.
2. Kattints a Create a new project gombra.
3. Keress rá a Windows Forms App (.NET) sablonra C# jelzéssel.
4. Nevezd el a projektet (pl. ElsoAlkalmazas), és nyomj a Create-re.
5. Megjelenik egy üres Form (ablak). A bal oldali Toolbox-ból húzhatsz rá elemeket, a jobb oldali Properties panelen pedig formázhatod őket.
C# WinForms Események (Events)
A WinForms programozás Eseményvezérelt (Event-Driven). A program alapjáraton várakozik. Amikor a felhasználó interakcióba lép a felülettel (kattint, gépel), a háttérben lefut egy eseménykezelő (Event Handler) metódus.
A Leggyakoribb Események
| Esemény neve | Mikor fut le? | Tipikus használat |
|---|---|---|
| Click | Kattintás az elemen | Gomb (Button) megnyomása, mentés, adatküldés |
| TextChanged | Bármilyen szövegmódosításkor | Élő keresés, jelszóerősség-mérő frissítése |
| MouseEnter | Egérkurzor az elem fölé ér | Hover effektek (gomb színének megváltoztatása) |
| Load | Amikor a Form betöltődik | Adatok beolvasása adatbázisból induláskor |
Hogyan hozzunk létre eseményt? A tervezőben (Designer) dupla kattintással egy vezérlőn automatikusan létrejön az alapértelmezett esemény (pl. Gombnál a Click). Más eseményekhez használd a Properties ablak villám (Events) ikonját!
Gomb Események Példa (Hover és Click)
Hogyan animáljunk egy gombot, és hogyan tüntessük el kattintáskor:
// 1. Kattintás esemény (Click)
private void btnVarazslat_Click(object sender, EventArgs e)
{
MessageBox.Show("Bumm! Ez egy kattintás volt!");
// Az elem láthatatlanná válik
btnVarazslat.Visible = false;
}
// 2. Egér ráhúzása (MouseEnter)
private void btnVarazslat_MouseEnter(object sender, EventArgs e)
{
// Háttérszín módosítása és gomb eltolása (X tengely)
btnVarazslat.BackColor = Color.Yellow;
btnVarazslat.Left += 10;
}
// 3. Egér lehúzása (MouseLeave)
private void btnVarazslat_MouseLeave(object sender, EventArgs e)
{
// Eredeti rendszer-szín visszaállítása
btnVarazslat.BackColor = SystemColors.Control;
btnVarazslat.Left -= 10;
}
C# WinForms Adatbekérés és Validáció
A legfontosabb szabály a szoftverfejlesztésben: Soha ne bízz a felhasználói bemenetben! A TextBox mindig string (szöveg) típust ad vissza. Ha ezt számként kezeled, konvertálnod kell.
A Parse vs TryParse probléma
Az int.Parse(txtSzam.Text) hibára fut (Exceptiont dob), ha a felhasználó betűt vagy üres szóközt ír be. Emiatt a program kifagy.
A megoldás a TryParse, amely sosem fagyasztja ki a programot, hanem egy Boolean (igaz/hamis) értékkel jelzi, hogy sikerült-e a konverzió.
Biztonságos konverzió (int.TryParse)
Nézzük meg egy egyszerű négyzetre emelő kalkulátor kódját:
private void btnKiszamol_Click(object sender, EventArgs e)
{
// A TryParse megvizsgálja a txtBemenet.Text-et.
// Ha szám, akkor a kimeneti (out) 'szam' változóba teszi, és true-t ad vissza.
bool sikeresE = int.TryParse(txtBemenet.Text, out int szam);
if (sikeresE)
{
// Biztosak lehetünk benne, hogy a 'szam' egy valid egész szám
int negyzet = szam * szam;
lblEredmeny.Text = "Eredmény: " + negyzet.ToString();
lblEredmeny.ForeColor = Color.Green;
}
else
{
// Szebben kezeljük a hibát
lblEredmeny.Text = "Hiba: Csak egész számot írhatsz be!";
lblEredmeny.ForeColor = Color.Red;
// Mező ürítése és a fókusz visszaadása, hogy a user javíthasson
txtBemenet.Clear();
txtBemenet.Focus();
}
}
További típusok: Nem csak `int`, hanem `double.TryParse()`, `decimal.TryParse()` és `DateTime.TryParse()` is létezik a tört számok és dátumok biztonságos beolvasásához.
C# WinForms MessageBox
A MessageBox egy beépített kis felugró (modális) ablak, amely tökéletes információk, figyelmeztetések megjelenítésére, vagy a felhasználó jóváhagyásának kikérésére (Igen/Nem).
MessageBox paraméterei
A MessageBox több paramétert is elfogad. A teljes szintaxis a következő:
Egyszerű Értesítés (Hiba ikonnal)
// Csak egy OK gomb és egy piros X ikon jelenik meg
MessageBox.Show("A fájl nem található!", "Olvasási hiba", MessageBoxButtons.OK, MessageBoxIcon.Error);
Megerősítés Kérése (Igen/Nem)
Hogyan kérdezzük meg a felhasználót törlés előtt, és hogyan dolgozzuk fel a válaszát a DialogResult enum segítségével:
private void btnTorles_Click(object sender, EventArgs e)
{
// Felteszünk egy kérdést Igen/Nem gombokkal és egy kérdőjel ikonnal
DialogResult valasz = MessageBox.Show(
"Biztosan törölni szeretnéd a kijelölt elemet?",
"Megerősítés",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question
);
// Megvizsgáljuk, mit nyomott a felhasználó
if (valasz == DialogResult.Yes)
{
// Tényleges törlés logikája
Adatbazis.Torol(id);
MessageBox.Show("Sikeres törlés!", "Infó", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
// Nem csinálunk semmit, a törlés megszakítva
}
}
C# WinForms UI Vezérlők (Controls)
Választó Vezérlők (CheckBox, RadioButton, ComboBox)
Ezekkel a vezérlőkkel a felhasználó opciókat választhat ki. Mindegyiknek megvan a maga célja a felhasználói élmény (UX) szempontjából.
- CheckBox (Jelölőnégyzet): Akkor használjuk, ha több dolgot is ki lehet választani (pl. Extra feltétek egy pizzán, vagy ÁSZF elfogadása). Állapota:
.Checked(true/false). - RadioButton (Választógomb): Csoportosítva működik (GroupBox-ban). Egyszerre mindig csak EGYET lehet kiválasztani (pl. Kicsi / Közepes / Nagy méret).
- ComboBox (Legördülő lista): Nagyon sok opció esetén helytakarékos megoldás (pl. Ország kiválasztása).
Összetett Űrlap Logika
Nézzük meg egy dinamikus űrlap kódját, ahol az elemek befolyásolják egymást:
private void Form1_Load(object sender, EventArgs e)
{
// ComboBox feltöltése induláskor
cmbOrszag.Items.Add("Magyarország");
cmbOrszag.Items.Add("Ausztria");
cmbOrszag.Items.Add("Németország");
// 0. indexű (Magyarország) kiválasztása alapból
cmbOrszag.SelectedIndex = 0;
// A tovább gomb induláskor nem kattintható
btnTovabb.Enabled = false;
}
// A CheckBox CheckedChanged eseménye lefut, ha bekattintják vagy kiveszik a pipát
private void chkASZF_CheckedChanged(object sender, EventArgs e)
{
// A gomb aktív lesz, ha be van pipálva, különben inaktív
btnTovabb.Enabled = chkASZF.Checked;
}
private void btnTovabb_Click(object sender, EventArgs e)
{
// Kiolvasás a RadioButton-ból
string nem = rbFerfi.Checked ? "Férfi" : "Nő";
// Kiolvasás a ComboBox-ból (A SelectedItem egy object-et ad, muszáj ToString-ezni)
string orszag = cmbOrszag.SelectedItem.ToString();
MessageBox.Show($"Sikeres regisztráció: {nem}, {orszag}");
}
C# WinForms PictureBox
A PictureBox vezérlőt képek megjelenítésére használjuk. Akár lokális fájlból, akár erőforrásból (Resources), akár internetről töltjük be a képet.
SizeMode tulajdonság
Nagyon fontos a SizeMode beállítása a tervezőben vagy kódban, különben a kép kilóg a dobozból:
- Normal: A kép bal felső sarka igazodik, kilóg ha nagyobb a doboznál.
- StretchImage: Torzítva kitölti a dobozt. Általában rosszul néz ki.
- Zoom: Arányosan kicsinyíti/nagyítja a képet (A legjobb opció fotókhoz!).
Képek betöltése futásidőben
private void btnBetolt_Click(object sender, EventArgs e)
{
// 1. Kép betöltése egy fájl elérési útjából (Lokális)
// A @ jel kell a string elé, hogy a backslasheket (\) sima karakterként kezelje
pictureBox1.Image = Image.FromFile(@"C:\Képek\profil.jpg");
// Zoom mód beállítása kódból
pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
}
private void btnInternet_Click(object sender, EventArgs e)
{
// 2. Kép betöltése internetes URL-ről (Kicsit lassabb lehet)
pictureBox1.Load("https://w3schools.com/images/picture.jpg");
}
C# WinForms ListBox mélyvíz
A ListBox az egyik legsokoldalúbb vezérlő többelemes adatok (feladatok, nevek, logok) megjelenítésére.
Fontos tulajdonságok és metódusok
Items.Add(obj): Új elem hozzáadása a végére.Items.Insert(index, obj): Elem beszúrása egy adott pozícióra.Items.Remove(obj): Elem eltávolítása a szövege alapján.Items.RemoveAt(index): Elem eltávolítása sorszám alapján.Items.Clear(): A teljes lista kiürítése.SelectedIndex: Az aktuálisan kijelölt elem sorszáma (0-tól indul). -1, ha semmi nincs kijelölve.
Komplex Példa: Keresőmotor a Listában
Beírunk egy szótétöredéket, és a program megkeresi és kijelöli az első egyezést (kis- és nagybetű függetlenül).
private void btnKeres_Click(object sender, EventArgs e)
{
// A keresett szót kisbetűssé alakítjuk (ToLower), és levágjuk a szóközöket (Trim)
string mitKeresunk = txtKeres.Text.ToLower().Trim();
if (mitKeresunk == "") return; // Ne keressünk üreset
// Végigiterálunk a lista összes elemén
for (int i = 0; i < lstAdatok.Items.Count; i++)
{
// Lekérjük a lista i-edik elemét string formában
string aktualisElem = lstAdatok.Items[i].ToString().ToLower();
// Ha a string tartalmazza (Contains) a keresett szöveget
if (aktualisElem.Contains(mitKeresunk))
{
// Kijelöljük az indexet
lstAdatok.SelectedIndex = i;
// Megállítjuk a függvényt, megvan az eredmény
return;
}
}
// Ha lefutott a ciklus és nem állt meg a return-nél, akkor nem találta meg
MessageBox.Show("Nincs egyezés a listában!", "Info");
}
C# WinForms Timer (Időzítő)
A Timer egy láthatatlan vezérlő, amely adott időközönként (Interval) folyamatosan elsüt egy eseményt (Tick). Tökéletes órákhoz, animációkhoz, és háttérfolyamatok frissítéséhez.
A Timer lelke: Az Interval
Az Interval tulajdonság ezredmásodpercben (ms) értendő. 1000 ms = 1 másodperc.
Figyelem: A WinForms Timer a fő UI szálon fut (Single-threaded). Ha nagyon bonyolult, lassan lefutó kódot teszel a Tick eseménybe, a teljes grafikus felület be fog fagyni (szaggat). Ne használj Timert nehéz adatbázis lekérdezésekhez!
Visszaszámláló készítése
A tervezőben adj hozzá egy Timert (timer1), állítsd az Interval-ját 1000-re, és generáld le a Tick eseményét.
// Osztály szintű változó, tárolja a másodperceket
int hatralevoIdo = 10;
private void btnIndit_Click(object sender, EventArgs e)
{
// Elindítjuk az időzítőt
timer1.Start();
// Letiltjuk a gombot, amíg fut a stopper
btnIndit.Enabled = false;
}
// Ez a függvény pontosan 1 másodpercenként (1000ms) hívódik meg automatikusan
private void timer1_Tick(object sender, EventArgs e)
{
hatralevoIdo--; // Csökkentjük az időt
lblOra.Text = $"Hátralévő idő: {hatralevoIdo} mp";
if (hatralevoIdo <= 0)
{
timer1.Stop(); // Időzítő leállítása
MessageBox.Show("Lejárt az idő!", "Bumm!");
// Alaphelyzetbe állítás
hatralevoIdo = 10;
btnIndit.Enabled = true;
}
}
C# WinForms Több Ablak Kezelése
Egy komplexebb asztali alkalmazás sosem áll egyetlen Formból. Meg kell tanulnunk ablakokat nyitni, és adatokat mozgatni (passzolni) köztük.
Show() vs ShowDialog()
Amikor megnyitsz egy második ablakot, kétféleképpen teheted meg:
.Show(): Megnyitja az ablakot, de a kód fut tovább. Párhuzamosan tudod használni mindkét ablakot (Modelless)..ShowDialog(): Megnyitja az ablakot, és a kód megáll itt! Várakozik, amíg a második ablak be nem zárul. Nem tudsz visszakattintani a főablakra. (Modális). Ezt használjuk beállításokhoz és bejelentkezéshez.
Login Rendszer: Adat átadása VISSZAfelé (Properties)
Megnyitunk egy Login formot (Form2). Ha sikeres, a Form1 visszakapja a felhasználónevet.
// ========== LoginForm.cs (A 2. ablak kódja) ==========
// Ez egy publikus tulajdonság (Property). A Form1 képes lesz kiolvasni.
public string SikeresFelhasznalo { get; private set; }
private void btnBelepes_Click(object sender, EventArgs e)
{
if (txtFelhasznalonev.Text == "admin" && txtJelszo.Text == "123")
{
// Eltároljuk a nevet a Property-be
SikeresFelhasznalo = txtFelhasznalonev.Text;
// A DialogResult-ot OK-ra állítjuk. Ez automatikusan BEZÁRJA ezt az ablakot is!
this.DialogResult = DialogResult.OK;
}
else
{
MessageBox.Show("Hibás azonosítás!");
}
}
// ========== Form1.cs (A főablak, ahonnan hívjuk) ==========
private void btnLoginMegnyitas_Click(object sender, EventArgs e)
{
LoginForm loginAblak = new LoginForm();
// A ShowDialog() megnyitja, és a kód ITT MEGÁLL, amíg az be nem zárul.
// Amikor bezárul, megvizsgáljuk, hogy a DialogResult OK volt-e (tehát jó volt a jelszó).
if (loginAblak.ShowDialog() == DialogResult.OK)
{
// Mivel az ablak lefutott, kiolvashatjuk a publikus Property-jét!
lblKoszonto.Text = "Üdv a rendszerben, " + loginAblak.SikeresFelhasznalo;
}
}
C# WinForms Fájlok olvasása (I/O) és CSV
A szoftverek adatait legtöbbször relációs adatbázisok (SQL) tárolják, de kisebb projekteknél vagy exportálásnál a sima szöveges fájlok (TXT, CSV) írása/olvasása elengedhetetlen.
A System.IO névtér
Mielőtt bármilyen fájlműveletet végzel, a kódfájlod legtetejére be kell szúrnod: using System.IO;. Ez tartalmazza a File statikus osztályt.
Szöveges fájl (TXT) betöltése OpenFileDialog-gal
private void btnMegnyit_Click(object sender, EventArgs e)
{
// 1. Létrehozzuk a beépített Windows fájl tallózó ablakot
OpenFileDialog opf = new OpenFileDialog();
// Beállítjuk a szűrőt (Csak TXT fájlokat engedjen választani)
opf.Filter = "Szöveges fájlok (*.txt)|*.txt";
opf.Title = "Válassz ki egy jegyzetet";
// 2. Megnyitjuk, és ha a felhasználó a "Megnyitás" gombra kattintott (OK)
if (opf.ShowDialog() == DialogResult.OK)
{
// 3. A File.ReadAllText beolvassa a fájl teljes tartalmát EGYETLEN stringbe
string teljesSzoveg = File.ReadAllText(opf.FileName);
// 4. Megjelenítjük egy TextBox-ban (Aminek be van kapcsolva a Multiline tulajdonsága!)
txtJegyzet.Text = teljesSzoveg;
}
}
CSV fájl soronkénti beolvasása és darabolása (Split)
Tegyük fel, az adatok.csv fájl ilyen sorokat tartalmaz: Terméknév,Ár,Készlet (pl. Laptop,250000,5).
private void btnCSV_Click(object sender, EventArgs e)
{
// A ReadAllLines egy String TÖMBÖT (string[]) ad vissza. Minden elem egy sor a fájlban.
string[] sorok = File.ReadAllLines(@"C:\mappa\adatok.csv");
foreach (string sor in sorok)
{
// A Split(',') darabokra vágja a sort a vesszők mentén
// A "Laptop,250000,5" ebből egy 3 elemű tömb lesz: adatok[0], adatok[1], adatok[2]
string[] adatok = sor.Split(',');
if (adatok.Length >= 3)
{
string nev = adatok[0];
string ar = adatok[1];
// Hozzáadás ListBox-hoz formázva
lstTermekek.Items.Add($"Termék: {nev} - Ár: {ar} Ft");
}
}
}
C# WinForms DataGridView
Ha komoly üzleti alkalmazást építesz, az adatokat Excel-szerű táblázatban kell megjelenítened. Erre való a DataGridView.
Adatkötés (Data Binding): A DataGridView-t a leggyakrabban nem kézzel töltjük fel, hanem egy adatbázisból (pl. SQL DataTable vagy List<T>) kötjük rá a DataSource tulajdonságon keresztül. De kezdőknek érdemes megérteni a kézi feltöltést is.
Oszlopok és sorok felépítése kód bázison
private void Form1_Load(object sender, EventArgs e)
{
// Először definiáljuk az oszlopokat: (AzonosítóNév, MegjelenőSzöveg)
dataGridView1.Columns.Add("IdOszlop", "ID");
dataGridView1.Columns.Add("NevOszlop", "Teljes Név");
dataGridView1.Columns.Add("FizetesOszlop", "Nettó Bér (HUF)");
// Oszlopok formázása (Pl. az ID oszlop legyen nagyon keskeny)
dataGridView1.Columns["IdOszlop"].Width = 50;
// Adatsorok (Rows) hozzáadása a definált oszlopok sorrendjében
dataGridView1.Rows.Add("1", "Kovács Béla", "450000");
dataGridView1.Rows.Add("2", "Nagy Anna", "520000");
// Megjelenés finomhangolása: Az utolsó oszlop töltse ki a maradék üres helyet!
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
// Letiltjuk, hogy a felhasználó tudjon új, üres sorokat beírni a rács alján
dataGridView1.AllowUserToAddRows = false;
// A cellák ne legyenek szerkeszthetőek dupla kattintásra
dataGridView1.ReadOnly = true;
}
C# WinForms Hibakezelés & Naplózás
A kezdő programozó azt hiszi, hogy a kódja sosem romolhat el. A profi programozó tudja, hogy biztosan el fog. A különbség az, hogy a profi kezeli (Try-Catch) és naplózza (Logging) a hibákat.
Az Összeomlás (Crash): Ha egy Exception (Kivétel/Hiba) bekövetkezik, és azt nem rakod egy Try-Catch blokkba, a Windows egy csúnya hibaüzenettel bezárja (leállítja) a programodat.
Try-Catch és Log fájl írása (AppendAllText)
Megpróbálunk betölteni egy fájlt, ami nem létezik. A Catch blokk elegánsan lekezeli, majd a hiba pontos részleteit egy TXT fájlba (Log) másolja, hogy mi később elolvashassuk, mi baja volt a rendszernek.
private void btnVeszelyes_Click(object sender, EventArgs e)
{
try
{
// A TRY blokkba írjuk azt a kódot, ami VÁRHATÓAN hibát okozhat (Hálózat, I/O)
string txt = File.ReadAllText("C:\\nagyon_nem_letezo_mappa\\titok.txt");
}
catch (Exception ex)
{
// A CATCH csak akkor fut le, ha a Try-ban Exception dobódott.
// Az 'ex' változó tartalmazza a hiba technikai részleteit!
// 1. Elegáns, felhasználóbarát hibaüzenet (Sose mutass technikai kódot a usernek!)
MessageBox.Show("Hálózati vagy fájl hiba történt. Kérjük próbáld újra később.",
"Hiba", MessageBoxButtons.OK, MessageBoxIcon.Error);
// 2. Naplózás a háttérben fájlba.
// A File.AppendAllText Hozzáírja a fájl végéhez a szöveget (nem felülírja).
// Beletesszük a pontos Dátumot és az 'ex.Message' technikai üzenetet.
string log = $"[{DateTime.Now.ToString()}] HIBA: {ex.Message}\n";
// A program gyökerében (bin/Debug) hozza létre az error_log.txt-t
File.AppendAllText("error_log.txt", log);
}
finally
{
// Ez a blokk mindenképp lefut a végén, akár volt hiba, akár nem.
// (Általában erőforrások felszabadítására, formázásra használják).
btnVeszelyes.Enabled = false;
}
}
C# WinForms String Műveletek
A string a leggyakrabban használt adattípus. Ismerd meg a legfontosabb beépített metódusait szövegek manipulálásához.
Legfontosabb String metódusok
.ToUpper()/.ToLower()– Nagybetűssé / kisbetűssé alakítás.Trim()– Szóközök levágása elejéről és végéről.Contains(str)– Tartalmaz-e egy részletet? (true/false).Replace(régi, új)– Részlet cseréje.Split(karakter)– Darabolás elválasztó alapján.Length– Karakterek száma.StartsWith(str)/.EndsWith(str)– Mivel kezdődik/végződik?
1. Példa – Szövegformázás és Email ellenőrzés
string nev = " Kovács Béla ";
// Szóközök eltávolítása, majd nagybetűssé alakítás
string tisztaNev = nev.Trim().ToUpper();
// Eredmény: "KOVÁCS BÉLA"
lblNev.Text = tisztaNev;
// Email formátum egyszerű ellenőrzése
string email = txtEmail.Text;
if (!email.Contains("@") || !email.Contains("."))
{
lblHiba.Text = "Érvénytelen e-mail formátum!";
lblHiba.ForeColor = Color.Red;
}
else
{
lblHiba.Text = "Az e-mail cím érvényes.";
lblHiba.ForeColor = Color.Green;
}
2. Példa – String interpoláció ($) és Replace
string vezNev = "Kovács";
string kerNev = "Béla";
int kor = 35;
// Régimódi összefűzés (nehézkes)
string A = vezNev + " " + kerNev + ", kor: " + kor.ToString();
// Modern $ interpoláció (ajánlott!)
string B = $"{vezNev} {kerNev}, kor: {kor}";
lblEredmeny.Text = B; // "Kovács Béla, kor: 35"
// Csere: Tizedespontot vesszőre cserélünk (Magyar formátum)
string szam = "3.14";
string jszam = szam.Replace(".", ",");
// Eredmény: "3,14"
3. Példa – Split és jelszóhossz-ellenőrzés
// Split: Tagolt adat szétbontása (pl. "Alma,Körte,Barack")
string gyumolcsok = "Alma,Körte,Barack";
string[] lista = gyumolcsok.Split(',');
foreach (var gy in lista)
lstGyumolcsok.Items.Add(gy);
// Jelszóhossz ellenőrzése a .Length tulajdonsággal
string jelszo = txtJelszo.Text;
if (jelszo.Length < 8)
{
MessageBox.Show("A jelszónak legalább 8 karakternek kell lennie!");
}
C# WinForms Gyűjtemények (List és Dictionary)
A List<T> és a Dictionary<K,V> a C# leghasznosabb adatgyűjteményei. A sima tömbökkel ellentétben dinamikusan növekednek.
List<T> – Dinamikus Lista
1. Példa – Névlista kezelése (Hozzáadás, Törlés, Rendezés)
// Osztályszintű lista deklarálás
List<string> nevek = new List<string>();
private void btnHozzaad_Click(object sender, EventArgs e)
{
nevek.Add(txtNev.Text);
FrissitLista();
}
private void btnTorles_Click(object sender, EventArgs e)
{
if (lstNevek.SelectedIndex >= 0)
{
nevek.RemoveAt(lstNevek.SelectedIndex);
FrissitLista();
}
}
private void btnRendez_Click(object sender, EventArgs e)
{
nevek.Sort(); // ABC sorrendbe rendezés
FrissitLista();
}
private void FrissitLista()
{
lstNevek.Items.Clear();
foreach (var n in nevek)
lstNevek.Items.Add(n);
lblDarab.Text = $"Összesen: {nevek.Count} bejegyzés";
}
Dictionary<K,V> – Kulcs-Érték Pár
2. Példa – Termékkatalógus (Árak lekérdezése)
Dictionary<string, int> arjegyzek = new Dictionary<string, int>()
{
{ "Laptop", 250000 },
{ "Egér", 8000 },
{ "Billentyűzet", 15000 }
};
private void Form1_Load(object sender, EventArgs e)
{
// ComboBox feltöltése a szótár kulcsaival
foreach (var kv in arjegyzek)
cmbTermekek.Items.Add(kv.Key);
cmbTermekek.SelectedIndex = 0;
}
private void btnAr_Click(object sender, EventArgs e)
{
string termek = cmbTermekek.SelectedItem.ToString();
int ar = arjegyzek[termek]; // Kulcs alapján kivesszük az árat
lblAr.Text = $"{termek} ára: {ar:N0} Ft";
}
3. Példa – Telefonkönyv (Keresés Dictionaryben)
Dictionary<string, string> telefonkonyv = new Dictionary<string, string>();
private void btnFelvesz_Click(object sender, EventArgs e)
{
string nev = txtNev.Text.Trim();
string tel = txtTelefon.Text.Trim();
// ContainsKey: megnézzük, nem duplikálunk-e
if (!telefonkonyv.ContainsKey(nev))
telefonkonyv.Add(nev, tel);
else
MessageBox.Show("Ez a név már szerepel a könyvben!");
}
private void btnKeres_Click(object sender, EventArgs e)
{
string keresett = txtKeres.Text.Trim();
if (telefonkonyv.ContainsKey(keresett))
lblEredmeny.Text = $"Telefonszám: {telefonkonyv[keresett]}";
else
lblEredmeny.Text = "Nem található.";
}
C# WinForms OOP – Osztályok és Objektumok
Az Objektum-Orientált Programozás (OOP) a modern C# fejlesztés alapja. Saját Osztályokat (Class) hozunk létre, amelyek adatokat és logikát fognak össze.
Miért osztályok? Ha 100 felhasználót kell nyilvántartani, felesleges 100×3 változót létrehozni. Ehelyett egy Felhasznalo osztályt csinálunk, és annak példányait tároljuk listában.
1. Példa – Felhasznalo osztály definiálása (Felhasznalo.cs)
Jobb klikk a projekten → Add → Class → Név: Felhasznalo.cs
public class Felhasznalo
{
// Tulajdonságok (Properties)
public string Nev { get; set; }
public string Email { get; set; }
public int Kor { get; set; }
// Konstruktor: új objektum létrehozásakor fut le (new)
public Felhasznalo(string nev, string email, int kor)
{
Nev = nev;
Email = email;
Kor = kor;
}
// Metódus: az objektum saját viselkedése
public string Bemutatkozas()
{
return $"Szia! {Nev} vagyok, {Kor} éves.";
}
}
2. Példa – Az osztály használata Form1.cs-ben
List<Felhasznalo> felhasznalok = new List<Felhasznalo>();
private void btnRegisztral_Click(object sender, EventArgs e)
{
// Új példány létrehozása a bevitt adatokból
Felhasznalo uj = new Felhasznalo(
txtNev.Text,
txtEmail.Text,
int.Parse(txtKor.Text)
);
felhasznalok.Add(uj);
lstFelhasznalok.Items.Add(uj.Bemutatkozas());
}
private void btnOsszesito_Click(object sender, EventArgs e)
{
// LINQ: Átlagkor kiszámítása az összes user kora alapján
double atlag = felhasznalok.Average(f => f.Kor);
MessageBox.Show($"Összesen: {felhasznalok.Count} felhasználó\nÁtlagkor: {atlag:F1} év");
}
3. Példa – Öröklés (Inheritance)
Az öröklés lehetővé teszi, hogy egy osztály átvegye egy másik tulajdonságait és bővítse azt.
// Alap osztály (szülő)
public class Allat
{
public string Nev { get; set; }
public virtual string Hang() => "...";
}
// Kutya osztály örökli az Allat osztályt (: Allat)
public class Kutya : Allat
{
// override: felülírjuk az alap Hang() metódust
public override string Hang() => "Vau!";
}
public class Macska : Allat
{
public override string Hang() => "Miau!";
}
// Felhasználás Form1.cs-ben:
private void btnHang_Click(object sender, EventArgs e)
{
List<Allat> allatok = new List<Allat> {
new Kutya { Nev = "Rex" },
new Macska { Nev = "Cirmi" }
};
foreach (var a in allatok)
lstHangok.Items.Add($"{a.Nev}: {a.Hang()}");
}
C# WinForms LINQ – Language Integrated Query
A LINQ (Language Integrated Query) C# beépített lekérdező nyelve. Segítségével listák, tömbök és adatbázisok adatait tömören, SQL-szerű stílusban szűrhetjük, rendezhetjük és alakíthatjuk át – egyetlen sorban.
Előfeltétel: A LINQ használatához add hozzá a fájl tetejéhez: using System.Linq;. .NET 6+ projektekben ez automatikusan elérhető.
Kétféle szintaxis
A LINQ-t kétféleképpen írhatod. Mindkettő ugyanazt csinálja – a Method szintaxis az elterjedtebb C# fejlesztők körében.
Query vs Method szintaxis (ugyanaz az eredmény)
List<int> szamok = new List<int> { 1, 5, 3, 8, 2, 9, 4, 7, 6 };
// === QUERY szintaxis (SQL-szerű) ===
var query = from s in szamok
where s > 4
orderby s
select s;
// === METHOD szintaxis (lambda kifejezésekkel) ===
var method = szamok.Where(s => s > 4).OrderBy(s => s);
// Mindkettő eredménye: 5, 6, 7, 8, 9
foreach (var s in method)
lstEredmeny.Items.Add(s.ToString());
1. Where() – Szűrés
Az egyik legfontosabb LINQ metódus. Azokat az elemeket adja vissza, amelyek megfelelnek a feltételnek.
Példa – Felnőtt felhasználók szűrése
List<Felhasznalo> felhasznalok = GetFelhasznalok(); // Képzelt adatforrás
// Csak a 18+ korúakat tartjuk meg
var felnottEk = felhasznalok.Where(f => f.Kor >= 18);
lstFelhasznalok.Items.Clear();
foreach (var f in felnottEk)
lstFelhasznalok.Items.Add($"{f.Nev} ({f.Kor})");
Példa – Szókeresés Where + Contains kombinációval
List<string> termekek = new List<string> { "Laptop", "Egér", "Billentyűzet", "Monitor", "Webkamera" };
string keresett = txtKeres.Text.ToLower();
// Azokat adjuk vissza, amik tartalmazzák a keresett szöveget
var talalt = termekek.Where(t => t.ToLower().Contains(keresett));
lstTermekek.Items.Clear();
foreach (var t in talalt)
lstTermekek.Items.Add(t);
2. Select() – Átalakítás (Projekció)
A Select() minden elemet átalakít valami mássá. Olyan, mint egy "mappa" – kiveszed a listából az adatot, és más formában adod vissza.
Példa – Nevek nagybetűsítése és más típusba alakítás
List<Felhasznalo> lista = GetFelhasznalok();
// Csak a neveket vesszük ki (Felhasznalo → string)
List<string> nevek = lista.Select(f => f.Nev).ToList();
// Neveket nagybetűsítve
List<string> nagybetus = lista.Select(f => f.Nev.ToUpper()).ToList();
// Tömör névjegy string előállítása
List<string> nevjegyek = lista
.Select(f => $"{f.Nev} | {f.Email} | {f.Kor} év")
.ToList();
foreach (var nv in nevjegyek)
lstOutput.Items.Add(nv);
3. OrderBy() / OrderByDescending() – Rendezés
Egy lista elemeit rendezi növekvő (OrderBy) vagy csökkenő (OrderByDescending) sorrendbe valamelyik tulajdonság alapján.
Példa – Felhasználók rendezése kor és név szerint
// Kor szerint növekvő (legfiatalabb elöl)
var korRendezve = felhasznalok.OrderBy(f => f.Kor);
// Kor szerint csökkenő (legidősebb elöl)
var korForditott = felhasznalok.OrderByDescending(f => f.Kor);
// Név szerint ABC sorrendbe (string-et rendez)
var nevABC = felhasznalok.OrderBy(f => f.Nev);
// ThenBy: Először kor szerint, kor egyenlőségnél név szerint
var osszetett = felhasznalok
.OrderBy(f => f.Kor)
.ThenBy(f => f.Nev);
foreach (var f in osszetett)
lstSorted.Items.Add($"{f.Nev} – {f.Kor} év");
4. Aggregáló metódusok (Count, Sum, Average, Min, Max)
Ezek a metódusok egy listából egyetlen összesített értéket számolnak ki.
Példa – Statisztikák számítása listából
List<int> fizetesek = new List<int> { 320000, 450000, 210000, 580000, 390000 };
int db = fizetesek.Count(); // 5
int osszeg = fizetesek.Sum(); // 1950000
double atlag = fizetesek.Average(); // 390000
int legkev = fizetesek.Min(); // 210000
int legtobb = fizetesek.Max(); // 580000
// Feltételes Count: Hányan keresnek 400000 felett?
int magasKeresoK = fizetesek.Count(f => f > 400000); // 2
lblStatisztika.Text =
$"Összesen: {db} fő\n" +
$"Átlagfizetés: {atlag:N0} Ft\n" +
$"Legmagasabb: {legtobb:N0} Ft\n" +
$"400k felett: {magasKeresoK} fő";
5. First() / FirstOrDefault() – Első egyező elem
First() hibát dob, ha nincs találat. A FirstOrDefault() ilyenkor null-t (vagy 0-t számoknál) ad vissza – ez sokkal biztonságosabb.
Példa – Felhasználó keresése e-mail alapján
string emailCim = txtEmail.Text.ToLower();
// FirstOrDefault: Ha nem találja, null-t ad vissza (nem crashel!)
Felhasznalo talalt = felhasznalok
.FirstOrDefault(f => f.Email.ToLower() == emailCim);
if (talalt != null)
{
MessageBox.Show($"Megtalálva: {talalt.Nev}, {talalt.Kor} év");
}
else
{
MessageBox.Show("Nincs ilyen e-mail a rendszerben.");
}
// LastOrDefault: Az utolsó egyező elemet adja vissza
Felhasznalo utolso = felhasznalok.LastOrDefault(f => f.Kor < 30);
6. Any() / All() – Feltétel-ellenőrzés
Any(): Van-e legalább egy elem, ami megfelel? → boolAll(): Minden elem megfelel-e? → bool
Példa – Validáció listán Any és All segítségével
List<string> jelszavak = new List<string> { "abc123", "Titkos!1", "rövid" };
// Any: Van-e legalább egy 8 karakternél rövidebb jelszó?
bool vanGyenge = jelszavak.Any(j => j.Length < 8);
// Eredmény: true (abc123 és rövid is rövidebb)
// All: Minden jelszó legalább 6 karakter-e?
bool mindenOk = jelszavak.All(j => j.Length >= 6);
// Eredmény: false (rövid = 5 karakter)
if (vanGyenge)
lblFigyelmezetes.Text = "⚠ Van gyenge jelszó a listában!";
// Felhasználók esetén: Van-e admin jogú user?
bool vanAdmin = felhasznalok.Any(f => f.Szerep == "Admin");
7. GroupBy() – Csoportosítás
Az elemeket valamelyik tulajdonságuk alapján csoportokba rendezi. Nagyon hasznos statisztikákhoz és kimutatásokhoz.
Példa – Felhasználók csoportosítása életkor szerint
// Csoportok létrehozása a Szerep (pl. "Admin", "User") mező alapján
var csoportok = felhasznalok.GroupBy(f => f.Szerep);
foreach (var csoport in csoportok)
{
// csoport.Key = a csoportosítási érték (pl. "Admin")
lstOutput.Items.Add($"--- {csoport.Key} ({csoport.Count()} fő) ---");
foreach (var f in csoport)
lstOutput.Items.Add($" {f.Nev}");
}
// Életkor-csoportok: Fiatal (<30), Középkorú (30-50), Senior (50+)
var korCsoportok = felhasznalok.GroupBy(f =>
f.Kor < 30 ? "Fiatal" :
f.Kor < 50 ? "Középkorú" : "Senior"
);
foreach (var g in korCsoportok)
lstOutput.Items.Add($"{g.Key}: {g.Count()} fő, átlagkor {g.Average(f => f.Kor):F1}");
8. Distinct() / Take() / Skip() – Egyedi elemek és lapozás
Distinct – Duplikátumok eltávolítása
List<string> varosok = new List<string> { "Budapest", "Pécs", "Budapest", "Győr", "Pécs" };
// Csak az egyedi városokat tartjuk meg
var egyedi = varosok.Distinct();
// Eredmény: Budapest, Pécs, Győr
foreach (var v in egyedi)
lstVarosok.Items.Add(v);
Take() és Skip() – Lapozás (Pagination)
List<Felhasznalo> mindenki = GetFelhasznalok(); // pl. 100 elem
int oldalMeret = 10;
int aktualisOldal = 2; // 0-tól indul
// Skip: Átugorjuk az első N elemet
// Take: Csak a következő N elemet vesszük
var oldal = mindenki
.Skip(aktualisOldal * oldalMeret) // Átugorjuk az első 20-at
.Take(oldalMeret); // Vesszük a 21-30-at
foreach (var f in oldal)
lstOutput.Items.Add(f.Nev);
9. Láncolás (Method Chaining) – A LINQ ereje
A LINQ igazi ereje abban rejlik, hogy a metódusokat egymás után láncolhatod, és összetetett lekérdezéseket írhatsz egyetlen, olvasható kifejezésben.
Összetett lekérdezés – Szűrés + rendezés + átalakítás + lapozás
// Feladat: Az első 5, 25 évnél idősebb és "User" szerepű felhasználó
// neve és kora, névsor szerint rendezve
List<string> eredmeny = felhasznalok
.Where(f => f.Kor > 25) // 1. Szűrés kor alapján
.Where(f => f.Szerep == "User") // 2. Szűrés szerep alapján
.OrderBy(f => f.Nev) // 3. ABC sorrendbe
.Take(5) // 4. Csak az első 5
.Select(f => $"{f.Nev} ({f.Kor} év)") // 5. Szöveg formázás
.ToList(); // 6. List-té alakítás
lstTop5.Items.Clear();
foreach (var sor in eredmeny)
lstTop5.Items.Add(sor);
lblOsszesen.Text = $"Találatok: {eredmeny.Count}";
Fontos: A LINQ lekérdezések lusta kiértékelésűek (lazy evaluation) – a Where(), OrderBy() stb. nem futnak le azonnal, csak akkor, amikor valaki iterál felettük (pl. foreach) vagy meghívod a .ToList()-ot. Ha többször is szükséged van az eredményre, mindig hívj .ToList()-ot, hogy elkerüld a többszörös feldolgozást!
10. Dictionary készítése LINQ-kal (ToDictionary & GroupBy)
Az egyik leggyakoribb feladat: egy listából gyorsan összeállítani egy Dictionary-t – akár keresési táblának (lookup), akár megszámláláshoz (counting). A LINQ erre elegáns eszközöket kínál.
10.1 – ToDictionary(): Lista → Dictionary konverzió
Ha minden elemnek van egy egyedi azonosítója (pl. ID), akkor a listát egyetlen lépésben Dictionary-vé alakíthatjuk. Így O(1) idő alatt tudunk majd visszakeresni.
List<Felhasznalo> lista = GetFelhasznalok();
// ToDictionary(kulcs, érték)
// Kulcs: a felhasználó e-mail címe (egyedi!)
// Érték: maga a Felhasznalo objektum
Dictionary<string, Felhasznalo> emailIndex =
lista.ToDictionary(f => f.Email, f => f);
// Gyors visszakeresés kulcs alapján (nem kell ciklus!)
string keresett = txtEmail.Text;
if (emailIndex.ContainsKey(keresett))
{
Felhasznalo talalat = emailIndex[keresett];
lblEredmeny.Text = $"Megtalálva: {talalat.Nev}, {talalat.Kor} év";
}
else
{
lblEredmeny.Text = "Nincs ilyen e-mail.";
}
// Csak az ID-t és nevet tároljuk (int → string)
Dictionary<int, string> idNevTerkep =
lista.ToDictionary(f => f.Id, f => f.Nev);
10.2 – GroupBy + ToDictionary: Megszámlálás (Counting)
Ez az egyik leghasznosabb minta: egy listában megszámolod, hogy az egyes értékekből (pl. városok, szerepek, termékek) mennyi van. Az eredmény egy Dictionary<string, int>, ahol a kulcs a kategória, az érték a darabszám.
List<string> varosok = new List<string>
{
"Budapest", "Pécs", "Budapest", "Győr",
"Pécs", "Budapest", "Miskolc", "Pécs"
};
// GroupBy: Csoportosítás érték szerint
// ToDictionary: Kulcs = város neve, Érték = hány darab van belőle
Dictionary<string, int> varosokSzama =
varosok
.GroupBy(v => v)
.ToDictionary(g => g.Key, g => g.Count());
// Eredmény: { "Budapest": 3, "Pécs": 3, "Győr": 1, "Miskolc": 1 }
// Megjelenítés ListBox-ban
lstEredmeny.Items.Clear();
foreach (var kv in varosokSzama.OrderByDescending(kv => kv.Value))
lstEredmeny.Items.Add($"{kv.Key}: {kv.Value} db");
10.3 – Objektum lista megszámlálása tulajdonság alapján
Ugyanez a minta, de most egy komplex objektumlista valamelyik mezője szerint csoportosítunk és számolunk (pl. hány felhasználó van városonként, szerepenként).
List<Felhasznalo> felhasznalok = GetFelhasznalok();
// Hány felhasználó van szerepenként? (pl. Admin, User, Moderator)
Dictionary<string, int> szerepekSzama = felhasznalok
.GroupBy(f => f.Szerep)
.ToDictionary(g => g.Key, g => g.Count());
// Hány felhasználó van városonként?
Dictionary<string, int> varosonkent = felhasznalok
.GroupBy(f => f.Varos)
.ToDictionary(g => g.Key, g => g.Count());
// Kiírás
foreach (var kv in szerepekSzama)
lstSzerepek.Items.Add($"{kv.Key}: {kv.Value} fő");
10.4 – Összetett Dictionary: Megszámlálás + Átlag + Max egyszerre
Haladó minta: Nem csak az elemek számát, hanem az összes összesített statisztikát is megkapjuk csoportonként – egy lépésben, névtelen (anonymous) típussal.
// Csoportonkénti statisztika: Részleg → { Fők száma, Átlagfizetés, Legmagasabb }
var statisztika = felhasznalok
.GroupBy(f => f.Reszleg)
.ToDictionary(
g => g.Key, // Kulcs: Részleg neve
g => new // Érték: Névtelen objektum statisztikákkal
{
Db = g.Count(),
Atlagber = g.Average(f => f.Fizetes),
Maximumber = g.Max(f => f.Fizetes)
}
);
// Kiírás és feldolgozás
foreach (var kv in statisztika)
{
lstOutput.Items.Add($"📁 {kv.Key}");
lstOutput.Items.Add($" Létszám: {kv.Value.Db} fő");
lstOutput.Items.Add($" Átlagbér: {kv.Value.Atlagber:N0} Ft");
lstOutput.Items.Add($" Legmagasabb: {kv.Value.Maximumber:N0} Ft");
}
Mikor melyiket használd?
• ToDictionary(k, v) – Ha listából gyors visszakeresési táblát akarsz csinálni egyedi kulcsok alapján.
• GroupBy(...).ToDictionary(g => g.Key, g => g.Count()) – Ha megszámolod, melyik értékből mennyi van.
• GroupBy(...).ToDictionary(g => g.Key, g => new { ... }) – Ha csoportonként összesített statisztikákat akarsz (átlag, max, összeg).
🎉 Gratulálunk! Elvégezted a Teljes Kurzust!
LINQ ismeretekkel felvértezve most már valóban haladó C# WinForms fejlesztő vagy. A következő lépés: Próbálj ki egy valós projektet – például egy SQLite adatbázishoz kötött, LINQ-ot használó teendőlista alkalmazást!
C# WinForms Gyakorló Feladatok
Teszteld a tudásod ezekkel az egyszerű, kezdőknek szóló feladatokkal!
Tipp: Próbáld meg fejből, vagy a korábbi fejezetek kódpéldái alapján megoldani a feladatokat, mielőtt megnézed a megoldást!
1. Feladat: Köszönő gomb
Készíts egy programot, amely egy gomb megnyomására kiírja egy MessageBox-ba, hogy "Szia Világ!".
Kattints ide a megoldásért!
private void btnKoszont_Click(object sender, EventArgs e)
{
MessageBox.Show("Szia Világ!");
}
2. Feladat: Szöveg Másolása
Helyezz el a formon két TextBox-ot és egy Gombot. A gomb megnyomásakor az első szövegdoboz tartalma másolódjon át a másodikba.
Kattints ide a megoldásért!
private void btnMasol_Click(object sender, EventArgs e)
{
txtMasodik.Text = txtElso.Text;
}
3. Feladat: Számok összeadása
Kérj be két számot két TextBox-ból. Egy gomb megnyomására add össze őket, és írd ki az eredményt egy Label-be. Figyelj a típuskonverzióra (int.Parse vagy int.TryParse)!
Kattints ide a megoldásért!
private void btnOsszead_Click(object sender, EventArgs e)
{
if (int.TryParse(txtSzam1.Text, out int a) && int.TryParse(txtSzam2.Text, out int b))
{
lblEredmeny.Text = (a + b).ToString();
}
else
{
MessageBox.Show("Kérlek, számokat adj meg!");
}
}
4. Feladat: Bevásárlólista (ListBox)
Készíts egy bevásárlólistát! Legyen egy TextBox, ahova a termék nevét írjuk, egy gomb, ami hozzáadja a ListBox-hoz, és egy gomb, ami törli a ListBox-ból a kijelölt elemet.
Kattints ide a megoldásért!
// Hozzáadás gomb
private void btnHozzaad_Click(object sender, EventArgs e)
{
if (txtTermek.Text != "")
{
lstBeVasarol.Items.Add(txtTermek.Text);
txtTermek.Clear();
}
}
// Törlés gomb
private void btnTorol_Click(object sender, EventArgs e)
{
if (lstBeVasarol.SelectedIndex != -1)
{
lstBeVasarol.Items.RemoveAt(lstBeVasarol.SelectedIndex);
}
}
5. Feladat: Háttérszín változtatása
Rakj a formra egy ComboBox-ot a következő elemekkel: "Piros", "Zöld", "Kék". Ha a felhasználó kiválaszt egyet, a Form háttérszíne változzon meg a kiválasztott színre!
Kattints ide a megoldásért!
private void cmbSzin_SelectedIndexChanged(object sender, EventArgs e)
{
string valasztott = cmbSzin.SelectedItem.ToString();
if (valasztott == "Piros")
this.BackColor = Color.Red;
else if (valasztott == "Zöld")
this.BackColor = Color.Green;
else if (valasztott == "Kék")
this.BackColor = Color.Blue;
}
6. Feladat: Feltételek (CheckBox)
Legyen egy "Elfogadom a feltételeket" CheckBox és egy "Regisztráció" gomb. A gomb alapértelmezetten legyen letiltva (Enabled = false). Csak akkor legyen kattintható, ha a CheckBox be van pipálva!
Kattints ide a megoldásért!
private void chkFeltetelek_CheckedChanged(object sender, EventArgs e)
{
btnRegisztracio.Enabled = chkFeltetelek.Checked;
}
7. Feladat: Lista szűrése (LINQ)
Van egy List<int> szamok = new List<int> { 12, 45, 8, 23, 100, 3 }; listád. LINQ segítségével szűrd ki csak a 20-nál nagyobb számokat, és írd ki őket egy ListBox-ba!
Kattints ide a megoldásért!
private void Form1_Load(object sender, EventArgs e)
{
List<int> szamok = new List<int> { 12, 45, 8, 23, 100, 3 };
var szurtSzamok = szamok.Where(sz => sz > 20);
foreach (var szam in szurtSzamok)
{
listBox1.Items.Add(szam);
}
}
8. Feladat: Stopper (Timer)
Rakj a formra egy Labelt (alapból "0") és egy Timer-t. Gombnyomásra induljon el a Timer, és másodpercenként (Interval = 1000) növelje a Label értékét eggyel!
Kattints ide a megoldásért!
int masodperc = 0;
private void btnIndit_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
masodperc++;
lblIdo.Text = masodperc.ToString();
}
9. Feladat: Árlekérdezés (Dictionary)
Készíts egy Dictionary<string, int> adatszerkezetet, ami 3 gyümölcs nevét és árát tárolja. Kérj be egy gyümölcsnevet a felhasználótól (TextBox), és gombnyomásra írd ki az árát, vagy ha nincs ilyen, akkor azt, hogy "Nincs találat"!
Kattints ide a megoldásért!
Dictionary<string, int> arak = new Dictionary<string, int>()
{
{ "Alma", 300 },
{ "Banán", 500 },
{ "Körte", 450 }
};
private void btnLekerdez_Click(object sender, EventArgs e)
{
string gyumolcs = txtGyumolcs.Text;
if (arak.ContainsKey(gyumolcs))
{
MessageBox.Show($"Az ár: {arak[gyumolcs]} Ft");
}
else
{
MessageBox.Show("Nincs találat!");
}
}
10. Feladat: Egyszerű Fájlba mentés
Legyen a formon egy szövegdoboz és egy "Mentés" gomb. A gomb megnyomásakor a program írja ki a szövegdoboz tartalmát egy jegyzet.txt fájlba a program mappájába!
Kattints ide a megoldásért!
// Ne felejtsd el a fájl tetejére: using System.IO;
private void btnMentes_Click(object sender, EventArgs e)
{
string szoveg = txtTartalom.Text;
File.WriteAllText("jegyzet.txt", szoveg);
MessageBox.Show("Sikeresen lementve a jegyzet.txt fájlba!");
}
11. Feladat: Eldöntendő kérdés (DialogResult)
Rakj fel egy "Törlés" gombot. Ha a felhasználó rákattint, dobj fel egy kérdést egy MessageBox-ban: "Biztosan törölni akarod?". Ha az Igen-re (Yes) kattint, írd ki egy Label-be, hogy "Törölve!", különben "Megszakítva".
Kattints ide a megoldásért!
private void btnTorles_Click(object sender, EventArgs e)
{
DialogResult valasz = MessageBox.Show(
"Biztosan törölni akarod?",
"Megerősítés",
MessageBoxButtons.YesNo,
MessageBoxIcon.Warning
);
if (valasz == DialogResult.Yes)
{
lblEredmeny.Text = "Törölve!";
}
else
{
lblEredmeny.Text = "Megszakítva.";
}
}
12. Feladat: Két Form használata
Hozz létre egy második formot (Form2)! A fő formon legyen egy gomb, ami megnyitja a második formot, úgy, hogy amíg az nyitva van, az elsőre ne lehessen kattintani!
Kattints ide a megoldásért!
private void btnUjAblak_Click(object sender, EventArgs e)
{
// Példányosítjuk a másik ablakot
Form2 masikAblak = new Form2();
// ShowDialog()-ot használunk, hogy "Modális" legyen (megakassza a futást)
masikAblak.ShowDialog();
}
13. Feladat: Osztály és Objektum (OOP)
Készíts egy Kutya osztályt, aminek van két tulajdonsága: Nev és Fajta. A Form indulásakor (Load esemény) példányosíts egy kutyát, add meg az adatait, és írd ki az eredményt egy Label-be!
Kattints ide a megoldásért!
// Az osztály definíciója (lehet a formon kívül, vagy egy új fájlban)
public class Kutya
{
public string Nev { get; set; }
public string Fajta { get; set; }
}
private void Form1_Load(object sender, EventArgs e)
{
// Új objektum példányosítása és feltöltése
Kutya kedvenc = new Kutya();
kedvenc.Nev = "Buksi";
kedvenc.Fajta = "Puli";
// Kiírás
lblInfo.Text = $"A kutyám neve: {kedvenc.Nev}, fajtája: {kedvenc.Fajta}";
}