C# 11. Gyakorlat: Menükezelés, több ablakos alkalmazások 1. feladat: Az ELTE PPK (Pedagógiai és Pszichológiai kar) Gazdaság- és Környezetpszichológia Tanszéke tavaly a „vendéglátó-ipari egység fantázianév” kategória győzteseként a képen látható kocsmát jelölte meg. (Idei hasonló adatot nem találtam.) (https://www.facebook.com/photo.php?f bid=513577955420949&set=a.36007753 7437659.1073741828.359692027476210 &type=1&theater) A rövid híradásból az nem derült ki, hogy kaptak-e érte valamilyen jutalmat, mi azonban ajándékozzuk meg őket egy C# programmal.
A Fájl menü a „szokásos”: meg lehet nyitni a kocsma választékát és árait tartalmazó adatfájlt. Az Itallap menüpont is és a Mentés is csak ezután válik elérhetővé. A Súgó menüpont hatására megnyíló ablakocska segít a továbbiakban: A fájl betöltése után azonnal (ill. bármikor később is az Itallap menüpontra kattintva) megjelenik az árlista. Ebből lehet rendelni. Mivel kis kocsmáról van szó, ezért egy italfajtából egyszerre legföljebb csak 999 adagot lehet kérni.
1
A Rendel gombra bal egérgombbal kattintva tudjuk leadni a rendelést. Ha semmi sincs kijelölve, akkor adjunk hibaüzenetet, ha valamelyik bejelölt italhoz tartozó adagot rosszul töltöttük ki, akkor változzon pirosra a hozzá tartozó szövegdoboz háttérszíne, de akárhány hiba is van, csak egyetlen üzenetdoboz jelezze, hogy hibásak az adagok. Helyesen kitöltött adatok esetén vegye fel a rendelést, és szüntessük meg a kijelöléseket, ürítsük ki a szövegdobozokat. Ha jobb egérgombbal kattintunk a gombra, akkor jelenjen meg egy úgynevezett context menü: A Számlát kér menüpont hatása: A számla egy richTextBox-ban jelenik meg. A Fizet menüpont hatására kiürül a számla, a kifizetett értékeket pedig „könyvelik” – egyelőre még csak a memóriában, a Mentés menüpont hatására kerül majd fájlba. Az eredményfájl szerkezete ital fajtánként: az ital neve; összesen eladott adag; bevétel. A Galéria menüpont hatására egy képgaléria nyílik ki, ahol lapozgatni lehet a környékről készült képek között:
A névjegy most csak egy üzenet:
2
2. feladat: Egy becsületkasszás automatából édességeket és üdítőket lehet vásárolni, egyszerre többfélét is, de egyszerre mindegyikből csak egyet. (Több ilyen automata is létezik, itt olvashat az egyikről: http://www.eletforma.hu/szines_hirek/becsuletkasszas_italautomatak_budapesten.) Az automatában kapható árucikkek nevét, vonalkódját és egységárát az arucikkek.txt fájl tartalmazza. A fájldialógus ablak az indító felület File\Megnyitás menüpontjának hatására nyílik meg. Helyes választás esetén jelenjen meg az alábbi felület (a felirat és a gombok is váljanak láthatóvá), ezen a jelölőnégyzetek bekapcsolásával jelezhetjük, hogy mit szeretnénk vásárolni. Hibás fájlkezelés esetén kapjunk hibaüzenetet. Ha sikerült a beolvasás, akkor az eddig inaktív Mentés és Könyvelés menüpont is váljon aktívvá.
„Fizetni” a Fizetés nyomógomb hatására megnyíló ablakban tudunk. A gombra kattintva ebben a másik ablakban megjelenik a fizetendő összeg értéke. Be kell gépelnünk, hogy mennyit fizetünk (ha kedve van elszöszmötölni vele, akkor kicserélheti úgy, hogy különböző gombok jelöljék a bedobott címleteket, és addig dobáljon, amíg el nem éri a szükséges értéket). Ha az Enter gombot is lenyomtuk, akkor szépen egymás alá igazítva címletenkénti bontásban megjelenik a visszajáró összeg, feltéve, hogy eleget fizettünk, illetve egy hibaüzenet, ha kevés a befizetett érték. (Igazítás: Courier New vagy Consolas betűtípus, PadRight() metódus.) Az eredeti vásárlás ablak csak akkor legyen ismét aktív, ha a Fizetés ablakot lezártuk. Ha rákattintunk a Fizetés gombra, és a Fizetés ablakban megjelenik a fizetendő összeg, akkor tekintsük eladottnak a kiválasztott árucikkeket, függetlenül attól, hogy ténylegesen kifizetik-e az árát, vagy sem. (Az Arucikk osztály Elad() metódusában növekszik a darabszám.) Lezáráskor nem ellenőrizzük, hogy tényleg fizettek-e – épp ezért becsületkasszás az automata . A vásárlás felületen az Új vásárlás gombra kattintva kikapcsolhatjuk az összes kijelölést. A Mentés menüpont hatására mentsük el egy adatfájlba az aktuális adatokat. Adatszerkezet: név;vonalkód;ár;eladott_darabszám A Könyvelés menüpont hatására jelenjenek meg egy újabb formon az árucikkek adatai (célszerű richTextBox-ba rakni, mert az automatikusan scrollozható). A richTextBoxba
3
(hasonlóan a korábbi visszajárót tartalmazó szövegmezőhöz) Courier New vagy Consolas betűtípus kerül, a szöveg pedig a PadLeft(), PadRight() metódusokkal formázható. A Súgó menüpont hatására a gyengébbek kedvéért jelenjen meg egy súgó; a Névjegy menüpont hatására pedig jelenjen meg a névjegy-ablak:
2. b/ feladat: Bár kicsit(?) erőltetett, de azért, hogy ennek során sok mindent átgondoljon, próbálja meg átalakítani az előző feladatot úgy, hogy most nem közvetlenül a Vásárlás form-ról nyílik meg a Fizetés felület, hanem mindkettőt egy közös menüből lehet elérni:
A File menüpont hatása ugyanaz, mint az a/ feladatban. A Vásárlás menüpont hatására nyílik meg a vásárlói felület, a Fizetés hatására a fizetési, a Könyvelés hatására pedig a könyvelés.
Most odja meg Új vásárlás gomb nélkül, úgy, hogy a Fizetés felület lezárásakor automatikusan kikapcsolódhat a Vásárlás felület összes kijelölése.
4
3. feladat: Készítsünk menüvezérelt programot, amely egy hengernek metódusok hívásával kiszámítja a felszínét és a térfogatát! Minden menüpont egy új ablak megnyitását eredményezi. A Számítások menüpont csak akkor legyen elérhető, ha az Adatok megadása már kiválasztásra került. A feladat megoldása során arról kell gondoskodnunk, hogy az egyik ablakban megadott adatok (Adatok megadása menü) átjussanak a Felszín vagy Térfogat számoló ablakokba. Gondoskodjon az adatbevitel ellenőrzéséről! Készítsünk felbukkanó (Popup vagy Contextus) menüt az eredmények betűtípusának és színének megadására a megfelelő dialógusablakok segítségével! A program menürendszere: Henger Névjegy Adatok megadása Számítások Felszín Térfogat -------------Kilépés
Néhány futási kép:
5
4. feladat Készítsen alkalmazást egy Fitness klub szolgáltatásaiból származó bevételek kiszámítására, tárolására. Az alkalmazás Menüpontjai a következő ábrákon látható. Minden menüpont egy új ablak megjelenését idézi elő.
A program indulásakor az alábbi ablak jelenik meg.
Hozzon létre egy Szamla osztályt, amelyben a szolgáltatást igénybevevő személy nevét, a kiválasztott edzéstípust, a kiválasztott szintet, az alkalmak számát tartjuk nyilván és kiszámoljuk a fizetendő összeget. Minden egyes számlát egy egyedi sorszám is jellemez. Készítsen egy SzamlaKezeles osztályt is, amely a számlákat tartalmazó lista fájlba írását, illetve a fájlból listába történő beolvasást végzi. A Kínálat főmenü választásakor a Sportolás menüt választva egy új ablak jelenik meg, amelynek formája a feladat végén lévő képen látható: A Fájl menü Mentés menüpontját választva egy SaveFileDialog ablakban megadva a célkönyvtárat és a fájl nevét, a számlák listát mentjük egy szöveges fájlba. 6
A Fájl menü Számlák listája menüpontja egy új ablakban lista dobozban mutatja meg a korábban mentett számlákat. A Fájl menü Kilép menüpontja az ablak és egyben a program bezárására szolgál. A Névjegy menü egy modális ablakban megmutatja a program szerzőjének nevét és a program verziószámát. Az alábbi ábrán a Kínálat/Sportol menü kiválasztásakor megjelenő futási kép látható, A Számláz gomb megnyomására létrejön egy új számla objektum, kiszámoljuk a kiválasztott adatok alapján a fizetendő összeget, és a számla objektumot hozzáadjuk a számlák listájához. A Töröl gomb hatására minden szövegmező üres lesz és a radiogombok jelöletlenné válnak.
7
5. feladat Írja meg az „Itt a piros, hol a piros” játékot.
A felületen három doboz (lehet Button is, Label is) ugrál véletlenszerűen. (Figyeljen rá, hogy ne kerüljenek egymás tetejére.) Ha rákattintunk valamelyikre, akkor megáll a mozgás, és mindháromnak láthatóvá válik a színe. Ha duplán kattintunk a felületre, akkor ismét elindul a játék. A játékhoz írjon súgót is, és egy eredmény ablakban lehessen látni a találatok számát (akkor van találat, ha a pirosra – vagy bármelyik, előre rögzített színű – dobozra kattintunk).
A menü akkor is jelenjen meg, ha jobb egérgombbal kattintunk a felületre. Mivel ez egy annyira komplikált játék , ezért még azt is próbálja megoldani, hogy az F1 billentyű hatására is megjelenjen a súgó.
8
6. feladat Szimuláljon egy fotóversenyt. (Az igazi megoldás az lenne, ha interneten keresztül lehetne szavazni, de ilyesmit majd csak később tanul, az alapokat viszont most is elsajátíthatja.) A verseny jeligés, a versenyzők „neve” a hozzájuk tartozó képfájl neve. Az induló résztvevők adatait – azaz a versenyen résztvevő képek névsorát a „versenyzok.txt” fájl tartalmazza. (Mivel fájlnevekről van szó, ezért nincs bennük ékezet, de jó lenne, ha a képek alatt lévő rádiógombok feliratán már helyesen szerepelnének ezeket a nevek.
A képek és a feliratok az alkalmazás indulásakor töltődnek be. Egy-egy kicsi képre kattintva, az alkalmazás fölött (azt eltakarva) megjelenik a kiválasztott kép nagyított változata. Ha erre kattintunk, akkor eltűnik, és ismét az eredeti felületet látjuk. A Szavazás gombra kattintva lehet szavazni, feltéve, ha kijelöltük valamelyik képet. Ha nem, hibaüzenetet kapunk. A gomb megnyomása után megszűnik a kiválasztás is. A Tudnivaló menüpontra kattintva kis eligazítást kapunk, Az Eredmény menüpontra kattintva pedig szavazatszám szerint rendezve láthatjuk a verseny pillanatnyi állását. Akár a Mentés gombra, akár a Mentés menüpontra kattintva elmenthetjük az eredményt egy kiválasztott adatfájlba. Az adatfájl szerkezete: név, pontosvessző, szavazatszám legyen.
9
Megjegyzések: 1. A kiadott mappa tartalmazza a képeket is és az adatfájlt is, de természetesen más adatok alapján is készülhet a verseny. A képen látható külalak elnyeréséhez ezeket a méreteket alkalmaztam: A kezdő form központi paneljének mérete: 430250 pixel. Egy-egy kis kép mérete: 8055, egy-egy nagy képé: 800550 pixel. 2. Ha azt szeretnénk, hogy az alkalmazás önálló exe-ként is fusson, akkor a felhasznált fájlokat nem a bin/Debug mappába kell raknunk, hanem be kell építenünk a projekt Resources tulajdonságába. Ezt így tehetjük meg: A Solution Explorer-ben jobb egérgomb a projekt nevén – Properties – és a projekt tulajdonságai közül válassza ki a Resources tulajdonságot.
Itt kiválaszthatja, hogy mit akar hozzáadni (jelenleg a kép (Images)) van beállítva, de mást is lehet. (Kevésbé elegáns módon „gyalog” is megoldhatjuk: egyenként importálva egy fiktív PictureBox Image tulajdonságának beállításakor.) Ekkor egy-egy képre ilyen módon tud hivatkozni: kepDoboz.Image = (Image)Resources.ResourceManager.GetObject(KepNev);
Az igazi az lenne, ha a versenyzok.txt fájlt is ide raknánk be, és innen hivatkoznánk rá, de ennek megoldására egyelőre nem jöttem rá, az interneten meg túl bonyolult megoldásokat javasolnak. Az, aki elsőként küldi be az egyszerű megoldást, kap egy szelet csokit.
10
7. feladat: Találja el a betűket! Készítsen egy űrlapot, amelyen egy listadobozban véletlenszerűen jelennek meg betűk, az időzítőben beállított időintervallum mértékének megfelelő gyorsasággal. Ha a játékos a billentyűzeten leüti a megjelenő betűt, akkor az törlődik a listából. Az időzítő pedig egy kicsit gyorsabban ketyeg. A játék addig tart, amíg 7 olyan betű lesz a listában, amelyet a játékos nem talált el. Ekkor a Játék vége felirat jelenik meg. Az űrlapon a listapanel alatt egy statusStrip (és egy Timer) vezérlőelemet helyezünk el, amely folyamatosan mutatja a játék állapotát. Hány betűt találtunk el, hányat nem, és összesen hány betűt adott a gép. Az eredményt százalékosan is kiírjuk (hány százalékot értünk el). A StatusStrip vezérlőn helyezzünk el egy ProgressBar vezérlőt is, amely azt mutatja, hogy milyen nehézségi fokot értünk el a játékban. A nehézségi fok az időzítő időintervallumának csökkentésével növelhető. Az alkalmazás űrlapja:
A statusStrip Item tulajdonságában adhatjuk meg, hogy milyen információk jelenjenek meg rajta:
Az Form tulajdonságai közül a KeyPreview tulajdonság értékét állítsuk True értékre, hogy fel tudjuk dolgozni a játékos által leütött billentyűket. A Form1_KeyDown
11
eseménykezelőjében tudjuk feldolgozni, hogy milyen billentyűt ütött le a játékos. (e.KeyCode). Készítsünk egy statisztika osztályt, amely mindig frissíti a játék állapotát jelző információkat. Egy futási kép:
A listapanel MultiColumn tulajdonságának a True értéket beállítva érjük el, hogy a lista elemeit egymás mellé írja. A listapanel SelectionMode tulajdonsága legyen: None.
12
8. feladat: Ha van kedve, ideje, valósítson meg néhány szövegszerkesztési funkciót: Az új lap ikon hatására megjelenik egy új felület, amelyen már induláskor egy richTextBox van, ebbe lehet majd írni a szöveget. A megoldáshoz használja az MDIParent form-ot, ebben sok funkció elő van készítve. Valósítson meg közülük néhányat: pl. copy-cut-paste – ezeket magyaríthatja is, ha ráér, saját formázás menüpont, amely alapján a betűszínt, betűtípust állíthatja be, stb. (Ez utóbbiakhoz érdemes a color-, ill. a font-Dialog vezérlőelemeket használni. Néhány funkció:
Eredeti szöveg:
Néhány módosítás után:
13
Segítség a megoldásokhoz:
Főmenü – MenuStrip vezérlőelem Tulajdonságok: ShortcutKey “forrógomb” a menüpont billentyűzetről való eléréséhez Text a menüpont szövege, elérési kulcs ( access key ) megadásához a megfelelő betű elé & jelet helyezünk
Névjegy ablak (Ha nem saját szerkesztésű): About Box
Az About Box –ban található képet, címke feliratokat szabadon megváltoztathatjuk a címkék Text tulajdonsága segítségével. Másik megoldás, hogy a Project menüből kiválasztjuk a Projektnév Properties almenüpontot, ahol a Projektnév a saját projektünk neve. A megjelenő ablakban rákattintunk az Assembly Information gombra, s a megjelenő ablakba írjuk bele a szükséges információkat. Ezek az információk fognak megjelenni futáskor a Névjegy ablakban.
14
Környezeti menü – ContextMenuStrip Amelyik objektumhoz tartozik, annak a ContextMenuStrip tulajdonságát állítjuk rá.
Egy vezérlő Visible tulajdonsága - true – ha látható az elem, ugyanez a hatás a Show() metódussal - false – ha elrejtjük az elemet, ugyanez a hatás a Hide() metódussal Egy vezérlő Enabled tulajdonsága - true – ha elérhető az elem - false – ha nem elérhető, nem használható, de látható az elem
Új form hozzáadása a projekthez: Project/Add Windows Form… menüpontban, pl. FormN néven, majd kialakítjuk a form képét a megfelelő vezérlőelemekkel
Egy form megjelenítése egy másikból, pl. egy menüpontra klikkelve: - létrehozás FormN formváltozónév = new FormN ( ); - megjelenítés formváltozónév.Show(); formváltozónév.ShowDialog(); // ez modális ablak lesz // a modális ablakokra jellemző, hogy amíg nem fejezzük be vele a párbeszédet, más ablakokba átlépni nem tudunk.
Előfordulhat, hogy láthatósági problémák miatt valamelyik osztályt is publikusra kell deklarálni.
15