Grafikus C# – Windows Forms tanfolyam › 1.4 lecke

Windows Forms · 1.4 lecke · önálló gyakorlás

CheckBox és RadioButton – választások és események

Bepipálható négyzet, egymást kizáró választások és egy felirat, amely azonnal reagál a változásra. Ebben a leckében egy lámpa kapcsolóját és színválasztóját építjük meg, és közben megismerjük a CheckBox, a RadioButton és a GroupBox működését.

  • kb. 60 perc
  • kezdő szint
  • választások
Diák C# programozást gyakorol egy tanulósarokban

A lecke végére

  • a CheckBox állapotát a Checked tulajdonsággal kiolvasod;
  • reagálsz a CheckedChanged eseményre;
  • a RadioButton elemeket GroupBox-ba csoportosítod;
  • egyetlen közös metódussal frissíted a felületet több vezérlő állapota alapján;
  • érted az értékadás (=) és az összehasonlítás (==) különbségét;
  • beállítod a kezdőállapotot, hogy a felirat induláskor is helyes legyen.

Mielőtt elkezded

Ehhez a leckéhez kell az 1.3 lecke, valamint az if–else és a logikai (igaz/hamis) érték ismerete a C# alapokból.

1.3 Számolás és TryParse →

A felület: lámpa és színek

Egy lámpát építünk: a CheckBox a kapcsolója, a RadioButton elemek a színe, a Label pedig maga a lámpa. Tedd az ablakra:

chkLampaEgy CheckBox, a Text: Bekapcsolva.
lblLampaEgy nagyobb Label, ez a lámpa. Állítsd a méretét nagyobbra (AutoSize: False), és a Text: A lámpa nem világít.
grpSzinEgy GroupBox (Toolbox, Containers csoport), a Text: Szín.
rbSarga, rbPiros, rbZoldHárom RadioButton a GroupBoxon belül. Az előtag rb a RadioButton rövidítése.
📷 Képernyőkép helye

Mit tegyél ide: a tervezőnézet a kész felülettel: a CheckBox, a nagy Label és a Szín feliratú GroupBox benne három RadioButtonnal. A Toolbox Containers csoportjában a GroupBox is látszik.Javasolt fájlnév: winforms-1-4-felulet.webp · Alt szöveg: A lámpa program felülete CheckBoxszal, feliratokkal és színválasztó RadioButtonokkal

A RadioButtonoknak a GroupBoxban kell lenniük!

A GroupBoxot először tedd az ablakra, majd a RadioButtonokat húzd bele. Ha mellé húzod őket, nem a csoport részei lesznek. Ellenőrizd: ha a GroupBoxot mozgatod, a RadioButtonoknak vele kell mozogniuk.

A CheckBox: be- vagy kikapcsolva

A CheckBox egy jelölőnégyzet. A Checked tulajdonsága logikai (bool) érték: true, ha be van pipálva, false, ha nem. Amikor a felhasználó rákattint, kiváltódik a CheckedChanged esemény. Kattints duplán a CheckBoxra a tervezőben:

Form1.csC#
private void chkLampa_CheckedChanged(object sender, EventArgs e)
{
if (chkLampa.Checked)
{
lblLampa.Text = "A lámpa világít.";
}
else
{
lblLampa.Text = "A lámpa nem világít.";
}
}
chkLampa.CheckedIgaz, ha be van pipálva. Az if feltételébe közvetlenül beírható, nem kell == true.
CheckedChangedAz esemény, amely minden pipálásnál és pipa-eltávolításnál lefut. A Checked a pillanatnyi állapotot mutatja.

Jósolj!

A CheckBox kezdetben nincs bepipálva. Háromszor rákattintasz. Hányszor fut le a CheckedChanged eseménykezelő, és milyen szöveg lesz a végén?

Jóslat ellenőrzése

Háromszor fut le (minden változáskor egyszer). A végén a pipa be van kapcsolva (be, ki, be), ezért a szöveg: A lámpa világít.

A RadioButton és a GroupBox

