Tutorial Exercises

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ő:

MessageBox.Show(Szöveg, Címsor, Gombok, Ikon);

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? → bool
All(): 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}"; }