Grafikus C# – Windows Forms tanfolyam › 1.5 lecke Windows Forms · 1.5 lecke · önálló gyakorlás Egy névlistából több nevet is ki lehet választani, majd a kijelölteket egy másik listába lehet másolni. Ebben a leckében megismered a két lista vezérlő működését, és megtanulod megkülönböztetni a kijelölt és a bepipált elemet.CheckedListBox és ListBox – több elem kiválasztása

A lecke végére
- listákat töltesz fel elemekkel az
Items.Add()metódussal; - megkülönbözteted a kijelölt (Selected) és a bepipált (Checked) elemet;
- a
foreachciklussal végigmész a bepipált elemeken; - törölsz egy elemet vagy az egész listát (
RemoveAt,Clear); - kiolvasod az elemek számát (
Items.Count); - beállítod a
CheckOnClicktulajdonságot, hogy egy kattintás elég legyen a pipához.
Mielőtt elkezded
Ehhez a leckéhez kell az 1.4 lecke és a Form1_Load eseményt bemutató 0.8 lecke. A foreach ciklust a lecke közben magyarázzuk el.
A felület
Tegyél az ablakra két listát, két gombot és egy feliratot:
CheckedListBox: minden sora mellett jelölőnégyzet van. Az előtag clb.ListBox: a kiválasztott nevek listája. Az előtag lst.Kijelöltek másolása, Lista ürítése és Kijelölt törlése (ez utóbbit az 5. szakaszban használjuk).Label, amely a kiválasztott nevek számát mutatja.Állítsd a Mit tegyél ide: a tervezőnézet két egymás melletti listával (balra a CheckedListBox néhány névvel, jobbra az üres ListBox), alattuk a két gomb és a számláló felirat.Javasolt fájlnév: winforms-1-5-felulet.webp · Alt szöveg: Az ablak CheckedListBoxszal, ListBoxszal és két gombbal a tervezőbenclbNevek CheckOnClick tulajdonságát True-ra (lásd a 3. szakaszt).
A lista feltöltése
A lista elemeit az Items gyűjtemény tartalmazza. Az Add() metódussal egyenként adhatsz hozzá elemet. A betöltéskor futó Form1_Load eseményben töltsük fel a nevekkel:
private void Form1_Load(object sender, EventArgs e)
{
clbNevek.Items.Add("István");
clbNevek.Items.Add("Judit");
clbNevek.Items.Add("Béla");
clbNevek.Items.Add("Lilla");
}clbNevek.Items.AddRange(new object[] { "István", "Judit" });. A new object[] { ... } egy elemlistát készít, amelyet a tömbökről szóló leckében részletesen tanulunk.Items tulajdonságnál a (Collection) gombbal a tervezőben is beírhatod az elemeket, ahogy a ComboBoxnál (1.6, 2.5).Jósolj!
Megnyitod a programot, de a Form1_Load metódust kézzel gépelted be, nem dupla kattintással hoztad létre. Mi lesz a listában?
Jóslat ellenőrzése
Üres lesz, mert a metódus nincs összekötve a Load eseménnyel, ezért sosem fut le. A tervezőben az ablak üres részére duplán kattintva jön létre a megfelelően összekötött Form1_Load.
Kijelölt vagy bepipált?
A CheckedListBoxban két külön dolog van, és könnyű összekeverni:
| Fogalom | Mit jelent? | Tulajdonság |
|---|---|---|
| Kijelölt (Selected) | A sor, amelyre rákattintottál, kiemelve látszik. Egyszerre egy sor lehet kijelölt. | SelectedItem, SelectedIndex |
| Bepipált (Checked) | A sor melletti jelölőnégyzet be van pipálva. Egyszerre több is lehet. | CheckedItems |
A CheckOnClick tulajdonság
Alapból az első kattintás csak kijelöli a sort, és a második kattintás pipálja be. Ez zavaró. A CheckOnClick tulajdonság True értékével már az első kattintás bepipálja a sort.
Jósolj!
A CheckOnClick értéke False. Egyszer rákattintasz a „Judit” sorra. Be van pipálva?
Jóslat ellenőrzése
Nincs. Az első kattintás kijelöli a sort, és csak a második kattintás pipálja be. A CheckOnClick = True esetén az első kattintás is bepipálja.
Új fogalom: a foreach ciklus
A bepipált elemek számát nem tudjuk előre, ezért ciklussal megyünk végig rajtuk. A foreach (magyarul: „minden egyes”) ciklus a gyűjtemény minden elemére egyszer lefuttatja a kapcsos zárójelek közötti kódot:
private void btnAtmasol_Click(object sender, EventArgs e)
{
lstValasztott.Items.Clear();
foreach (object nev in clbNevek.CheckedItems)
{
lstValasztott.Items.Add(nev);
}
lblDarab.Text = $"Kiválasztva: {lstValasztott.Items.Count}";
}nev az éppen soron lévő elem.Jósolj!
Bepipálod az István és a Lilla nevet, és megnyomod a gombot. Hány elem lesz a jobb oldali listában, és mi áll a feliraton?
Jóslat ellenőrzése
Két elem: István és Lilla. A felirat: Kiválasztva: 2. A foreach kétszer fut le, mert két bepipált elem van.
Mit tegyél ide: a futó program: a bal listában az István és a Lilla be van pipálva, a jobb listában ugyanez a két név látszik, alatta a „Kiválasztva: 2” felirat.Javasolt fájlnév: winforms-1-5-atmasolas.webp · Alt szöveg: A bepipált nevek átmásolva a jobb oldali listába
Törlés és darabszám
Két törlési mód van: az egész lista ürítése (Clear()) és egy kijelölt elem törlése (RemoveAt()). Utóbbinál a SelectedIndex mondja meg, melyik elem a kijelölt (ha nincs kijelölt elem, az értéke -1).
private void btnTorol_Click(object sender, EventArgs e)
{
lstValasztott.Items.Clear();
lblDarab.Text = "Kiválasztva: 0";
}
private void btnKijeloltTorol_Click(object sender, EventArgs e)
{
if (lstValasztott.SelectedIndex >= 0)
{
lstValasztott.Items.RemoveAt(lstValasztott.SelectedIndex);
}
else
{
MessageBox.Show("Előbb jelölj ki egy elemet!");
}
lblDarab.Text = $"Kiválasztva: {lstValasztott.Items.Count}";
}-1).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. A kijelölteket másolja a bepipáltak helyett
foreach (object nev in clbNevek.SelectedItems)
{
lstValasztott.Items.Add(nev);
}Hiba és javítás
Rossz működés: a SelectedItems a kijelölt (kiemelt) sorokat adja, nem a bepipáltakat. A CheckedListBox jelölőnégyzeteihez a CheckedItems kell.
2. Összeomlik törléskor
lstValasztott.Items.RemoveAt(lstValasztott.SelectedIndex);Hiba és javítás
Futás közbeni hiba (ArgumentOutOfRangeException), ha nincs kijelölt elem, mert a SelectedIndex ilyenkor -1. Előbb ellenőrizd: if (lstValasztott.SelectedIndex >= 0).
3. Duplikált nevek
A másolás gombot kétszer nyomod meg, és a jobb listában kétszer szerepelnek a nevek. A másolás előtt nem ürítetted a jobb oldali listát. Tedd az eseménykezelő elejére az Ok és javítás
lstValasztott.Items.Clear(); sort.
4. Üres a lista induláskor
Az ablak megnyitása után egyetlen név sincs a listában. A Ok és javítás
Form1_Load nincs összekötve a Load eseménnyel (kézzel gépelted be), vagy üres a metódus belseje. Kattints duplán az ablak üres részére a tervezőben, és ott add meg a feltöltést.
5. Kétszer kell kattintani a pipához
A CheckedListBoxban egy kattintás csak kijelöl, nem pipál. A Ok és javítás
CheckOnClick tulajdonság értéke False. Állítsd True-ra a Properties ablakban.
Mini projekt: meghívottak listája
Állítsd össze a teljes programot:
- A két lista, a gombok és a felirat a megadott nevekkel. A
CheckOnClicklegyenTrue. - A
Form1_Loadtöltse fel a nevekkel a CheckedListBoxot (legalább hat név). - A Kijelöltek másolása gomb másolja át a bepipált neveket, és a felirat mutassa a darabszámot.
- A Lista ürítése gomb ürítse a jobb oldali listát.
- Próbáld ki: pipálj be két nevet, másold át, majd pipálj be még egyet, és másolj újra.
Mit tegyél ide: a kész program néhány bepipált névvel és a másolt névsorral a jobb oldali listában.Javasolt fájlnév: winforms-1-5-meghivottak.webp · Alt szöveg: A kész meghívottak listája program
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. Új név hozzáadása
Tegyél az ablakra egy txtUj beviteli mezőt és egy btnHozzaad gombot, amely az új nevet a CheckedListBox végére teszi (üres név ne kerüljön be).Egy lehetséges megoldás
string nev = txtUj.Text.Trim();
if (nev.Length > 0)
{
clbNevek.Items.Add(nev);
txtUj.Clear();
}
2. Kijelölt elem törlése
Készíts egy Használd a leckében látott btnKijeloltTorol gombot, amely a jobb oldali listából a kijelölt elemet törli.Egy lehetséges megoldás
btnKijeloltTorol_Click eseménykezelőt, SelectedIndex >= 0 ellenőrzéssel és RemoveAt hívással.
3. Mennyi van bepipálva?
Írd ki egy Tedd a másolás gombba, vagy a lista lblBepipalt feliratra, hogy hány elem van bepipálva a bal oldali listában. A CheckedItems gyűjteménynek is van Count tulajdonsága.Egy lehetséges megoldás
lblBepipalt.Text = $"Bepipálva: {clbNevek.CheckedItems.Count}";ItemCheck eseményéhez (az 5. fejezetben tanulunk róla).
Gyakorlótár: 6 további feladat
Három szinten gyakorolhatsz: alap, közepes és kihívás. Használd a txtElem beviteli mezőt, a lstElemek ListBoxot és a leírt gombokat. Csak a saját próbálkozásod után nyisd le a megoldást.
Alap szint
1. Elem hozzáadása
A A btnHozzaad gomb vegye fel a mezőbe írt szöveget a listába, majd ürítse a mezőt. Üres szöveget ne vegyen fel.Megoldás megnyitása
Items.Add adja hozzá az elemet. A Trim() a szóközöket levágja a szöveg széléről.private void btnHozzaad_Click(object sender, EventArgs e)
{
string elem = txtElem.Text.Trim();
if (elem.Length == 0)
{
MessageBox.Show("Írj be valamit!");
return;
}
lstElemek.Items.Add(elem);
txtElem.Clear();
txtElem.Focus();
}
2. A kijelölt elem törlése
A A btnTorol gomb törölje a kijelölt elemet. Ha nincs kijelölt elem, a program ne omoljon össze, hanem szóljon.Megoldás megnyitása
SelectedIndex értéke -1, ha nincs kijelölt elem. A RemoveAt(-1) hibát okozna, ezért előbb ellenőrzünk.private void btnTorol_Click(object sender, EventArgs e)
{
if (lstElemek.SelectedIndex >= 0)
{
lstElemek.Items.RemoveAt(lstElemek.SelectedIndex);
}
else
{
MessageBox.Show("Előbb jelölj ki egy elemet!");
}
}
Közepes szint
3. Duplikáció elkerülése
Ugyanaz az elem ne kerülhessen be kétszer a listába. Az Megoldás megnyitása
Items.Contains igaz, ha az elem már szerepel. Az összehasonlítás kis- és nagybetűre is érzékeny (az alma és az Alma két külön elem).private void btnHozzaad_Click(object sender, EventArgs e)
{
string elem = txtElem.Text.Trim();
if (elem.Length == 0)
{
MessageBox.Show("Írj be valamit!");
}
else if (lstElemek.Items.Contains(elem))
{
MessageBox.Show("Ez az elem már szerepel a listában.");
}
else
{
lstElemek.Items.Add(elem);
txtElem.Clear();
}
}
4. A bepipált elemek listázása
Egy A CheckedListBox (clbTantargyak) tantárgyakat tartalmaz. A btnListaz gomb írja a lblEredmeny feliratra a bepipált elemeket vesszővel elválasztva.Megoldás megnyitása
CheckedItems csak a bepipált elemeket tartalmazza (nem azonos a kijelölt elemmel). A foreach végigmegy rajtuk, a TrimEnd a felesleges záró vesszőt és szóközt levágja.private void btnListaz_Click(object sender, EventArgs e)
{
string lista = "";
foreach (object elem in clbTantargyak.CheckedItems)
{
lista = lista + elem.ToString() + ", ";
}
if (lista.Length == 0)
{
lblEredmeny.Text = "Nincs bepipált elem.";
}
else
{
lblEredmeny.Text = lista.TrimEnd(',', ' ');
}
}
Kihívás szint
5. Másolás másik listába
A A pipák kikapcsolása során a btnMasol gomb másolja át a bepipált elemeket a lstValasztott ListBoxba (előbb ürítse), majd kapcsolja ki az összes pipát.Megoldás megnyitása
SetItemChecked(index, false) metódus kell, mert az elemeket indexükkel érjük el. A for ciklus a Items.Count értékéig megy.private void btnMasol_Click(object sender, EventArgs e)
{
lstValasztott.Items.Clear();
foreach (object elem in clbTantargyak.CheckedItems)
{
lstValasztott.Items.Add(elem);
}
for (int i = 0; i < clbTantargyak.Items.Count; i++)
{
clbTantargyak.SetItemChecked(i, false);
}
}
6. Bevásárlólista darabszámmal
A lista legyen ábécébe rendezett, és a A ListBox lblDarab felirat mutassa: 3 tétel. Hozzáadás és törlés után is frissüljön.Megoldás megnyitása
Sorted tulajdonságát állítsd True értékre a Properties ablakban: ekkor automatikusan rendezett marad. A darabszámot a Items.Count adja, amelyet külön metódusban frissítünk, és minden változtatás után meghívunk.private void DarabFrissit()
{
lblDarab.Text = $"{lstElemek.Items.Count} tétel";
}
private void btnHozzaad_Click(object sender, EventArgs e)
{
string elem = txtElem.Text.Trim();
if (elem.Length > 0)
{
lstElemek.Items.Add(elem);
txtElem.Clear();
DarabFrissit();
}
}
private void btnTorol_Click(object sender, EventArgs e)
{
if (lstElemek.SelectedIndex >= 0)
{
lstElemek.Items.RemoveAt(lstElemek.SelectedIndex);
DarabFrissit();
}
}
Gyors önellenőrzés
Válaszolj fejben, és csak utána nyisd le a választ. A A kijelölt sor kiemelt (egyszerre egy lehet), a bepipált sor jelölőnégyzete be van jelölve (egyszerre több is lehet). Kiüríti a lista összes elemét. A gyűjtemény minden elemére egyszer lefuttatja a ciklus belsejét. Az ablak betöltésekor, még a megjelenése előtt, egyszer.1. Melyik gyűjtemény tartalmazza a bepipált elemeket?
CheckedItems.2. Mi a különbség a kijelölt és a bepipált elem között?
3. Mit csinál az Items.Clear()?
4. Mit csinál a foreach?
5. Mi a SelectedIndex értéke, ha nincs kijelölt elem?
-1.6. Mikor fut a Form1_Load?
Mit tudsz már?
- Feltöltöd a listákat elemekkel.
- Megkülönbözteted a kijelölt és a bepipált elemet.
- A foreach ciklussal végigmész a bepipált elemeken.
- Törölsz egy elemet vagy az egész listát.
- Beállítod a CheckOnClick tulajdonságot.
Következő lecke: ComboBox, TrackBar és DateTimePicker
Eddig listából több elemet választottunk. A következő leckében legördülő listát, csúszkát és dátumválasztót használunk.