A RadioButton (választógomb) egymást kizáró lehetőségeket mutat: egy csoportban egyszerre csak egy lehet kijelölve. Az, hogy melyek tartoznak egy csoportba, a tárolótól függ: az azonos GroupBoxban lévő RadioButtonok egy csoportot alkotnak.

CheckedUgyanúgy logikai érték, mint a CheckBoxnál: igaz, ha éppen ez a gomb van kijelölve.
Egy csoport, egy választásHa az egyiket kijelölöd, a többi automatikusan kikapcsol.
Több csoportHa két független választásra van szükség (például szín és méret), mindegyiknek külön GroupBox kell.
CheckedChanged kétszer futHa átváltasz egy másik gombra, az eddig kijelölt gombnál is lefut az esemény (kikapcsol), az újnál is (bekapcsol). Ezért kell a Checked értékét vizsgálni.

Jósolj!

A piros RadioButton ki van jelölve, te a zöldre kattintasz. Melyik RadioButton eseménykezelője fut le?

Jóslat ellenőrzése

Mindkettőé: a pirosnál a kijelölés megszűnik, a zöldnél létrejön. Ezért az eseménykezelőkben mindig a Checked aktuális értékét kell figyelni.

Egy közös metódus a felület frissítésére

A lámpa kinézete két dologtól függ: be van-e kapcsolva, és melyik szín van kiválasztva. Ahelyett, hogy minden eseménykezelőbe újra beírnánk ugyanazt, egyetlen Frissit() metódusba tesszük a logikát, és mindhárom eseménykezelő ezt hívja:

Form1.csC#
private void Frissit()
{
if (chkLampa.Checked)
{
lblLampa.Text = "A lámpa világít.";

if (rbPiros.Checked)
{
lblLampa.BackColor = Color.LightCoral;
}
else if (rbZold.Checked)
{
lblLampa.BackColor = Color.LightGreen;
}
else
{
lblLampa.BackColor = Color.LightYellow;
}
}
else
{
lblLampa.Text = "A lámpa nem világít.";
lblLampa.BackColor = SystemColors.Control;
}
}

private void chkLampa_CheckedChanged(object sender, EventArgs e)
{
Frissit();
}

private void rbPiros_CheckedChanged(object sender, EventArgs e)
{
Frissit();
}

private void rbZold_CheckedChanged(object sender, EventArgs e)
{
Frissit();
}

private void rbSarga_CheckedChanged(object sender, EventArgs e)
{
Frissit();
}
Frissit()Mindig az éppen érvényes állapotot olvassa ki, és ennek megfelelően állítja be a feliratot. Nem számít, melyik vezérlő váltotta ki.
if / else if / elseHárom lehetőség közül választ: piros, zöld, vagy minden más eset (a sárga).
Color.LightCoralEgy előre megadott szín (halványpiros). A Color osztály sok színt tartalmaz.
SystemColors.ControlA Windows alapértelmezett felületi színe: a lámpa kikapcsolt állapota.

Egy eseménykezelő több vezérlőhöz

Négy szinte azonos eseménykezelő helyett egyetlen is elég: a Properties ablak Events nézetében a CheckedChanged sor melletti legördülő listából válaszd ki ugyanazt a metódust mindegyik vezérlőnél. Erről az 5.8 leckében lesz részletesebben szó.

📷 Képernyőkép helye

Mit tegyél ide: három kép egymás mellett a futó programról: kikapcsolt lámpa (szürke), bekapcsolt sárga lámpa, bekapcsolt zöld lámpa.Javasolt fájlnév: winforms-1-4-lampa-fut.webp · Alt szöveg: A lámpa program kikapcsolva, sárga és zöld színnel

A kezdőállapot

Induláskor a felirat és a vezérlők állapota nem biztos, hogy egyezik. Két teendő van:

  1. A tervezőben jelöld ki az egyik RadioButtont (például az rbSarga elemet), és állítsd a Checked tulajdonságát True-ra. Így induláskor mindig van kijelölt szín.
  2. A Form1_Load eseményben (0.8 lecke) hívd meg a Frissit(); metódust, hogy a felirat is a kezdőállapotot tükrözze.

Jósolj!

