Tartalom
18.1. feladat (Form sarokba igazítása gombnyomásra – szint: 1). Készíts WindowsForm alkalmazást, mely a képernyő 4 sarkába ugorhat. Legyen rajta 4 button, amelyre kattintva a form – a feliratának megfelelő – sarokba ugrik.
Magyarázat: Figyeljünk arra, hogy ne adjuk meg előre a lehetséges felbontás értékeit, helyette használjuk a Screen.PrimeryScreen objektum Bounds tulajdonságait.
18.1. forráskód. A Form sarokba igazítása
public partial class Frm_Sarokba : Form { private void Bt_BF_Click(object sender, EventArgs e) { Left = 0; Top = 0; } private void Bt_JF_Click(object sender, EventArgs e) { Left = Screen.PrimaryScreen.Bounds.Width - Width; Top = 0; } private void Bt_BL_Click(object sender, EventArgs e) { Left = 0; Top = Screen.PrimaryScreen.Bounds.Height - Height; } private void Bt_JL_Click(object sender, EventArgs e) { Left = Screen.PrimaryScreen.Bounds.Width - Width; Top = Screen.PrimaryScreen.Bounds.Height - Height; } }
18.2. feladat (Szöveg igazítása – szint: 1). Készíts WindowsForm alkalmazást, amely a label komponens szövegigazításait demonstrálja. A formon egy label legyen található, ami a form egész területét elfoglalja. A label egyes részeire kattintva változtathatjuk a szöveg igazítását.
Magyarázat: A 9 külön lehetőség miatt ne hozzunk létre komponenseket, és írjunk külön eseménykezelőket. Helyette képzeletben osszuk fel a form területét, és a kattintásokkor ez alapján állítsuk be a label komponens szövegének elrendezését.
18.2. forráskód. A szöveg igazítása
private void label_MouseClick(object sender, MouseEventArgs e) { int n = e.X / (label.Width / 3); int m = e.Y / (label.Height / 3); switch (m * 3 + n) { case 0: label.TextAlign = ContentAlignment.TopLeft; break; case 1: label.TextAlign = ContentAlignment.TopCenter; break; case 2: label.TextAlign = ContentAlignment.TopRight; break; case 3: label.TextAlign = ContentAlignment.MiddleLeft; break; case 4: label.TextAlign = ContentAlignment.MiddleCenter; break; case 5: label.TextAlign = ContentAlignment.MiddleRight; break; case 6: label.TextAlign = ContentAlignment.BottomLeft; break; case 7: label.TextAlign = ContentAlignment.BottomCenter; break; case 8: label.TextAlign = ContentAlignment.BottomRight; break; } }
18.3. feladat (Form és Label koordinátáinak kiírása – szint: 1). Írjon WindowsForm alkalmazást, amely az egér aktuális pozícióját írja ki. A pozíció rögtön frissüljön a fejlécben, ahogy az egér megmozdul. Legyen a form közepén egy panel, ami fölé érve az egér pozíciója a panelhez relatív legyen, vagyis a panel bal felső sarkában 0,0.
Magyarázat: Figyeljünk arra, hogy a panel a form közepén mindig pontosan középen legyen, és a form méretének negyedét foglalja csak el, akkor is, ha átméretezik az ablakot, ehhez iratkozzunk fel a form átméretezésének eseményére.
18.3. forráskód. Egér koordinátáinak kiírása
private void Frm_Holmozog_MouseMove(object sender, MouseEventArgs e) { Text = String.Format("Az egér koordinátái X:{0}, Y:{1}", e.X, e.Y); } private void Frm_Holmozog_Resize(object sender, EventArgs e) { PanelIgazit(); } private void Frm_Holmozog_Load(object sender, EventArgs e) { PanelIgazit(); } private void PanelIgazit() { panel.Left = (ClientSize.Width - panel.Width) / 2; panel.Top = (ClientSize.Height - panel.Height) / 2; }
18.4. feladat (Form mozgatása – szint: 2). Írjon WindowsForm alkalmazást, amellyel a form pozíciójának, méretének és átlátszóságának változásait mutathatja be. Két gomb szolgáljon a form méretének csökkentésére és növelésére. Adjunk meg minimális méretet a formnak, ami alá nem csökkenhet. Az átlátszóság 20% alá ne mehessen. A teljesen gombok-ra ugorjon a form teljesen a képernyő szélére a megfelelő irányba, majd tűnjön el, hogy ne lehessen megnyomni ha már az ablak szélére került a form, viszont jelenjen meg újra, ha elhagytuk azt valamelyik másik gomb segítségével. A balra, fel, jobbra, le gombok konstansként meghatározott mértékben mozgassák az ablakot, és ugyancsak ne látszódjanak, ha már a képernyő szélére került a form. A középre gomb hatására a form foglalja el pontosan a képernyő közepét (ilyenkor látszódjon minden gomb).
Magyarázat: Akárcsak az első feladatnál, itt is használjuk a Screen.PrimeryScreen.Bounds tulajdonságot a képernyő méreteihez. Figyeljünk arra, hogy ha elértük a határokat tüntessük el a megfelelő gombokat.
18.4. forráskód. Form jellemzői
private void Bt_M_Cso_Click(object sender, EventArgs e) { Width -= meretezo; Height -= meretezo; } private void Bt_Atl_No_Click(object sender, EventArgs e) { if (Opacity < 1.0) Opacity += 0.1; } private void Bt_Kozep_Click(object sender, EventArgs e) { Left = (Screen.PrimaryScreen.Bounds.Width - Width) / 2; Top = (Screen.PrimaryScreen.Bounds.Height - Height) / 2; Bt_Le.Visible = Bt_Le_T.Visible = Bt_Fel.Visible = Bt_Fel_T.Visible = Bt_Bal.Visible = Bt_Bal_T.Visible = Bt_Jobb.Visible = Bt_Jobb_T.Visible = true; }
18.5. forráskód. Form mozgatása
private void Bt_Fel_T_Click(object sender, EventArgs e) { Top = 0; Bt_Fel.Visible = Bt_Fel_T.Visible = false; Bt_Le.Visible = Bt_Le_T.Visible = true; } private void Bt_Fel_Click(object sender, EventArgs e) { if (Top - meretezo > 0) { Top -= meretezo; } else { Top = 0; Bt_Fel.Visible = Bt_Fel_T.Visible = false; } Bt_Le.Visible = Bt_Le_T.Visible = true; }
18.5. feladat (ScrollBar használata – szint: 2). Írjon programot, amely az additív színkeverést mutatja be. Egy négyzet alakú label háttérszíne mutassa a kevert színt. Három scrollbar komponenssel lehessen állítani a szín piros, kék, és zöld összetevőjét. Akármelyik csúszka pozíciója változik, rögtön frissüljön a szín. A színt mutató label méretét szintén egy csúszkával lehessen változtatni, ez 10 és 300 pixel közötti érték lehet.
Magyarázat: Ne felejtse el beállítani a scrollbarok minimum és maximum értékeit.
18.6. forráskód. ScrollBar használata
public partial class Frm_Csuszka : Form { private void Sb_Piros_ValueChanged(object sender, EventArgs e) { Lb_Negyzet.BackColor = Color.FromArgb(Sb_Piros.Value, SB_Zold.Value, SB_Kek.Value); } private void Sb_Oldal_ValueChanged(object sender, EventArgs e) { Lb_Negyzet.Width = Lb_Negyzet.Height = Sb_Oldal.Value; Lb_Oldal.Text = Sb_Oldal.Value.ToString(); } }
18.6. feladat (Képet forgat – szint: 1). Írjon programot, mely köralakban jelenít meg képeket, és mindkét irányba körbe léptethetőek.
Magyarázat: A képek egymás közti forgatásához vegyünk fel egy Image típusú segédváltozót.
public partial class Frm_Kepforog : Form { private void Pb_Bal_Click(object sender, EventArgs e) { Image s = Lb_1.Image; Lb_1.Image = Lb_2.Image; Lb_2.Image = Lb_3.Image; Lb_3.Image = Lb_4.Image; Lb_4.Image = Lb_5.Image; Lb_5.Image = Lb_6.Image; Lb_6.Image = Lb_7.Image; Lb_7.Image = Lb_8.Image; Lb_8.Image = s; } }
18.7. feladat (Futásidejű komponensek – szint: 2). Készítsen programot, ami minden egérkattintáskor egy-egy új label komponenst hoz létre dinamikusan. Az új label felirata legyen egy véletlen szám 1 és 100 között. Számoljuk, hogy mennyi új komponens jött létre, mi a véletlen számok összege, átlaga, minimuma és maximuma.
Magyarázat: A min és max változók inicializálásánál célszerű az int típus szélsőértékeit használni, hiszen pl. a int.MinValue-nál csak nagyobb számot generálhatunk. Véletlen szám generálásnál figyeljünk a határokra, a Random(100) 0 és 99 közötti számot generál, ezt még el kell tolni egyel. Az újonnan létrehozott label komponenst ne felejtsük el hozzáadni a form Controls tömbjéhez, hisz csak ekkor fog megjelenni. Átlagszámításnál figyeljünk arra, hogy az osztót (db) lebegőpontosra kell alakítani, mert különben egész osztást alkalmaz a fordító.
18.8. forráskód. Futás idejű létrehozás
public partial class Frm_Dinamikus : Form {Random random = new Random(); double atlag; int osszeg, db, min = int.MaxValue, max = int.MinValue;} private void Frm_Dinamikus_MouseClick(object sender, MouseEventArgs e) { int i = random.Next(100) + 1; Label lb = new Label(); lb.Location = new Point(e.X, e.Y); lb.Text = i.ToString(); lb.AutoSize = true; Controls.Add(lb); db++; osszeg += i; atlag = osszeg / (double)db; if (min > i) min = i; if (max < i) max = i; lb_Eredmeny.Text = String.Format("Darabszám: {0}, összeg: {1}, átlag: {2}," +"minimum: {3}, maximum: {4}.", db, osszeg, atlag, min, max); } }
18.8. feladat (Halmazok – szint: 3). Írjon programot, amely bemutatja két halmaz közötti műveleteket. Egy-egy halmaznak egy-egy listbox komponensek feleljen meg. Kezdetben legyen üres mind az A, és B halmaz is. Mindkét halmaz elemszámát kérjük be, majd töltsük fel őket véletlen számokkal, és számoljuk ki A unió B -t, A metszet B-t, A-B és B-A eredményét is.
Magyarázat: A feltöltésnél figyeljünk arra, hogy nem csak egyszerű adatsorozatot készítünk, hanem halmazt, melynek fő tulajdonsága, hogy egy elem csak egyszer szerepelhet benne.
18.9. forráskód. Halmaz generálása
private void Bt_Eloall_Click(object sender, EventArgs e) { HalmazGeneral(LBx_A, Convert.ToInt32(TBx_A.Text)); HalmazGeneral(LBx_B, Convert.ToInt32(TBx_B.Text)); Metszet(LBx_A, LBx_B, LBx_Metsz); Unio(LBx_A, LBx_B, LBx_Unio); Minusz(LBx_A, LBx_B, LBx_A_B); Minusz(LBx_B, LBx_A, LBx_B_A); } private void HalmazGeneral(ListBox LB, int N) { int elem; LB.Items.Clear(); for (int i = 0; i < N; i++) { do { elem = random.Next(N * 5); } while (Bennevan(LB, elem)); LB.Items.Add(elem); } } private bool Bennevan(ListBox LB, object elem) { for (int i = 0; i < LB.Items.Count; i++) if (LB.Items[i].Equals(elem)) return true; return false; }
18.10. forráskód. Halmazműveletek
private void Unio(ListBox LBx_A, ListBox LBx_B, ListBox LBx_Unio) { LBx_Unio.Items.Clear(); for (int i = 0; i < LBx_A.Items.Count; i++) { if (!Bennevan(LBx_Unio, LBx_A.Items[i])) { LBx_Unio.Items.Add(LBx_A.Items[i]); } } for (int i = 0; i < LBx_B.Items.Count; i++) { if (!Bennevan(LBx_Unio, LBx_B.Items[i])) { LBx_Unio.Items.Add(LBx_B.Items[i]); } } } private void Metszet(ListBox LBx_A, ListBox LBx_B, ListBox LBx_Metsz) { LBx_Metsz.Items.Clear(); for (int i = 0; i < LBx_A.Items.Count; i++) { if (Bennevan(LBx_B, LBx_A.Items[i])) { LBx_Metsz.Items.Add(LBx_A.Items[i]); } } }
18.9. feladat (Mátrix – szint: 4). Készítsen programot, mely egy mátrix elemeit feltölti véletlen számokkal, majd kiírja melyik a legkisebb, ill. legnagyobb szám, és hol vannak. A mátrixot jelenítse meg egy DataGridView komponensben, oszlopainak és sorainak száma 2 és 10 közötti - nem feltétlenül egyenlő - számok legyenek, és a felhasználó adhassa meg NumericUpDown komponenssel.
Magyarázat: A NumericUpDown komponensnél ne felejtsük el beállítani a határokat. A grid kialakításánál figyeljünk oda, hogy letiltsuk azt (ReadOnly property), illetve ne látszódjanak az oszlop- és sorfejlécek (ColumnHeadersVisible, RowHeadersVisible property-k).
Magyarázat: Feltöltéskor ne felejtsük el létrehozni az oszlopokat a táblázatba, és csak ezután adjuk hozzá a véletlen számokból álló sorokat.
private void AdatokFeltolt(int N, int M) { dataGridView.Columns.Clear(); dataGridView.Rows.Clear(); for (int j = 0; j < M; j++) { dataGridView.Columns.Add(String.Empty, String.Empty); dataGridView.Columns[j].Width = 35; } for (int i = 0; i < N; i++) { object[] intArrray = new object[M]; for (int j = 0; j < M; j++) { intArrray[j] = random.Next(N * M * 10) + 1; } dataGridView.Rows.Add(intArrray); } }
Magyarázat: A táblázat feldolgozásakor ne felejtsük, hogy a táblázat cellái object típusúként vannak eltárolva, felhasználásukkor át kell alakítani (castolni) int típusúra őket.
A eredmény kiárásához használt RichTextBox komponens szövegét ne felejtsük el alaphelyzetbe állítani (ResetText metódus), és csak ezután írjunk bele (AppendText).
private void EredmenyKiir(int N, int M) { int max = int.MinValue, min = int.MaxValue; int maxi, maxj, mini, minj; maxi = maxj = mini = minj = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { if ((int)dataGridView[j, i].Value > max) { max = (int)dataGridView[j, i].Value; maxi = i; maxj = j; } if ((int)dataGridView[j, i].Value < min) { min = (int)dataGridView[j, i].Value; mini = i; minj = j; } } } richTextBox.ResetText(); richTextBox.AppendText(String.Format("A legnagyobb elem: {0}{1}", max, Environment.NewLine)); richTextBox.AppendText(String.Format("A legnagyobb elem indexe:" +"({0},{1}){2}", maxi + 1, maxj + 1, Environment.NewLine)); richTextBox.AppendText(String.Format("A legkisebb elem: {0}{1}", min, Environment.NewLine)); richTextBox.AppendText(String.Format("A legkisebb elem indexe:" +"({0},{1}){2}", mini + 1, minj + 1, Environment.NewLine)); }
18.10. feladat (Szorzótábla – szint: 4). Készítsen programot a szorzótábla gyakorlására. A program véletlenszerűen kérdezzen rá a szorzatokra, jelezze az első sorban és oszlopban más háttérszínnel, hogy éppen melyik két szám szorzatára vagyunk kíváncsiak. Ugyancsak legyen más színű az a cella, ahová az eredményt várjuk, és rajta kívül egyetlen másik cella se legyen szerkeszthető. Elhagyva a cellát a program értékelje a számításunkat, ha jó számot adunk meg, akkor kérje a következő szorzatot, ha rosszat, akkor kérje be újra. A felhasználó két label-ben lássa, hogy hány jó, ill. rossz választ adott meg eddig. Ha minden cellát helyesen kitöltött egy üzenetablakban gratuláljunk neki.
Magyarázat: A 9. feladathoz hasonlóan itt is tiltsuk le a gridben a sor és oszlop fejléceket, de ne állítsuk csak szerkeszthetőre (readonly). A grid szerkesztési módját (EditMode) állítsuk EditOnEnter-re.
18.13. forráskód. Sorsol egy pozíciót
private void Sorsol() { do { aktI = random.Next(N) + 1; aktJ = random.Next(N) + 1; } while (dataGridView[aktJ, aktI].Value != null); dataGridView[aktJ, aktI].Style.BackColor = dataGridView[0, aktI].Style.BackColor = dataGridView[aktJ, 0].Style.BackColor = Color.PowderBlue; }
18.14. forráskód. Feltölti a fejléceket
private void TablaEpit() { dataGridView.Columns.Clear(); dataGridView.Rows.Clear(); dataGridView.Width = 35 * (N + 1) + 3; for (int j = 0; j <= N; j++) { dataGridView.Columns.Add(String.Empty, String.Empty); dataGridView.Columns[j].Width = 35; } for (int i = 0; i <= N; i++) { object[] intArrray = new object[N]; dataGridView.Rows.Add(intArrray); } for (int i = 1; i <= N; i++) { dataGridView[i, 0].Value = i; dataGridView[i, 0].Style.Font = new Font(dataGridView.Font, FontStyle.Bold); } for (int j = 1; j <= N; j++) { dataGridView[0, j].Value = j; dataGridView[0, j].Style.Font = new Font(dataGridView.Font, FontStyle.Bold); } }
Magyarázat: Az új kérdés sorsolásakor figyeljünk arra, hogy olyan szorzatot válasszunk, amit még nem töltött ki a felhasználó, és sor-, ill. oszlopindexét tároljuk el változókban, ezek alapján tudjuk figyelni a grid CellBeginEdit eseményében, hogy a megfelelő cellát kezdi-e el szerkeszteni a felhasználó.
private void dataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e) { if (dataGridView[aktJ, aktI].Value == null) return; if (aktI * aktJ == Convert.ToInt32(dataGridView[aktJ, aktI].Value)) { dataGridView[aktJ, aktI].Style.BackColor = dataGridView.DefaultCellStyle.BackColor; dataGridView[0, aktI].Style.BackColor = dataGridView[aktJ, 0].Style.BackColor = dataGridView.DefaultCellStyle.BackColor; joValasz++; lb_Joalasz.Text = String.Format("Jó válaszaid száma: {0}", joValasz); if (joValasz < N * N) { Sorsol(); } else { MessageBox.Show("Gratulálok, kész a szorzótábla!"); dataGridView.Enabled = false; } } else { dataGridView[aktJ, aktI].Value = null; rosszValasz++; lb_Rosszvalasz.Text = String.Format("Rossz válaszaid száma:" +"{0}", rosszValasz); MessageBox.Show("Rossz válasz!"); } }
18.11. feladat (LNKO LKKT – szint: 1). Írjon programot, mely bekér két egész számot, és kiszámolja azok legnagyobb közös osztóját (LNKO) és legkisebb közös többszörösét (LKKT). Hogy épp melyiket számolja ki, azt rádiógombokkal lehessen beállítani. Külön gomb szolgáljon a kilépésre.
Magyarázat: Elég megírjuk az lnko algoritmusát, hiszen a legkisebb közös többszöröst az (a*b)/LNKO(a,b) képlet megadja.
public int LNKO(int a, int b) { if (a == 0) return b; if (b == 0) return a; if (a > b) return LNKO(a % b, b); else return LNKO(a, b % a); }
Magyarázat: Az int.TryParse(...) metódusával ellenőrizzük le hogy tényleg számot adott-e meg a felhasználó, és csak ez után számoljunk.
18.17. forráskód. Művelet elvégzése
private void button1_Click(object sender, EventArgs e) { int a, b; // Adatok ellenőrzése számítás előtt if (!int.TryParse(TBx_A.Text, out a)) { MessageBox.Show("Nem megfelelő szám!"); TBx_A.Text = String.Empty; TBx_A.Focus(); return; } if (!int.TryParse(TBx_B.Text, out b)) { MessageBox.Show("Nem megfelelő szám!"); TBx_B.Text = String.Empty; TBx_B.Focus(); return; } if (Rb_LNKO.Checked) { MessageBox.Show(String.Format( "A két szám legnagyobb közös osztója: {0}", LNKO(a, b))); } else { MessageBox.Show(String.Format( "A két szám legkisebb közös többszöröse: {0}", (a * b) / LNKO(a, b))); } }
18.12. feladat (Formázás – szint: 2). Készítsünk alkalmazást, mely egy szöveg betűtípusának beállításait mutatja be. Lehessen beállítani a betűtípus méretét, stílusát (dőlt, aláhúzott, félkövér), típusát (3 választás: Arial, Times New Roman, Comic Sans). Használjunk ComboBox és CheckBox komponenseket. Állítható legyen továbbá a label szövegének és hátterének színe is. Adjon lehetőséget a program a label szövegének átírására is.
18.18. forráskód. Változtatás kezelése
private void Cbx_Piros_CheckedChanged(object sender, EventArgs e) { if (Comb_Mit.SelectedIndex == 0) { Lb_Proba.ForeColor = SzinBeallit(); } else { Lb_Proba.BackColor = SzinBeallit(); } }
18.19. forráskód. Font beállításai
private void FontBeallit() { Lb_Proba.Font = new Font(GetFontName(), (int)NDD_Fontmeret.Value, GetFontStyle()); } private FontStyle GetFontStyle() { FontStyle result = FontStyle.Regular; if (Cbx_Alahuz.Checked) result |= FontStyle.Underline; if (Cbx_Dolt.Checked) result |= FontStyle.Italic; if (Cbx_Felk.Checked) result |= FontStyle.Bold; return result; } private string GetFontName() { if (Rb_Arial.Checked) return Rb_Arial.Text; else if (Rb_CS.Checked) return Rb_CS.Text; else if (Rb_TNR.Checked) return Rb_TNR.Text; return String.Empty; }
Magyarázat: A GetFontStyle metódusban használjuk ki, hogy a FontStyle felsorolástípus maszkolható, vagyis az aláhúzás, dőlt betű és a vastag betűs tulajdonságokat egymástól függetlenül is be lehet állítani a ’|’ operátor segítségével.
18.20. forráskód. Szín beállítás és ComboBox
private Color SzinBeallit() { return Color.FromArgb( Cbx_Piros.Checked ? 255 : 0, Cbx_Zold.Checked ? 255 : 0, Cbx_Kek.Checked ? 255 : 0 ); } private void Comb_Mit_SelectedIndexChanged(object sender, EventArgs e) { GB_Font.Enabled = GB_Stilus.Enabled = NDD_Fontmeret.Enabled = (Comb_Mit.SelectedIndex == 0); CheckBoxokBeallit((Comb_Mit.SelectedIndex == 0) ? Lb_Proba.ForeColor : Lb_Proba.BackColor); }
Magyarázat: A színek beállításánál a kijelöléstől függően állítsuk a szín adott komponensét 0, vagy 255 értékre.
18.13. feladat (Logikai műveletek – szint: 2). Készítsen programot, mely bemutatja a matematikai logikai műveleteket. Egy combobox-ból lehessen kiválasztani az aktuális műveletet, az operandusok (A és B, vagy csak A) értékét checkbox komponenssel állítsuk be. Ezen kívül a program írja ki a számolási szabályokat a műveletek között: kommutativitás, asszociativitás, disztributivitás.
Magyarázat: Figyeljünk arra, hogy attól függően, hogy 1 vagy 2 operandusú az operátor, csak annyi bemeneti adat (CheckBox) legyen kötelező.
18.21. forráskód. ComboBox kezelése
private void Frm_Logika_Load(object sender, EventArgs e) { comboBoxMuvelet.SelectedIndex = 0; } private void comboBoxMuvelet_SelectedIndexChanged(object sender, EventArgs e) { Cbx_B.Enabled = comboBoxMuvelet.SelectedIndex != 0; }
18.22. forráskód. Logikai műveletek
private void Bt_Eredmeny_Click(object sender, EventArgs e) { switch (comboBoxMuvelet.SelectedIndex) { case 0: MessageBox.Show(String.Format("not A = {0}", !Cbx_A.Checked)); break; case 1: MessageBox.Show(String.Format("A and B = {0}", Cbx_A.Checked & Cbx_B.Checked)); break; case 2: MessageBox.Show(String.Format("A or B = {0}", Cbx_A.Checked | Cbx_B.Checked)); break; case 3: MessageBox.Show(String.Format("A nand B = {0}", !(Cbx_A.Checked & Cbx_B.Checked))); break; case 4: MessageBox.Show(String.Format("A nor B = {0}", !(Cbx_A.Checked | Cbx_B.Checked))); break; case 5: MessageBox.Show(String.Format("A xor B = {0}", Cbx_A.Checked ^ Cbx_B.Checked)); break; } } private void Rb_Komm_CheckedChanged(object sender, EventArgs e) { if (Rb_Komm.Checked) { Lb_SzSz.Text = "A and B = B and A" + Environment.NewLine + "A or B = B or A"; } else if (Rb_Assz.Checked) { Lb_SzSz.Text = "A and (B and C) = (A and B) and C" + Environment.NewLine + "A or (B or C) = (A or B) or C"; } else if (Rb_Disz.Checked) { Lb_SzSz.Text = "A and (B or C) = (A and B) or (A and C)" + Environment.NewLine + "A or (B and C) = (A or B) and (A or C)"; } }
18.14. feladat (Jegykiadó program – szint: 2). Írjon programot, ami különböző paraméterek alapján kiszámol egy vonatjegy árat. Lehessen megadni, hogy hova utazunk (Budapest 1500Ft, Hatvan 1300Ft, Székesfehérvár 2000Ft, Kecskemét 2800Ft), milyen kedvezményünk van (nappali tagozatos diák 50%, nyugdíjas 50%, törzsutas kártya 70%), és hogy milyen egyéb szolgáltatásokat kell igénybe vennünk (kutya 800Ft, bicikli 600Ft, túlméretes poggyász 400Ft). A beállítások után egy gombra kattintva írja ki a program a fizetendő árat, egy másik gomb pedig adjon lehetőséget a beállítások törlésére.
Magyarázat: Nem lehet igénybe venni egyszerre nappali tagozatos diák és nyugdíjas kedvezményt.
private void NyomtatásButton_Click(object sender, EventArgs e) { double díj = 0; if (Cbx_Napp.Checked && Cbx_Nyug.Checked) { Lb_Koltseg.Text = "Hiba!"; return; } if (Rb_Bud.Checked) díj = 1500; if (Rb_Hat.Checked) díj = 1300; if (Rb_Szek.Checked) díj = 2000; if (Rb_Kecs.Checked) díj = 2800; if (Cbx_Kutya.Checked) díj = díj + 800; if (Cbx_Bicikli.Checked) díj = díj + 600; if (Cbx_Poggy.Checked) díj = díj + 400; if (Cbx_Napp.Checked) díj = díj * 0.5; if (Cbx_Nyug.Checked) díj = díj * 0.5; if (Cbx_Torzs.Checked) díj = díj * 0.7; Lb_Koltseg.Text = díj + " Ft"; }
18.15. feladat (Rendezések hatékonysága – szint: 3). Készítsen programot, mely rendezéseket hasonlít össze. Generáljunk egy ListBox komponensbe 10000 és 20000 közti véletlen darabszámú 0 és 1000 közötti véletlenszámot. Ezeken az elemeken mérjük le a minimumkiválasztos, beszúrásos, buborékos rendezéseket, valamint a ListBox beépített rendezését (.Sort()). Írjuk ki az egyes rendezések után, hány másodpercbe kerültek. 1-1 ProgressBar komponensen érzékeltessük az arányokat. Ha új számokat generálunk, töröljük az eddigi időeredményeket.
Magyarázat: Amíg nincs meg az adott rendezéshez tartozó időeredmény, addig a hozzá tartozó label és progressbar ne látszódjon a felületen.
18.24. forráskód. Véletlen számok generálása
private void Btn_General_Click(object sender, EventArgs e) { Random rnd = new Random(); Int32 db = rnd.Next(10000) + 10000, akt; listBox.Items.Clear(); listBox.BeginUpdate(); for (Int32 i = 0; i < db; i++) { akt = rnd.Next(1000); listBox.Items.Add(akt); list.Add(akt); } listBox.EndUpdate(); MessageBox.Show(String.Format("Generált elemek száma: {0}", db)); gombok.ForEach(bt => bt.Enabled = true); LB_Beszurasos.Visible = LB_Buborek.Visible = LB_Gyors.Visible = LB_Minkiv.Visible = PB_Beszurasos.Visible = PB_Buborek.Visible = PB_Gyorsrend.Visible = PB_Minkiv.Visible = false; eredmenyek.ForEach(pb => pb.Maximum = Int32.MaxValue); }
Magyarázat: A számok generálása közben érdemes kikapcsolni a ListBox komponens azonnali frissítését, hogy ne villogjon, és görgessen minden új elem hozzáadásakor. Ezt a BeginUpdate metódussal tehetjük meg, és a feltöltés után az EndUpdate hatására frissül a felületen a listbox. A gombok tömbben található Button objektumok mindegyikének engedélyezéséhez használjuk a generikus List<> adatszerkezet ForEach metódusát, ami egy delegate-et vár, és megadható neki lambda-kifejezés is (bt => bt.Enabled = true).
18.25. forráskód. Minimumkiválasztásos rendezés
private void Btn_Minkiv_Click(object sender, EventArgs e) { gombok.ForEach(bt => bt.Enabled = false); DateTime start = DateTime.Now; MinKivRend(new List<Int32>(list)); Double eredmeny = (DateTime.Now - start).TotalSeconds; LB_Minkiv.Text = String.Format("{0} mp", eredmeny); LB_Minkiv.Show(); PB_Minkiv.Value = PB_Minkiv.Maximum = (Int32)Math.Round(eredmeny * 100); Maxok(); PB_Minkiv.Show(); gombok.ForEach(bt => bt.Enabled = true); }
18.16. feladat (Lista karbantartása – szint: 3). Készítsünk programot, mely két ListBox karbantartását végzi el. Mindkét ListBox-on a következő műveleteket végezhetjük el: új elem felvétele, kijelölt elem törlése, kijelölt elem mozgatása (felülre, fel, le, alulra) Ehhez készítsünk külön komponenst, mely tartalmaz egy ListBox-ot, és a fenti műveletekhez 1-1 gombot. Egy TextBox-on kérje be az új elemet, és ez is legyen része a komponensnek. A főablakra két ilyen komponenst tegyünk fel, majd egészítsük ki még két publikus metódussal: RemoveSelectedItem, AddNewItem. Ezek segítségével oldjuk meg a két komponens között az elemek átadását.
Magyarázat: A komponens készítésekor ügyeljünk arra, hogy a funkciókat letiltsuk, ha azoknak nincs értelme, pl. üres listából értelmetlen törölni, és a legfelső elemet sem lehet feljebb mozgatni.
18.26. forráskód. Komponensek közti mozgatás
private void button3_Click(object sender, EventArgs e) { Object item = listBoxControl1.RemoveSelectedItem(); if (item != null) { listBoxControl2.AddNewItem(item); } } private void button4_Click(object sender, EventArgs e) { Object item = listBoxControl2.RemoveSelectedItem(); if (item != null) { listBoxControl1.AddNewItem(item); } }
18.27. forráskód. Komponens főbb funkciói
private void Btn_Hozzaad_Click(object sender, EventArgs e) { if (TB_Uj.Text != String.Empty) { LB.Items.Add(TB_Uj.Text); TB_Uj.Text = String.Empty; LB.SelectedIndex = LB.Items.Count - 1; GombokFrissit(); } TB_Uj.Focus(); } private void Btn_Torles_Click(object sender, EventArgs e) { Int32 selIndex = LB.SelectedIndex; if (selIndex >= 0) { LB.Items.RemoveAt(selIndex); if (selIndex < LB.Items.Count) LB.SelectedIndex = selIndex; else LB.SelectedIndex = LB.Items.Count - 1; GombokFrissit(); } } private void Btn_Fel_Click(object sender, EventArgs e) { Int32 selIndex = LB.SelectedIndex; if (selIndex > 0) { Object selItem = LB.SelectedItem; LB.Items.RemoveAt(selIndex); LB.Items.Insert(selIndex - 1, selItem); LB.SelectedIndex = selIndex - 1; } }
18.17. feladat (Fájl keresése – szint: 3). Írjunk programot, amely megadott elérési úton keres egy maszknak megfelelő fájlokat. Egy TextBox-ban kérjük be az elérési utat és a maszkot, pl.
"C:\*.txt"
. Meg lehessen adni egy CheckBox komponens segítségével, hogy rekurzívan keressünk-e, vagy csak az adott könyvtárban. A talált fájlokat egy ListBox komponensben jelenítsük meg.
18.28. forráskód. Könyvtárszerkezet bejárása
public void GetFileList(String dir, String mask, Boolean recursive, Action<String> action) {DirectoryInfo di = new DirectoryInfo(dir); try { FileInfo[] rgFiles = di.GetFiles(mask); foreach (FileInfo fi in rgFiles) action(fi.FullName); if (recursive) { DirectoryInfo[] dirs = di.GetDirectories(); foreach (DirectoryInfo dirInfo in dirs) GetFileList(Path.Combine(dir, dirInfo.Name), mask, recursive, action); } } catch (UnauthorizedAccessException) { } } private void Btn_Lista_Click(object sender, EventArgs e) { String dir = Path.GetDirectoryName(textBox.Text); String mask = textBox.Text.Substring(dir.Length); listBox.Items.Clear(); listBox.BeginUpdate(); GetFileList(dir, mask, checkBox1.Checked, name => listBox.Items.Add(name)); listBox.EndUpdate(); }
Magyarázat: A bejárás paramétere egy Action<String> típusú delegate, ezt a fájlnevet váró akciót fogja végrehajtani a bejárás minden találatra. A bejárás során kivételt kaphatunk, ha olyan könyvtárat akarunk megnyitni, amihez nincs jogunk, készüljünk fel erre is.
18.18. feladat (Számok kiválogatása – szint: 3). Írjunk programot, amely egy ListBox-ba generál véletlen számokat és egy CheckListBox-ban megadott feltételek alapján szűri egy másik ListBox-ba.
Magyarázat: A szűrőfeltételeket érdemes egy listában eltárolni (Egy int paramétert váró és logikai értéket visszaadó függvény Predicate<int> típusú.) Ezek után végig kell menni az összes elemen, és megnézni a szűrőfeltételeket (elég addig vizsgálni egy adott elemet, míg az egyik feltétel nem teljesül).
18.29. forráskód. Generálás és szűrés
private void Btn_General_Click(object sender, EventArgs e) { Btn_General.Enabled = false; Random rnd = new Random(); HashSet<Int32> voltak = new HashSet<Int32>(); LBx_Ossz.Items.Clear(); LBx_Ossz.BeginUpdate(); Int32 akt; for (Int32 i = 0; i < 1000; i++) { do { akt = rnd.Next(10000); } while (voltak.Contains(akt)); voltak.Add(akt); LBx_Ossz.Items.Add(akt); } LBx_Ossz.EndUpdate(); Btn_General.Enabled = true; } private void Btn_Mutat_Click(object sender, EventArgs e) { List<Predicate<Int32>> feltetelek = new List<Predicate<Int32>>(); if (checkedListBox1.CheckedIndices.Contains(0)) feltetelek.Add(Prim); if (checkedListBox1.CheckedIndices.Contains(1)) feltetelek.Add(Paros); if (checkedListBox1.CheckedIndices.Contains(2)) feltetelek.Add(Paratlan); if (checkedListBox1.CheckedIndices.Contains(3)) feltetelek.Add(Oszt3); if (checkedListBox1.CheckedIndices.Contains(4)) feltetelek.Add(Oszt6); if (checkedListBox1.CheckedIndices.Contains(5)) feltetelek.Add(Oszt9); if (checkedListBox1.CheckedIndices.Contains(6)) feltetelek.Add(Negyzet); LBx_Valogat.Items.Clear(); for (Int32 i = 0; i < LBx_Ossz.Items.Count; i++) { Boolean kell = false; foreach (Predicate<Int32> feltetel in feltetelek) { kell = kell || feltetel((Int32)LBx_Ossz.Items[i]); if (kell) break; } if (kell) LBx_Valogat.Items.Add(LBx_Ossz.Items[i]); } LB_Eredm.Text = String.Format("{0}/{1}", LBx_Valogat.Items.Count, LBx_Ossz.Items.Count); }
18.19. feladat (Napok száma – szint: 1). Írjon programot, melynek a segítségével bekér két dátumot, és meghatározza a két megadott dátum közötti napok számát!
18.30. forráskód. Különbség kiszámítása
private void monthCalendar_DateChanged(object sender, DateRangeEventArgs e) { if (MC_kezd.SelectionStart.CompareTo(MC_veg.SelectionStart) > 0) { LB_kulonbseg.Text = "A keződátum nagyobb, mint a végdátum."; } else { LB_kulonbseg.Text = String.Format("A két dátum között eltelt napok száma: {0}", MC_veg.SelectionStart.Subtract(MC_kezd.SelectionStart).Days); } }
18.20. feladat (Horoszkóp – szint: 1). Írjon programot, melynek a segítségével bekér egy születési dátumot, és meghatározza, hogy a felhasználó melyik csillagjegyben született. Az ablak fejlécében üdvözöljön minket napszaknak megfelelően.
Magyarázat: Érdemes egy-egy tömbben a csillagjegyeket, és az azokat határoló dátumokat felsorolni. Ezek után a megadott dátum hónapjának és napjának figyelembevételével megkeresni melyik két határ közé esik.
18.31. forráskód. Csillagjegy megadása
private void Btn_Horoszkop_Click(object sender, EventArgs e) { label1.Text = Csillagjegy(dateTimePicker1.Value);} private String Csillagjegy(DateTime dateTime) { dateTime = new DateTime(2011, dateTime.Month, dateTime.Day); DateTime[] dates = new DateTime[12] { new DateTime(2011, 01, 20), new DateTime(2011, 02, 19), new DateTime(2011, 03, 21), new DateTime(2011, 04, 20), new DateTime(2011, 05, 21), new DateTime(2011, 06, 22), new DateTime(2011, 07, 23), new DateTime(2011, 08, 23), new DateTime(2011, 09, 23), new DateTime(2011, 10, 23), new DateTime(2011, 11, 22), new DateTime(2011, 12, 22) }; String[] jegyek = new String[12]{ "Vízöntő","Halak","Kos", "Bika","Ikrek","Rák", "Oroszlán","Szűz","Mérleg", "Skorpió","Nyilas","Bak" }; int i = 0; Boolean found = false; while (i < 11 && !found) { found = ((dates[i] < dateTime) && (dateTime < dates[i + 1])); i++; } return (found) ? jegyek[i - 1] : jegyek[11]; }
18.21. feladat (Időpont – szint: 1). Írjon programot, melynek a segítségével megnövelhető a dátum. Kiválasztható legyen melyik részét növelje a dátumnak vagy időnek (év, hónap, nap, óra, perc, másodperc).
Magyarázat: Az óra, perc, másodperc megadását egy MaskedTextBox komponensben oldjuk meg "00:00:00" maszkkal. Figyeljen arra, hogy értelmezhető-e a megadott idő.
18.32. forráskód. Dátum növelése
private void BT_hozzaad_Click(object sender, EventArgs e) { DateTime ido; try { ido = DateTime.ParseExact(maskedTextBox1.Text, "HH:mm:ss", CultureInfo.InvariantCulture);} catch (FormatException) { MessageBox.Show("Nincs megadva idő!"); return; } DateTime uj_datum_es_ido = new DateTime( datum.Value.Year, datum.Value.Month, datum.Value.Day, ido.Hour, ido.Minute, ido.Second ); Int32 noveles = (int)numericUpDown1.Value; if (RB_ev.Checked) uj_datum_es_ido = uj_datum_es_ido.AddYears(noveles); else if (RB_honap.Checked) uj_datum_es_ido = uj_datum_es_ido.AddMonths(noveles); else if (RB_nap.Checked) uj_datum_es_ido = uj_datum_es_ido.AddDays(noveles); else if (RB_ora.Checked) uj_datum_es_ido = uj_datum_es_ido.AddHours(noveles); else if (RB_perc.Checked) uj_datum_es_ido = uj_datum_es_ido.AddMinutes(noveles); else if (RB_masodperc.Checked) uj_datum_es_ido = uj_datum_es_ido.AddSeconds(noveles); label3.Text = String.Format("A növelt dátum és idő: {0:yyyy MM dd, HH:mm:ss}", uj_datum_es_ido); }
18.22. feladat (Stopper – szint: 1). Írj stoppert, mely jobb egérgombbal indítja és állítja, bal egérgombbal pedig részeredményeket ad.
18.33. forráskód. Egérkattintás kezelése
private void Stopper_MouseClick(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { if (started) { label1.Text = "Jobbgomb: stopper indítása"; lb_mert.Text = String.Format("Mért idő: {0:t}", (DateTime.Now - startTime)); } else { label1.Text = "Jobbgomb: stopper leállítása"; startTime = DateTime.Now; listBox1.Items.Clear(); lb_mert.Text = String.Empty; } started = !started; } else if (e.Button == System.Windows.Forms.MouseButtons.Left) { if (started) listBox1.Items.Add((DateTime.Now - startTime).ToString("t")); } }
18.23. feladat (Három szám átlagai – szint: 1). Kérjünk be 3 egész számot. Különböző műveleteket lehessen végezni velük, melyek eredményét a művelet nevével egy ListBox-ba gyűjtse a program. A műveleteket lehessen a formon lévő menüsorból kiválasztani, illetve a ListBox területén megjelenő helyi menüből is. A műveletek: A 3 szám összege, a 3 szám számtani, mértani, harmonikus közepe. A legnagyobb szám a 3 közül.
Magyarázat: A menük és helyi menü használatánál hangoljuk össze a működést. Elég az eseménykezelőket egyszer megírni, pl. a menüpontoknál, és a helyimenü menüpontjainak eseménykezelőit irányítsuk ezekre a metódusokra. Használjuk a MenuStrip és ContextMenuStrip komponenseket. Ne felejtsük el a ListBox-nál a ContextMenuStrip tulajdonságot beállítani.
18.34. forráskód. Három szám mértani közepe
private bool JoSzamok() { return ((int.TryParse(textBoxSz1.Text, out sz1)) && (int.TryParse(textBoxSz2.Text, out sz2)) && (int.TryParse(textBoxSz3.Text, out sz3)));} private void mértaniKözépToolStripMenuItem_Click(object sender, EventArgs e) { if (JoSzamok()) { ListBoxEredmeny.Items.Add("Mértani közép: " + (Math.Pow(sz1 * sz2 * sz3, 1.0 / 3)).ToString()); } else { MessageBox.Show("3 egész számot kérek!!!", "Hiba...", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
18.24. feladat (Menük ikonokkal – szint: 2). Egészítse ki az előző feladat megoldásául szolgáló programot úgy, hogy a menüpontok előtt kis ikonok is jelenjenek meg, melyek szimbolizálják a műveletet. Ugyanezek az ikonok jelenjenek meg egy eszköztáron is, ahonnan szintén elindítható legyen minden művelet.
18.25. feladat (Véletlen számok – szint: 3). Töltsön fel egy listát 10 és 20 közé eső véletlen számokkal. Legyen 10 elemű a lista. Lehessen a listából kijelölt elemeket törölni, új elemet bevinni, amit egy megjelenő TextBoxba tudunk bevinni, és lehessen a meglévő elemek összegét és szorzatát kiszámítani. Ezeket a műveleteket menüből kell indítani. A státuszsoron jelenítsük meg folyamatosan, hogy hány elemű a lista, mekkora a legkisebb és legnagyobb eleme.
Magyarázat: A feladat megoldásához alkalmazni kell a minimum-maximum kiválasztás tételét, az összegzés tételét alapesetben, és szorzatokra is. Ebben az esetben figyeljünk oda a gyűjtőváltozó kezdőérték adására. Az új érték bevitelénél csak egész számot fogadjunk el.
18.35. forráskód. Listaelemek kezelése
private void Szelsoertek(out int max, out int min) { int i; min = max = Convert.ToInt32(listBox1.Items[0]); for (i = 1; i < listBox1.Items.Count; i++) { if (max < Convert.ToInt32(listBox1.Items[i])) max = Convert.ToInt32(listBox1.Items[i]); if (min > Convert.ToInt32(listBox1.Items[i])) min = Convert.ToInt32(listBox1.Items[i]); } } private void SetStatus() { StatusLabel1.Text = "Elemek száma: " + listBox1.Items.Count.ToString(); int max, min; Szelsoertek(out max, out min); StatusLabel2.Text = "Legnagyobb elem: " + max.ToString(); StatusLabel3.Text = "Legkisebb elem: " + min.ToString(); } private void SetDef() { int i, szam; listBox1.Items.Clear(); for (i = 0; i < 10; i++) { szam = rnd.Next(10) + 10; listBox1.Items.Add(szam.ToString()); } SetStatus(); } private void alaphelyzetToolStripMenuItem_Click(object sender, EventArgs e) { SetDef(); } private void összegToolStripMenuItem_Click(object sender, EventArgs e) { int i, s = 0; for (i = 0; i < listBox1.Items.Count; i++) { s += Convert.ToInt32(listBox1.Items[i]); } labelOsszeg.Text = "Elemek összeg: " + s.ToString(); }
18.36. forráskód. Listaelemek kezelése
private void szorzatToolStripMenuItem_Click(object sender, EventArgs e) { int i; double s = 1; for (i = 0; i < listBox1.Items.Count; i++) { s *= Convert.ToInt32(listBox1.Items[i]); } labelSzorzat.Text = "Elemek szorzata: " + s.ToString(); } private void kijelöltekTörléseToolStripMenuItem_Click(object sender, EventArgs e) { while (listBox1.SelectedItems.Count > 0) { listBox1.Items.Remove(listBox1.SelectedItems[0]); } SetStatus(); } private void újBeviteleToolStripMenuItem_Click(object sender, EventArgs e) { int sz; if (int.TryParse(textBox1.Text, out sz)) listBox1.Items.Add(textBox1.Text); SetStatus(); }
18.26. feladat (Véletlen számok mátrixban – szint: 4). Töltsön fel egy 3x3 mátrixot 10 és 20 közé eső véletlen számokkal. Végezze el menüből és helyi menüből választhatóan a következő műveleteket: transzponált, a páratlan számok összege, a főátló számainak összege, a sorokban lévő értékek és az oszlopokban lévő értékek összege. Ezeket az eredményeket jelenítse is meg a formon.
Magyarázat: A feladat megoldásánál használjuk a DataGridView komponens adta lehetőségeket. Figyeljünk arra, hogy a mátrix bejárásánál a sorokat és oszlopokat megfelelően azonosítsuk. Használjuk az összegzés tételét megfelelően. A transzponált előállítását lásd a 18.43-ben.
18.37. forráskód. Mátrix elemek generálása
private void General() { Random rnd = new Random(); int i, j, szam; dataGridAlap.Rows.Clear(); for (i = 0; i < 3; i++) { DataGridViewRow r = new DataGridViewRow(); for (j = 0; j < 3; j++) { szam = rnd.Next(10) + 10; DataGridViewCell dc = new DataGridViewTextBoxCell(); dc.Value = szam; r.Cells.Add(dc); } dataGridAlap.Rows.Add(r); } }
18.38. forráskód. Mátrix elemek kezelése
private void páratlanÖsszegToolStripMenuItem_Click(object sender, EventArgs e) { int i, j, szam, ptl = 0; for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { szam = (int)dataGridAlap.Rows[j].Cells[i].Value; if (szam % 2 == 1) ptl += szam; } } labelPtlOsszeg.Text = "Páratlan elemek összege: " + ptl.ToString(); } private void sorokÖsszegeToolStripMenuItem_Click(object sender, EventArgs e) { int i, j, szam, s; labelSorok.Text = "Sorok összege: \n"; for (i = 0; i < 3; i++) { s = 0; for (j = 0; j < 3; j++) { szam = (int)dataGridAlap.Rows[i].Cells[j].Value; s += szam; } labelSorok.Text = labelSorok.Text + (i+1).ToString() + ". sor: " + s.ToString() + "\n"; } } private void főátlóÖsszegToolStripMenuItem_Click(object sender, EventArgs e) { int i, szam, ossz = 0; for (i = 0; i < 3; i++) { szam = (int)dataGridAlap.Rows[i].Cells[i].Value; ossz += szam; } labelFoAtlOsszeg.Text = "Főátló elemeinek összege: " + ossz.ToString(); }
18.27. feladat (Műveletek – szint: 2). Írj programot, amely egy számokkal töltött listában végez műveleteket. A műveleteket menüből érhessük el, és a következők legyenek:
minimum/maximum keresés (ezt almenü segítségével old meg)
átlagszámítás
összeg
páros számok összege
Ugyancsak menüből lehessen kiválasztani, hogy kézzel adjuk meg a számokat, vagy a program generálja őket. Menüből és gomb segítségével is lehessen kilépni a programból. A számok bekérésénél végezzünk ellenőrzést, hogy valóban egész számot adjon meg a felhasználó és a megadott határokon belül legyen: 1 és 20 között lehet a darabszám, és a számok 1 és 99 között legyenek a listában.
Magyarázat: Mivel gyakran kell egy bekért szám ellenőrzését elvégezni, írjunk rá külön metódust, mely egy textbox szövegét próbálja meg átalakítani és megadható neki két határ, amik közé kell essen a szám.
18.39. forráskód. Ellenőrzés és összegzés
private Boolean Ellenoriz(TextBox tb, Int32 ah, Int32 fh, out Int32 szam) { if (Int32.TryParse(tb.Text, out szam) && (szam >= ah) && (szam <= fh)) { return true; } else { MessageBox.Show(String.Format("Számot kell megadni és {0}," +"{1} között kell lennie!", ah, fh)); tb.Text = String.Empty; tb.Focus(); return false; } } private void párosakÖsszegeToolStripMenuItem_Click(object sender, EventArgs e) { Int32 sum = 0; for (Int32 i = 0; i < listBox.Items.Count; i++) { if ((Int32)listBox.Items[i] % 2 == 0) { sum += (Int32)listBox.Items[i]; } } if (sum > 0) MessageBox.Show(String.Format("A páros számok összege: {0}" , sum)); else MessageBox.Show("Nincs páros szám!"); } private void számokátlagaToolStripMenuItem_Click(object sender, EventArgs e) { Int32 sum = 0; for (Int32 i = 0; i < listBox.Items.Count; i++) { sum += (Int32)listBox.Items[i]; } MessageBox.Show(String.Format("A számok átlaga: {0}", sum / ((double)listBox.Items.Count))); }
18.28. feladat (SplitContainer használata – szint: 1). Írjon programot, mely tartalmaz 2 színes panelt egymás mellett, és lehetőség legyen a területük arányának változtatására. Adjuk meg a jobboldali panel szélességének arányát az egészhez képest.
Magyarázat: A panelek eltolására használja a SplitContainer komponenst, míg látványosan az arány megaddható a Trackbar segítségével.
18.40. forráskód. SplitContainer használata
namespace Tobbinfo_1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void trackBar1_Scroll(object sender, EventArgs e) { splitContainer2.SplitterDistance = splitContainer2.Width * trackBar1.Value / 100; labelPos.Text = trackBar1.Value.ToString() + "%"; } private void Form1_Shown(object sender, EventArgs e) { splitContainer2.SplitterDistance = splitContainer2.Width * 10 / 100; labelPos.Text = trackBar1.Value.ToString() + "%"; } } }
18.29. feladat (TabControl használata – szint: 1). Írjon programot, mely bekér két egész számot külön külön egy TabControl egyik lapján. Majd kiszámolja a két szám számtani közepét, amit kiír egy másik lapra, aminek a címkéje legyen: eredmények. A bekéréskor ügyeljen a kivételkezelésre! A programból való kilépéskor kérdezzen rá, hogy biztos ki akar-e lépni a felhasználó, és a válasznak megfelelően járjon el.
Magyarázat: Figyeljünk oda a hibakezelésre, és a váltásra a TabPage-ek között.
18.41. forráskód. TabControl használata
private void buttonSzamol_Click(object sender, EventArgs e) { int szam1, szam2; if (textBox1.Text != String.Empty && textBox2.Text != String.Empty) { try { szam1 = Convert.ToInt32(textBox1.Text); szam2 = Convert.ToInt32(textBox2.Text); labelEredmeny.Text = ((szam1 + szam2) / 2).ToString(); tabControl1.SelectTab(1); } catch { MessageBox.Show("Adathiba!", "Hiba", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else { MessageBox.Show("Mindkét számot írd be!", " Hiba", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
18.30. feladat (Mátrixok adatai egy formon – szint: 3). Írjon programot, mely generál egy 3x3 mátrixot olyan véletlen számokból, melyek 1 és 20 közé esnek. Határozza meg a mátrix transzponáltját, a skalárszorosát és a mátrix legkisebb és legnagyobb értékét is válassza ki. Az egyes mátrixokat és a szélsőértékeket külön lapokon jelenítse meg, de csak egy formot használjon.
Magyarázat: A kezdeti állapotban a program generáljon egy kiinduló mátrixot. Figyeljen oda, hogy a véletlen számok a megadott intervallumba essenek. Megjelenítéshez lehet használni a DataGridView egy megfelelően beállított példányát.
18.42. forráskód. Kiinduló mátrix generálása
private void buttonAlap_Click(object sender, EventArgs e) { Random rnd = new Random(); int i, j, szam; dataGridAlap.Rows.Clear(); for (i = 0; i < 3; i++) { DataGridViewRow r = new DataGridViewRow(); for (j = 0; j < 3; j++) { szam = (rnd.Next() % 20) + 1; DataGridViewCell dc = new DataGridViewTextBoxCell(); dc.Value = szam; r.Cells.Add(dc); } dataGridAlap.Rows.Add(r); } }
Magyarázat: A számolás indításakor határozza meg a feladatban előírt mátrixokat és számokat.
18.43. forráskód. Transzponált számítása
private void Transzponalt() { int i, j, szam; dataGridTr.Rows.Clear(); for (i = 0; i < 3; i++) { DataGridViewRow r = new DataGridViewRow(); for (j = 0; j < 3; j++) { szam = (int)dataGridAlap.Rows[j].Cells[i].Value; DataGridViewCell dc = new DataGridViewTextBoxCell(); dc.Value = szam; r.Cells.Add(dc); } dataGridTr.Rows.Add(r); } }
18.44. forráskód. Skalárral szorzás
private void SkalarSzorzas() { Random rnd = new Random(); int i, j, szam, szorzo; szorzo = (rnd.Next() % 7) + 3; labelSkalar.Text = " A skalár a: "+szorzo.ToString(); dataGridSzor.Rows.Clear(); for (i = 0; i < 3; i++) { DataGridViewRow r = new DataGridViewRow(); for (j = 0; j < 3; j++) { szam = (int)dataGridAlap.Rows[j].Cells[i].Value * szorzo; DataGridViewCell dc = new DataGridViewTextBoxCell(); dc.Value = szam; r.Cells.Add(dc); } dataGridSzor.Rows.Add(r); } }
18.45. forráskód. Szélsőértékek
private void SzelsoErtekek() { int szam, i,j, min = 21, max = -1; for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { szam = (int)dataGridAlap.Rows[i].Cells[j].Value; if (min > szam) min = szam; if (max < szam) max = szam; } } labelMin.Text = min.ToString(); labelMax.Text = max.ToString(); }
18.31. feladat (Színek állítása dialógusablak segítségével. – szint: 1). Készítsen egy olyan programot, mely egy formon lévő label-nek a szín tulajdonságait állítja. A színbeállítást egy nyomógomb segítségével kezdeményezze. A színeket a szokásos windows beállító ablak segítségével lehessen kiválasztani. Egy további label-be jelenítsük meg a kiválaszott szín adatait is.
Magyarázat: A ColorDialog példányosítása történhet a komponens használatával, vagy a kódból közvetlenül is! Figyeljen arra, hogy a ColorDialog is, mint minden dialógus ablak, a ShowDialog() metódussal hívható, melynek visszatérési értéke a DialogResult osztály egy példányában fogadható, és utána értékelhető ki.
18.46. forráskód. ColorDialog használata
private void buttonColors_Click(object sender, EventArgs e) { ColorDialog cd = new ColorDialog(); DialogResult dr; dr = cd.ShowDialog(); if (dr == DialogResult.OK) { labelMinta.BackColor = cd.Color; labelVal.Text = cd.Color.ToString(); } }
18.32. feladat (Kép megnyitása dialógus ablak segítségével. – szint: 1). Készítsen egy olyan programot, melyben a szokásos windows Megnyitás ablak segítségével kiválaszt egy képet, és azt megnyitja egy PictureBox-ban. A kép töltse ki a form felületét, méretezésre kövesse annak mozgását. A megnyitást egy gomb segítségével kezdeményezze.
Magyarázat: Figyeljen rá, hogy a PictureBox Dock tulajdonságát hogy állítja be!
18.47. forráskód. OpenFileDialog használata
private void buttonOpen_Click(object sender, EventArgs e) { OpenFileDialog of = new OpenFileDialog(); DialogResult dr = of.ShowDialog(); if (dr == DialogResult.OK) { pictureBoxDest.SizeMode = PictureBoxSizeMode.CenterImage; pictureBoxDest.Image = new Bitmap(of.FileName); } }
18.33. feladat (Szöveges file megnyitása és mentése – szint: 2). Készítsen egy programot, mely a szokásos windows Megnyitás ablak segítségével meg tud nyitni egy szöveges file-t egy TextBox-ba. Illetve tudjuk elmenteni a tartalmát a szokásos Mentés ablak használatával.
Magyarázat: Figyeljen oda, hogy a TextBox Multiline tulajdonságát hogy állítja be. Ne feledjük, a file-ok használathához a System.IO névtérre szükség van.
18.48. forráskód. A SaveFileDialog használata
private void buttonOpen_Click(object sender, EventArgs e) { OpenFileDialog of = new OpenFileDialog(); if (of.ShowDialog() == DialogResult.OK) { FileStream fs = new FileStream(of.FileName, FileMode.Open); StreamReader rs = new StreamReader(fs); string s = rs.ReadLine(); while (s != null) { textBoxDest.Text += s; s = rs.ReadLine(); } rs.Close(); fs.Close(); } } private void buttonSave_Click(object sender, EventArgs e) { SaveFileDialog sf = new SaveFileDialog(); if (sf.ShowDialog() == DialogResult.OK) { FileStream fs = new FileStream(sf.FileName, FileMode.Create); StreamWriter wr = new StreamWriter(fs); wr.Write(textBoxDest.Text); wr.Close(); fs.Close(); } }
18.34. feladat (Dialógusok használata – szint: 3). Készítsen programot mely egy RichText komponensbe megnyit egy kiválasztott rtf file-t. Tudjuk módosítani a háttér színét, a karakterek színét, a karakterek jellemzőit. Tudjunk menteni. Az egyes lehetőségeket helyi menüből érjük el.
Magyarázat: A háttérszín beállításánál használjuk a ColorDialog komponenst. A karakterek jellemzőit a FontDialog komponens segítségével állíthatjuk be. Ennek a Font tulajdonsága tartalmazza az összes beállítást.
18.49. forráskód. Háttérszín és Font beállítása
private void háttérszínToolStripMenuItem_Click(object sender, EventArgs e) { ColorDialog cd = new ColorDialog(); if (cd.ShowDialog() == DialogResult.OK) richTextBox1.BackColor = cd.Color; } private void fontBeállításToolStripMenuItem_Click(object sender, EventArgs e) { FontDialog fd = new FontDialog(); if (fd.ShowDialog() == DialogResult.OK) richTextBox1.Font = fd.Font; }
Magyarázat: Mentésnél figyeljünk arra, hogy file művelet végzésekor erőforrást használunk. Szükség lehet a kivételkezelésre.
18.50. forráskód. Mentés és visszatöltés
private void betöltésToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog of = new OpenFileDialog(); if (of.ShowDialog() == DialogResult.OK) richTextBox1.LoadFile(of.FileName); } private void mentésToolStripMenuItem_Click(object sender, EventArgs e) { SaveFileDialog sf = new SaveFileDialog(); if (sf.ShowDialog() == DialogResult.OK) richTextBox1.SaveFile(sf.FileName); }
18.35. feladat (Üzenetablak használata – szint: 1). Írjon programot, mely véletlenszerűen kitalál egy egész számot 1 és 20 között. A felhasználó tippelje meg, hogy páros vagy páratlan lesz. A kiértékelést egy dialógus üzenettel végezze a program.
Magyarázat: Ügyeljen a véletlenszámok használatára. Az üzenetablak a MessageBox Show metódusával hívható, melynek 4 paramétere van. A megjelenítendő szöveg, a form fejlécszövege, a megjelenő gombok, és az ikon. A gombok és az ikon a rendszer felsorolt típusa MessageBoxButtons és MessageBoxIcon. Ezek közül kell választani. A Páratlan tipp kiértékelése teljesen hasonlóan mehet.
private int aSzam = 0; private bool ParosE; private Random rnd = new Random(); private void buttonGen_Click(object sender, EventArgs e) { aSzam = (rnd.Next() % 20) + 1; ParosE = ((aSzam % 2) == 0); labelSZAM.Text = "Generálás kész"; } private void buttonParos_Click(object sender, EventArgs e) { if (ParosE && aSzam != 0) MessageBox.Show("Jól tippeltél nagyon. ", "Eredmény", MessageBoxButtons.OK, MessageBoxIcon.Information); else MessageBox.Show("Rossz tipp. ", "Eredmény", MessageBoxButtons.OK, MessageBoxIcon.Warning); labelSZAM.Text = aSzam.ToString(); }
18.36. feladat (Üzenetablak kiértékelése – szint: 1). Írjon programot, mely feltesz egy eldöntendő kérdést egy üzenet ablakban, és a válasznak megfelelően, ha IGEN, akkor zöldre, ha NEM akkor pirosra színezi a form hátterét.
18.52. forráskód. Egy lehetséges megoldás.
private void buttonKerdes_Click(object sender, EventArgs e) { if (MessageBox.Show("Süt kint a nap ?", "Kérdés ablak...", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { this.BackColor = Color.Green; } else { this.BackColor = Color.Red; } }
18.37. feladat (Adatbekérés modális form segítségével. – szint: 3). Írjon programot, mely bekér két egész számot külön külön egy adatbekérő modális form segítségével. Majd kiszámolja a két szám számtani átlagát, amit kiír a főformra. A bekéréskor ügyeljen a kivételkezelésre! A programból való kilépéskor kérdezzen rá, hogy biztos ki akar-e lépni a felhasználó, és a válasznak megfelelően járjon el.
Magyarázat: Figyeljen oda, hogy az adatbekérés után publikus adatmezőbe kerüljön az adat, hogy át lehessen venni a másik formból. Ne felejtse el az adatbekérő formon a felrakott gombok DialogResult értékét beállítani. Alapértelmezése None. Az adatbekéréshez példányosítsuk a bekérő formot. A kilépésnél kezeljük a MessageBox Show metódusának a visszatérési értékét.
18.53. forráskód. Egy lehetséges megoldás.
private void buttonBe1_Click(object sender, EventArgs e) { FormBeker frm = new FormBeker(); if (frm.ShowDialog() == DialogResult.OK) { SzamEgy = frm.BekertSzam; labelElso.Text = frm.BekertSzam.ToString(); } } private void FormMain_FormClosing(object sender, FormClosingEventArgs e) { if (MessageBox.Show("Biztos ki akar lépni?", "Kérdés", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel) { e.Cancel = true; } }
18.38. feladat (Összetartozó adatok kezelése – szint: 5). Készítsen egy programot, melyben egy kiscserkész csapat tagjainak adatait tudjuk nyilvántartani. A tagokról az azonosítójukat, a nevüket, és a születési dátumukat kell letárolni. Az adatbevitel egy modális form segítségével történjen. Az adatokat táblázatos formában jelenítsük meg. Tudjunk adatot menteni és visszatölteni fileból, a szokásos windows dialógus ablakok használatával.
Magyarázat: A feladat során több mindenre kell figyeljünk. Amit át kell tekinteni, a ListView kezelése, bináris file írása és olvasása, modális form használata, és adatforgalom a formok között.
Tekintsük először az adatbeviteli formot. Itt csak arra ügyeljünk, hogy az adatmezőket publikus láthatóságra állítsuk, hogy a FormMain osztályból is el lehessen érni.
18.54. forráskód. Adatbeviteli form
// Az adatbeviteli form public partial class FormAdat : Form { public string Beazon = ""; public string Benev = ""; public DateTime Beszul; public FormAdat() { InitializeComponent(); } private void buttonOK_Click(object sender, EventArgs e) { Beazon = textBoxAzon.Text; Benev = textBoxNev.Text; Beszul = dateTimePickerSzDatum.Value; } }
Magyarázat: A FormMain osztály eseménykezelői kissé összetettebbek, mert itt végezzük el a feladatokat.
18.55. forráskód. A főform eseménykezelői, metódusai
// A főform public partial class FormMain : Form { private string azon = ""; private string nev = ""; private DateTime szul; public FormMain() { InitializeComponent(); } private void buttonZar_Click(object sender, EventArgs e) { Close(); } private void FormMain_FormClosing(object sender, FormClosingEventArgs e) { if (MessageBox.Show(" Biztos kilép?", "Kérdés", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) { e.Cancel = true; } }
18.56. forráskód. A főform eseménykezelői, metódusai
// Kiválasztott adat módosítása private void buttonMod_Click(object sender, EventArgs e) { FormAdat frm = new FormAdat(); frm.textBoxAzon.Text = listViewData.Items[listViewData.SelectedIndices[0]].Text; frm.textBoxNev.Text = listViewData.Items[listViewData.SelectedIndices[0]].SubItems[1].Text; DateTime d = new DateTime(); d = Convert.ToDateTime( listViewData.Items[listViewData.SelectedIndices[0]].SubItems[2].Text); frm.dateTimePickerSzDatum.Value = d; if (frm.ShowDialog() == DialogResult.OK) { listViewData.Items[listViewData.SelectedIndices[0]].Text = frm.Beazon; listViewData.Items[listViewData.SelectedIndices[0]].SubItems[1].Text = frm.Benev; listViewData.Items[listViewData.SelectedIndices[0]].SubItems[2].Text = frm.Beszul.ToShortDateString(); } } // Bináris file-ba mentés private void buttonSave_Click(object sender, EventArgs e) { SaveFileDialog sf = new SaveFileDialog(); if (sf.ShowDialog() == DialogResult.OK) { BinaryWriter br = new BinaryWriter(File.Open(sf.FileName, FileMode.Create)); try { int i; for (i = 0; i < listViewData.Items.Count; i++) { br.Write(listViewData.Items[i].Text); br.Write(listViewData.Items[i].SubItems[1].Text); br.Write(listViewData.Items[i].SubItems[2].Text); } br.Flush(); } catch { MessageBox.Show("Hiba a mentésben."); } finally { br.Close(); } } }
18.57. forráskód. A főform eseménykezelői, metódusai
// Visszatöltés bináris file-ból private void buttonOpen_Click(object sender, EventArgs e) { OpenFileDialog of = new OpenFileDialog(); if (of.ShowDialog() == DialogResult.OK) { string sa; listViewData.Items.Clear(); BinaryReader br = new BinaryReader(File.Open(of.FileName, FileMode.Open)); try { if (File.Exists(of.FileName)) { long len1 = br.BaseStream.Length; while (br.BaseStream.Position < len1) { azon = br.ReadString(); nev = br.ReadString(); sa = br.ReadString(); ListViewItem li = new ListViewItem(azon, 0); li.SubItems.Add(nev); li.SubItems.Add(sa); listViewData.Items.Add(li); } } } catch { } finally { br.Close(); } } } // Sor törlése private void buttonDel_Click(object sender, EventArgs e) { listViewData.Items[listViewData.SelectedIndices[0]].Remove(); }
18.39. feladat (Memória – szint: 4). Írj memória játék programot. A következő beállításokat támogassa a program:
hány szám legyen (6 vagy 9)
mennyi ideig látszódjanak (5, 10, vagy 20 mp)
hány jegyűek legyenek (1 vagy 2)
Ha 6 db számot kell kitalálni, akkor 5/10 mp, ha 9 számot, akkor pedig 10/20 mp legyen a választható. A program a beállított paramétereknek megfelelően generáljon számokat és jelenítse meg azokat egy ideig, majd kérdezze vissza őket. A számok megjelenítéséhez és visszakérdezéséhez is modális ablakokat használjunk. A visszakérdezéskor csak annyi tippje lehessen a játékosnak, mint amennyi a kitalálandó számok darabszáma.
18.58. forráskód. Játék indítása és kiértékelése
private void BT_Indulhat_Click(object sender, EventArgs e) { int db = (RB_szam6.Checked) ? 6 : 9; Frm_Szamok frm_Szamok = new Frm_Szamok( db, (CB_Egyjegyu.Checked) ? 1 : 2, RB_mp5.Checked ? 5 : RB_mp10.Checked ? 10 : 20); frm_Szamok.ShowDialog(); Frm_Memoria frm_Memoria = new Frm_Memoria(db); frm_Memoria.ShowDialog(); int joValasz = 0; foreach (int i in frm_Memoria.tippek) { if (frm_Szamok.szamok.Contains(i)) { joValasz++; } } MessageBox.Show(String.Format("A jó válaszok száma: {0}", joValasz)); }
18.59. forráskód. Számok megjelenítése
private void LabelekKirak(int db, int szamjegy) { Random veletlen = new Random(); int meretSzelesseg = (panel1.Width - 40) / 3; int meretMagassag = 200 / (db / 3); szamok = new List<int>(db); int min, max; if (szamjegy == 1) { min = 1; max = 9; } else { min = 10; max = 99; } for (int i = 0; i < db; i++) { Label ujLabel = new Label(); int x = i % 3, y = i / 3; ujLabel.Location = new Point(x * (meretSzelesseg + 10) + 10, y * (meretMagassag + 10) + 10); ujLabel.Size = new Size(meretSzelesseg, meretMagassag); ujLabel.Font = new Font(Font.FontFamily, 16); ujLabel.TextAlign = ContentAlignment.MiddleCenter; ujLabel.BackColor = Color.Red; int ujSzam; do { ujSzam = veletlen.Next(max - min + 1) + min; } while (szamok.Contains(ujSzam)); szamok.Add(ujSzam); ujLabel.Text = ujSzam.ToString(); panel1.Controls.Add(ujLabel); } }
Magyarázat: A labeleket dinamikusan rakja fel a formra, mivel nem tudni előre, hogy hány számot kell megjeleníteni.
18.60. forráskód. Tipp hozzáadása
private void BT_Hozzaad_Click(object sender, EventArgs e) { if (!listBox1.Items.Contains(TB_Szam.Text)) { int temp; if (int.TryParse(TB_Szam.Text, out temp)) { listBox1.Items.Add(TB_Szam.Text); tippek.Add(temp); } } TB_Szam.Text = String.Empty; TB_Szam.Focus(); if (maxDb == listBox1.Items.Count) { TB_Szam.Enabled = BT_Hozzaad.Enabled = false; } }
Magyarázat: Maximálisan annyi számot lehessen beírni, amennyit eredetileg kiválasztottunk megtekintésre.
18.40. feladat (Időzítés használata – szint: 2). Írj programot, mely a form közepén mutatja a futó időt másodperc pontosan.
Magyarázat: Az időzítés legegyszerűbben a Timer komponens segítségével oldhatjuk meg. Használjuk a Tick eseményt. Figyeljünk rá, hogy az időzítőt engedélyezni kell. Az alapértelmezett értéke false.
18.61. forráskód. Időzítés használata
namespace timer_1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); timer1.Enabled = true; } private void timer1_Tick(object sender, EventArgs e) { labelIdo.Text = DateTime.Now.ToLongTimeString(); } } }
18.41. feladat (Form színe időzítve – szint: 1). Írj programot, mely 1 másodpercenként megváltoztatja a form háttérszínét.
Magyarázat: Egy lehetséges megoldás a színek ciklikus változtatására a maradékos osztás használata.
18.62. forráskód. Időzítés használata
namespace idozit_2 { public partial class Form1 : Form { int ind = 0; Color[] szinek = new Color[5] { Color.White, Color.Blue, Color.Beige, Color.Black, Color.DarkSeaGreen }; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { timer1.Interval = 1000; timer1.Enabled = true; } private void timer1_Tick(object sender, EventArgs e) { this.BackColor = szinek[ind % 5]; ind++; } } }
18.42. feladat (Új formok születése és halála – szint: 2). Írj programot, 2 másodpercenként megjelenít egy 20 másodpercig látható formot. Ezt 1 percig csinálja. Minden új form más más feliratot tartalmazzon.
Magyarázat: Több timerre is szükségünk lesz mind a főformon, ami méri a 2 másodperceket, mind a létrejövő formokon, ami a 20 másodpercekért felel. A főformon az 1 percet is figyelni kell.
18.63. forráskód. A vezérlés a főformon
DateTime kezdido = new DateTime(); int x, y; TimeSpan eltelt; private void button1_Click(object sender, EventArgs e) { timer1.Enabled = true; timer1.Interval = 2000; kezdido = DateTime.Now; } private void timer1_Tick(object sender, EventArgs e) { eltelt = DateTime.Now - kezdido; if (eltelt.Seconds > 60) this.Close(); Form2 frm = new Form2(); frm.label1.Text = DateTime.Now.ToLongTimeString(); frm.x = x % 800; frm.y = y % 600; frm.Show(); x += 100; y += 100; } }
18.64. forráskód. A megjelenő formok
private void Form2_Load(object sender, EventArgs e) { timer1.Enabled = true; } private void timer1_Tick(object sender, EventArgs e) { this.Close(); } private void Form2_Shown(object sender, EventArgs e) { this.Top = y; this.Left = x; }
18.43. feladat (Keringő form – szint: 2). Írjon programot, mely egy formot mozgat a képernyőn körbe, 1 másodperces időközzel lépkedve. A mozgás 2 percig menjen az indítástól. Használj felsorolás típust a mozgás irányának tárolásához.
18.65. forráskód. Felsorolás típus létrehozása
namespace Korbefut { enum Iranyok { Jobbra, Le, Balra, Fel } }
Magyarázat: Az éppen aktuális irány tárolásához hozzunk létre egy felsorolás típust (Jobbra,Le,Balra,Fel).
18.66. forráskód. Feladat megoldása
private void timer_Tick(object sender, EventArgs e) { label.Text = String.Format("{0} mp", stopper.Elapsed.TotalSeconds); if (stopper.Elapsed.TotalSeconds >= 120) { timer.Enabled = false; stopper.Stop(); Left = (Screen.PrimaryScreen.Bounds.Width - Width) / 2; Top = (Screen.PrimaryScreen.Bounds.Height - Height) / 2; return; } switch (irany) { case Iranyok.Jobbra: if (Left + lepes < Screen.PrimaryScreen.Bounds.Width - Width) Left += lepes; else { Left = Screen.PrimaryScreen.Bounds.Width - Width; irany = Iranyok.Le; } break; case Iranyok.Le: if (Top + lepes <Screen.PrimaryScreen.Bounds.Height - Height) Top += lepes; else { Top = Screen.PrimaryScreen.Bounds.Height - Height; irany = Iranyok.Balra; } break; case Iranyok.Balra: if (Left - lepes > 0) Left -= lepes; else { Left = 0; irany = Iranyok.Fel; } break; case Iranyok.Fel: if (Top - lepes > 0) Top -= lepes; else { Top = 0; irany = Iranyok.Jobbra; } break; } }
Magyarázat: Az aktuális állapot alapján mindig tudhatjuk, hogy merre kell mozgatni a form-ot, és melyik lesz a következő irány, ha elértük a képernyő megfelelő szélét. Figyeljünk arra, hogy mivel fix nagyságú lépéseket teszünk, nem biztos, hogy pontosan a képernyő széléhez ér az ablak majd a mozgás végén, ezért igazítsuk be (ne lógjon ki és ne is maradjon rés).
18.44. feladat (TiliToli játék – szint: 3). Írjon pogramot, mely megvalósítja a TiliToli játékot. Közben valósítsa meg az időmérést is.
Magyarázat: A játék lemezkéit egy-egy dinamikusan létrehozott label komponens valósítsa meg. Az újonnan létrehozott labeleket tároljuk el egy kétdimenziós tömbben, és mindegyikéhez ugyanazt az eseménykezelőt rendeljük. A közös metódus a sender objektumban utazó label pozíciójából „találja ki”, hogy ő melyik a rácsban. Ha a lyuk melletti lemezre kattintunk, akkor az cseréljen helyet a lyukkal. Készítsünk függvényt, ami a labelek feliratából és helyes sorrendjéből meghatározza, hogy jó-e az elrendezés.
18.67. forráskód. A kérdéses metódusok
void ujLabel_Click(object sender, EventArgs e) { if (!timer.Enabled) { timer.Enabled = true; } Label kep = (sender as Label); int i = kep.Left / meret; int j = kep.Top / meret; if (i > 0 && labelek[i - 1, j] == null) { Csere(i, j, i - 1, j); } else if (i < N - 1 && labelek[i + 1, j] == null) { Csere(i, j, i + 1, j); } else if (j > 0 && labelek[i, j - 1] == null) { Csere(i, j, i, j - 1); } else if (j < N - 1 && labelek[i, j + 1] == null) { Csere(i, j, i, j + 1); } if (MindegyikJoHelyen()) { timer.Enabled = false; MessageBox.Show("Gratulálok, kész! {0}",Lb_Ido.Text ); } } private bool MindegyikJoHelyen() { bool jo = true; for (int db = 0; (db < N * N) && jo; db++) { int i = db % N; int j = db / N; if (labelek[i, j] != null) { jo = Convert.ToInt32(labelek[i, j].Text) == (db + 1); } } return jo; }