DIALOG BOXES, DATA BINDING, STYLES, TRIGGERS WPF 1 Készítsük el a hallgatók és az oktatók nyilvántartását megvalósító modult. Mindkettő hasonló módon működik, ezért az alábbi leírásban csak a hallgatói modul működését részletezem. A nyilvántartás lehetővé teszi hallgatói adatokat tartalmazó fájl beolvasását az alkalmazásba, új hallgató felvitelét, hallgató módosítását vagy törlését, valamint az alkalmazásban éppen aktuális adatok visszamentését a fájlba. A Visual Studio Solution az alábbi szerkezetű: EgyetemiElet A belépési ponttal rendelkező, futtatható WPF alkalmazás Egyetem A korábban létrehozott típusaink osztálykönyvtára ResourceDictionaries Az implicit és az explicit stílusok erőforrás állományai Adatok A hallgatói és az oktatói adatokat tartalmazó szöveges fájlok RÉSZFELADATOK A HALLGATÓ OSZTÁLY FIGYELŐI Ahhoz, hogy az Egyetem.Hallgató típusú adatrétegbeli objektumok és a felület vezérlői közötti adatkötések létrejöjjenek, az osztálynak meg kell valósítania az INotifyPropertyChanged interfészt. Módosítsuk a saját osztályunkat az EVP.P06.EgyszeruEgyetem.Hallgato osztályt véve alapul. Tételezzük fel, hogy a hallgató nevét nem lehet módosítani, ezért a Név tulajdonságra nem fogunk figyelőt állítani. FELÜLETI RÉTEG (MAINWINDOW MARKUP ÉS CODE-BEHIND) Az EVP.P06.P08.CollectionBindingNotify projektet véve alapul, készítsük el a felületi és az adatréteget. A tanulás érdekében, a felületi réteg kialakítását igyekezzünk a markup-ra (.xaml fájlra) korlátozni, és mellőzzük a Designer, illetve a ToolBox nyújtotta kényelmi szolgáltatásokat, helyette kódoljunk. Hagyatkozzunk a ResourceDictionaries projekt stílusaira, vagy ami még jobb, fejlesszük azokat tovább a saját ízlésünknek megfelelően. Például a képen látható ablak és Hallgatók füle a következő vezérlő-fával rendelkezik: Window TabControl TabItem...Hallgatók DockPanel StackPanel ListBox StackPanel StackPanel TabItem...Oktatók Az Egyetem.Hallgató típusú objektumok megjelenítésére hozzunk létre egy DataTemplate-et az ablak erőforrásai között. A DataTemplate tartalmazzon vezérlőket (pl. TextBlock-okat) a Név, az Energia és a Kedv tulajdonságok megjelenítésére. A többi tulajdonság most nem fontos, illetve a Hozzáállás NKE HHK Had- és biztonságtechnikai mérnök 1
kezelésére egy későbbi részfeladatban visszatérünk, mert egészen új módon fogjuk megoldani. Például a képen látható DataTemplate egy 4 soros és 2 oszlopos Grid panelt használ, melynek cellái TextBlockokkal vannak feltöltve: DataTemplate Border Grid Grid.s Grid.ColumnDefinitions ColumnDefinition ColumnDefinition TextBlock...Row:0 Col:0 TextBlock...Row:0 Col:1 TextBlock...Row:1 Col:0 TextBlock...Row:1 Col:1 TextBlock...Row:2 Col:0 TextBlock...Row:2 Col:1 TextBlock...Row:3 Col:0 TextBlock...Row:3 Col:1 A logikai és a vizuális fákról régi, de jó összefoglalás olvasható itt www.codeguru.com/csharp/ ADATRÉTEG (MAINWINDOW MARKUP ÉS CODE-BEHIND) A felületi réteggel ellentétben az adatréteg kódolását lehetőleg a code-behind-ban (.xaml.cs fájlban) végezzük. Az adatréteg két listából fog állni, egy a hallgatók, egy pedig az oktatók számára. A két lista üresen inicializálódik, és a Fájlból olvasás vagy az Új hallgató gombok eseménykezelőiben lehet majd feltölteni. Gondoskodjunk arról, hogy az adatrétegbeli listák forrásként szolgáljanak a felületi rétegbeli listák megjelenítését lehetővé tevő vezérlők számára (ObservableCollection<>). FÁJLBÓL OLVASÁS A Fájlból olvas gombra kattintás eseménykezelőjének megírásához az EVP.P05.DialogBoxes projektet vehetjük alapul. A gombra kattintás eseménykezelője nyisson meg egy OpenFileDialog típusú dialógus dobozt. A dialógus dobozt konfiguráljuk úgy, hogy a.txt fájlokat külön listázhassuk, hiszen a hallgatói adatokat is.txt fájlban tároljuk. Miután kiválasztottuk a hallgatói adatokat tartalmazó fájlt, a fájlban található adatokkal töltsük fel az adatrétegbeli hallgatói listát. Az Egyetem.Hallgató.FájlbólListátElőállít() statikus metódus egy módosított változatát használhatjuk fel a művelethez. A metódus lista paraméterét módosítsuk, mivel a hallgatókat tartalmazó listánk ObservableCollection<> típusú. A hallgatói adatokat szekvenciális fájlban tároljuk, hasonló módon, ahogy azt a konzolos alkalmazásnál is tettük. A különbség annyi, hogy a fájlban az egy hallgatóhoz tartozó információt szóköz helyett most vesszővel választjuk el. (Ez maga után vonja, hogy az Egyetem.Polgár.FájlbólOlvas() metódusban módosítani szükséges a Split() függvény paraméterét.) NKE HHK Had- és biztonságtechnikai mérnök 2
Fájlból olvasás FÁJLBA MENTÉS A megoldás sokban hasonlít a Fájlból olvasás művelethez. A különbség annyi, hogy az Egyetem.Hallgató osztálynak még nincs fájlba író metódusa. Készítsük el ezt a statikus metódust, mely az OpenFileDialog dialógus dobozban kiválasztott fájlba kiírja az adatrétegbeli listát. Arra figyeljünk, hogy az egy hallgatóra vonatkozó adatokat vesszővel elválasztva, egyetlen sorba írjuk. HALLGATÓK HOZZÁÁLLÁSA A konzolos alkalmazásban a hozzáállásokat kiszámítottuk és eltároltuk az osztály egy tulajdonságában. A WPF alkalmazásban viszont rábízzuk ezt a felületre ValueConverter-ek használatával. Iktassuk ki tehát a hozzáállásokra vonatkozó tulajdonságokat és számításokat az Egyetem.Polgár, az Egyetem.Hallgató és az Egyetem.Oktató osztályokban, viszont hagyjuk meg az enum-okban definiált hozzáállás fajtákat. Az EVP.P06.P03.ValueConverter projektben megtaláljuk, hogyan alkalmaztunk ValueConverter-t az oktatói hozzáállás számítására. Ennek analógiájára implementáljunk egy MultiValueConverter-t a hallgatói hozzáállás számítására, és bővítsük a hallgatói DataTemplate-et úgy, hogy a konverterrel számított hozzáállást megjelenítse. Hallgatók listája NKE HHK Had- és biztonságtechnikai mérnök 3
DATA TRIGGER Amikor a hallgatók listáján az egeret mozgatjuk, akkor az éppen aktuális elemen a hozzáállás szövege legyen kövér és pirossal kiemelve. Ezt egy Data Trigger-rel tudjuk megvalósítani, hasonlóan, ahogy az EVP.P06.Styles projektben tettük. Mivel a lista elemek megjelenítését kiemeltük egy DataTemplatebe, ezért nem a Styles.Triggers-ek között, hanem a DataTemplate.Triggers-ek között helyezzük el a triggert. A feladat megoldásánál segítséget jelenthet a www.stackoverflow.com/questions/206495/ kérdésre adott második legjobb (12 szavazatos) válasz. Data Trigger HALLGATÓ LÉTREHOZÁSA Ehhez a részfeladathoz az EVP.P05.CustomDialogBox projektet vehetjük alapul, ahol saját dialógus doboz létrehozására láttunk példát. Implementáljunk egy dialógus dobozt, melyet mind új hallgató létrehozásakor, mind létező hallgató módosításakor fel tudunk használni. A létrehozás, a módosítás és a törlés eseménykezelőket az EVP.P06.P08.CollectionBindingNotify projekt alapján implementálhatjuk. Az Új hallgató gombra kattintás eseménykezelője nyissa meg a dialógus dobozt alapértelmezett értékekkel, majd a Rendben gombra kattintás esetén hozzunk létre egy új Egyetem.Hallgató típusú objektumot, melyet adjuk hozzá az adatrétegbeli hallgató listához. Saját DialogBox - létrehozás NKE HHK Had- és biztonságtechnikai mérnök 4
HALLGATÓ MÓDOSÍTÁSA Amikor a baloldali listából kijelölünk egy hallgatót, és a Hallgató módosítása gombra kattintunk, akkor nyíljon meg a dialógus doboz úgy, hogy az aktuálisan kijelölt hallgatói adatokkal legyen feltöltve. A hallgató nevét ne engedjük módosítani, azaz legyen az IsEnabled attribútum hamis a Név tulajdonságon. A hallgatói adatokon végzett módosításokat az adatrétegbeli hallgatói lista megfelelő elemén is szinkronizáljuk. Saját DialogBox - módosítás HALLGATÓ TÖRLÉSE Amikor a baloldali listából kijelölünk egy hallgatót, és a Hallgató törlése gombra kattintunk, akkor töröljük az adott hallgatói objektumot az adatrétegbeli hallgatókat tartalmazó listából. A VS SOLUTION JELLEMZŐI EgyetemiElet A belépési ponttal rendelkező, futtatható alkalmazás Hozzunk létre egy új WPF Application típusú Project-et, a Solution neve legyen WPF.EgyetemiElet, míg a projekt neve legyen EgyetemiElet. Hozzunk létre a projekt alatt két Package-et, egyet a konverterek számára, egyet a dialógus dobozok számára. Miután létrehoztuk majd az Egyetem és a ResourceDictionaries projekteket, adjuk azokat hozzá az Egyetem projekt referenciáihoz (References menü, Solution fül). Egyetem A korábban létrehozott típusaink osztálykönyvtára A Solution-ben WPF Application-ként hozzuk létre az Egyetem projektet, majd a projekt Properties ablakában az Application fülön állítsuk át az Output Type-ot Class Library-re. Töröljük ki a generált App.config, App.xaml, App.xaml.cs, MainWindow.xaml, MainWindow.xaml.cs fájlokat, és másoljuk át a saját.cs kiterjesztésű fájljainkat. A fájlok Properties ablakában a Build Action legyen Compile. ResourceDictionaries Az implicit és explicit stílusok erőforrás állományai A Solution-ben WPF Application-ként hozzuk létre a ResourceDictionaries projektet, majd a projekt Properties ablakában az Application fülön állítsuk át az Output Type-ot Class Library-re. Töröljük ki a generált App.config, App.xaml, App.xaml.cs, MainWindow.xaml, MainWindow.xaml.cs fájlokat, és adjunk hozzá egy BaseControlStyles nevű Package-et. A csomaghoz adjunk hozzá Resource Dictionary (WPF) típusú fájlokat, melyek a stílusokat fogják tartalmazni. A fájlok Properties ablakában a Build Action legyen Resource. Végül a projekthez adjunk hozzá egy Resource Dictionary (WPF) fájlt, neve ResourceLibrary.xaml, a Build Action szintén Resource. A fájl tartalmazni fogja a csomagban található erőforrásokat, így az EgyetemiElet projekt App.xaml fájljába csupán ezt a fájlt fogjuk erőforrásként feltüntetni. NKE HHK Had- és biztonságtechnikai mérnök 5
SOLUTION SZERKEZET WPF.EgyetemiElet...SOLUTION Egyetem...WPF PROJECT (CLASS LIBRARY) Egyetem.Polgar... ABSTRACT CLASS Egyetem.Hallgato...CLASS Egyetem.Oktato... CLASS Egyetem.Interfaces...NAMESPACE Egyetem.Interfaces.IHallgato...INTERFACE Egyetem.Interfaces.IOkato...INTERFACE Egyetem.Exceptions...NAMESPACE Egyetem.Exceptions.IntervallumonKivulException...CLASS EgyetemiElet...WPF PROJECT (WINDOWS APPLICATION) Converters... PACKAGE DialogBoxes... PACKAGE ResourceDictionaries...WPF PROJECT (CLASS LIBRARY) BaseControlStyles... PACKAGE Border...RESOURCE DICTIONARY (RESOURCE)...RESOURCE DICTIONARY (RESOURCE)... RESOURCE DICTIONARY (RESOURCE) ResourceLibrary...RESOURCE DICTIONARY (RESOURCE) NKE HHK Had- és biztonságtechnikai mérnök 6