A CheckBox Checked tulajdonságát a tervezőben igazra állítottad, de a Form1_Load eseményben nem hívod a Frissit() metódust. Mit mutat a lámpa induláskor?

Jóslat ellenőrzése

A felirat az eredeti, a tervezőben beállított szöveg lesz (A lámpa nem világít.), pedig a CheckBox be van pipálva. A kettő nem egyezik, mert a Frissit() még nem futott le. Ezért kell a Load eseményben meghívni.

Hibakeresés: te vagy a hibadetektív

Mi a baj, és hogyan javítod?

Gondold végig az okot, és csak utána nyisd le a megoldást.

1. Szöveg a feltételben

if (chkLampa.Text)
{
lblLampa.Text = "A lámpa világít.";
}
// CS0029: Cannot implicitly convert type 'string' to 'bool'
Hiba és javítás

Fordítási hiba (CS0029): a Text szöveg, az if feltételéhez viszont igaz/hamis érték kell. Használd a chkLampa.Checked tulajdonságot.

2. Egyenlőségjel helyett értékadás

if (chkLampa.Checked = true)
{
lblLampa.Text = "A lámpa világít.";
}
Hiba és javítás

Rossz működés: az egy darab = értéket ad, nem hasonlít össze. A kód minden alkalommal bepipálja a CheckBoxot, és a feltétel mindig igaz. A Visual Studio figyelmeztetést is mutat. A javítás: if (chkLampa.Checked), vagy összehasonlításhoz két egyenlőségjel (==).

3. A két választás összekeveredik

Egy szín- és egy méretválasztót is tettél az ablakra, de ha az egyik csoportban választasz, a másikban kikapcsol a kijelölés.

Ok és javítás

A RadioButtonok ugyanabban a tárolóban (például közvetlenül az ablakon) vannak, ezért egy csoportot alkotnak. Tegyél a két választást külön GroupBoxba.

4. A felirat induláskor hibás

A lámpa a program indulásakor a rossz szöveget mutatja.

Ok és javítás

Nincs meghívva a Frissit() a Form1_Load eseményben, vagy a kezdőállapot a tervezőben nem azonos a felirattal. Hívd meg a Load eseményben.

5. Nem történik semmi pipálásra

A CheckBoxot pipálod, de a felirat nem változik.

Ok és javítás

Az eseménykezelő nincs összekötve a CheckBoxszal (például kézzel gépelted be). Töröld, és generáltasd újra dupla kattintással, vagy az Events nézetben (villám) válaszd ki a CheckedChanged sorhoz.

Mini projekt: a lámpa program

Állítsd össze a teljes lámpa programot:

  1. Felület: chkLampa, lblLampa, grpSzin és benne rbSarga, rbPiros, rbZold.
  2. A Frissit() metódus és a négy eseménykezelő a leckében látott módon.
  3. Kezdőállapot: rbSarga kijelölve, a Form1_Load hívja a Frissit() metódust.
  4. Próbáld ki az összes kombinációt: ki- és bekapcsolva mindhárom színnel.
📷 Képernyőkép helye

Mit tegyél ide: a kész lámpa program bekapcsolt zöld lámpával, a bepipált CheckBoxszal és a kijelölt Zöld RadioButtonnal.Javasolt fájlnév: winforms-1-4-lampa-kesz.webp · Alt szöveg: A kész lámpa program bekapcsolt zöld lámpával

Három önálló gyakorlófeladat

Egyszerre csak egyet csinálj: tervezd meg, írd meg, futtasd, ellenőrizd, és csak utána nyisd ki a megoldást.

1. A kiválasztott szín kiírása

Tegyél az ablakra egy lblSzin feliratot, amely kiírja a kiválasztott szín nevét: Szín: piros.

Egy lehetséges megoldás
// a Frissit() metódus végére:
if (rbPiros.Checked)
{
lblSzin.Text = "Szín: piros";
}
else if (rbZold.Checked)
{
lblSzin.Text = "Szín: zöld";
}
else
{
lblSzin.Text = "Szín: sárga";
}

2. Kikapcsoló gomb

Készíts egy btnKi gombot, amely kikapcsolja a lámpát, vagyis kiveszi a pipát a CheckBoxból.

Egy lehetséges megoldás
private void btnKi_Click(object sender, EventArgs e)
{
chkLampa.Checked = false;
}

Ha kódból változtatod a Checked értékét, a CheckedChanged esemény ilyenkor is lefut, ezért a felirat magától frissül.

3. Második csoport: méret

Adj az ablakhoz egy második GroupBoxot (grpMeret) két RadioButtonnal (rbKicsi, rbNagy). A Nagy kijelölésekor a lámpa felirata kapjon nagyobb betűméretet.

Egy lehetséges megoldás
if (rbNagy.Checked)
{
lblLampa.Font = new Font(lblLampa.Font.FontFamily, 24);
}
else
{
lblLampa.Font = new Font(lblLampa.Font.FontFamily, 12);
}

A két csoport azért nem zavarja egymást, mert külön GroupBoxban van. A Font működését a 2.4 leckében magyarázzuk el.

Gyakorlótár: 6 további feladat

Három szinten gyakorolhatsz: alap, közepes és kihívás. Minden feladathoz építsd meg a felületet, és csak a próbálkozás után nyisd le a megoldást.

Alap szint

1. Pizza extrák

Az alap pizza 1500 Ft. Három CheckBox (chkSajt, chkSonka, chkGomba) extránként 300 Ft. A btnAr gomb írja ki a fizetendő összeget a lblAr feliratra.

Megoldás megnyitása

Minden jelölőnégyzetet külön if vizsgál, mert egyszerre többet is be lehet jelölni. A Checked igaz/hamis érték.

Form1.csC#
private void btnAr_Click(object sender, EventArgs e)
{
int ar = 1500;

if (chkSajt.Checked)
{
ar = ar + 300;
}

if (chkSonka.Checked)
{
ar = ar + 300;
}

if (chkGomba.Checked)
{
ar = ar + 300;
}

lblAr.Text = "Fizetendő: " + ar + " Ft";
}

2. Színválasztó

Három RadioButton (rbPiros, rbZold, rbKek) állítsa a lblMinta felirat betűszínét. Egyetlen eseménykezelőt használj.

Megoldás megnyitása

A tervezőben mindhárom RadioButton CheckedChanged eseményénél a legördülő listából válaszd ugyanazt a metódust. A Checked vizsgálattal derül ki, melyik az aktív.

Form1.csC#
private void SzinValtozott(object sender, EventArgs e)
{
if (rbPiros.Checked)
{
lblMinta.ForeColor = Color.Red;
}
else if (rbZold.Checked)
{
lblMinta.ForeColor = Color.Green;
}
else if (rbKek.Checked)
{
lblMinta.ForeColor = Color.Blue;
}
}

Közepes szint

3. Pizza méret és extrák

Add hozzá a 1. feladathoz a méretet is: kicsi 1000 Ft, közepes 1500 Ft, nagy 2000 Ft (rbKicsi, rbKozepes, rbNagy egy GroupBox-ban). Az extrák továbbra is 300 Ft-ba kerülnek. Az ár minden változáskor frissüljön.

Megoldás megnyitása

Az ár kiszámítását külön metódusba tesszük, amelyet minden vezérlő CheckedChanged eseménye hív. Így nincs szükség gombra.

Form1.csC#
private void ArSzamol()
{
int ar = 1500;

if (rbKicsi.Checked)
{
ar = 1000;
}
else if (rbNagy.Checked)
{
ar = 2000;
}

if (chkSajt.Checked) { ar = ar + 300; }
if (chkSonka.Checked) { ar = ar + 300; }
if (chkGomba.Checked) { ar = ar + 300; }

lblAr.Text = "Fizetendő: " + ar + " Ft";
}

private void Valtozas(object sender, EventArgs e)
{
ArSzamol();
}

4. Mindet kijelöl

A chkMind jelölőnégyzet bejelölésekor jelölje be az összes extrát, kikapcsoláskor kapcsolja ki őket.

Megoldás megnyitása

A chkMind CheckedChanged eseményében a másik három jelölőnégyzet értékét a chkMind.Checked értékére állítjuk.

Form1.csC#
private void chkMind_CheckedChanged(object sender, EventArgs e)
{
chkSajt.Checked = chkMind.Checked;
chkSonka.Checked = chkMind.Checked;
chkGomba.Checked = chkMind.Checked;
}

Kihívás szint

5. Kapcsolható lámpa

Egy chkBe jelölőnégyzet kapcsolja a lámpát (pnlLampa Panel). Bekapcsolva a három színes RadioButton adja a panel színét, kikapcsolva a panel szürke. Minden vezérlő ugyanazt a metódust hívja.

Megoldás megnyitása

A közös Frissit() metódus az aktuális állapotból számolja ki a megjelenést, így nem számít, melyik vezérlő váltotta ki.

Form1.csC#
private void Frissit()
{
if (!chkBe.Checked)
{
pnlLampa.BackColor = Color.Gray;
}
else if (rbPiros.Checked)
{
pnlLampa.BackColor = Color.Red;
}
else if (rbZold.Checked)
{
pnlLampa.BackColor = Color.LimeGreen;
}
else
{
pnlLampa.BackColor = Color.Blue;
}
}

private void Valtozas(object sender, EventArgs e)
{
Frissit();
}

6. Kvízkérdés

Kérdés: Melyik Magyarország fővárosa? A válaszok három RadioButton (rbDebrecen, rbBudapest, rbSzeged). Az btnEllenor gomb zöld Helyes! vagy piros Nem jó, próbáld újra! üzenetet ír a lblVisszajelzes feliratra. Ha nincs válasz kijelölve, kérje a választást.

Megoldás megnyitása

Három esetet kell kezelni: nincs választás, helyes választás, rossz választás. A RadioButton-ok közül legfeljebb egy lehet kijelölve, ezért mindhármat meg kell vizsgálni a „nincs választás” esethez.

Form1.csC#
private void btnEllenor_Click(object sender, EventArgs e)
{
if (!rbDebrecen.Checked && !rbBudapest.Checked && !rbSzeged.Checked)
{
lblVisszajelzes.ForeColor = Color.DarkOrange;
lblVisszajelzes.Text = "Válassz egy választ!";
}
else if (rbBudapest.Checked)
{
lblVisszajelzes.ForeColor = Color.SeaGreen;
lblVisszajelzes.Text = "Helyes!";
}
else
{
lblVisszajelzes.ForeColor = Color.Firebrick;
lblVisszajelzes.Text = "Nem jó, próbáld újra!";
}
}

Gyors önellenőrzés

Válaszolj fejben, és csak utána nyisd le a választ.

1. Mi a különbség a Checked és a Text között?

A Checked igaz/hamis érték (be van-e jelölve), a Text a felirat szövege.

2. Miért kell a RadioButtonokat GroupBoxba tenni?

Mert az azonos tárolóban lévő RadioButtonok alkotnak egy csoportot, amelyben egyszerre csak egy választható. Több független választáshoz több GroupBox kell.

3. Mikor fut le a CheckedChanged esemény?

Amikor a Checked értéke megváltozik, akár a felhasználó kattintása, akár kód miatt.

4. Miért fut le két RadioButton eseménykezelője egy váltásnál?

Az egyiknél a kijelölés megszűnik, a másiknál létrejön. Mindkettőnél változik a Checked.

5. Mi a különbség a = és a == között?

Az = értéket ad, a == összehasonlít.

6. Miért érdemes közös Frissit() metódust írni?

Hogy az összes vezérlő állapotát egy helyen kezeljük, és ne kelljen ugyanazt a kódot több eseménykezelőbe másolni.

Mit tudsz már?

  • Kiolvasod a CheckBox és a RadioButton állapotát a Checked tulajdonsággal.
  • Reagálsz a CheckedChanged eseményre.
  • GroupBoxba csoportosítod a RadioButtonokat.
  • Közös metódussal frissíted a felületet.
  • Megkülönbözteted az = és a == jelet.

Következő lecke: CheckedListBox és ListBox

Eddig néhány választási lehetőségünk volt. A következő leckében listákból választunk.