Windows Phone fejlesztés lépésről lépésre

Készült a Microsoft Magyarország megbízásából

Árvai Zoltán – Fár Attila Gergő – Farkas Bálint – Fülöp Dávid – Komjáthy Szabolcs – Turóczy Attila – Velvárt András

Windows Phone fejlesztés lépésről lépésre

Jedlik Oktatási Stúdió Budapest, 2012

A szerzők a könyv írása során törekedtek arra, hogy a leírt tartalom a lehető legpontosabb és naprakész legyen. Ennek ellenére előfordulhatnak hibák, vagy bizonyos információk elavulttá válhattak. A könyvben leírt programkódokat mindenki saját felelősségére alkalmazhatja. Javasoljuk, hogy ezeket ne éles környezetben próbálják ki. A felhasználásból eredő esetleges károkért sem a szerzők, sem a kiadó nem vonható felelősségre. A forráskódok elérhetők a https://devportal.hu/wp7/konyv oldalon keresztül. Az oldalakon előforduló márka- valamint kereskedelmi védjegyek bejegyzőjük tulajdonában állnak.

A könyv vagy annak bármely része, valamint a benne szereplő példák a szerzőkkel kötött megállapodás nélkül nem használhatók fel üzleti célú oktatási tevékenység során! A könyv tudásanyaga államilag finanszírozott közép- és felsőoktatásban, illetve szakmai közösségek oktatásában bármely célra felhasználható.
© 2011 Microsoft. Minden jog fenntartva. A könyv papír alapon megvásárolható a Jedlik Oktatási Stúdió honlapján keresztül: http://joskiado.hu/termek/windows_phone_fejlesztes_lepesrol_lepesre.html

Szerkesztette: Novák István Szakmai lektor: Novák István Anyanyelvi lektor: Dr. Bonhardtné Hoffmann Ildikó Borító: Varga Tamás

Kiadó: Jedlik Oktatási Stúdió Kft. 1215 Budapest, Ív u. 8-12. Internet: http://www.jos.hu E-mail: jos@jos.hu Felelős kiadó: a Jedlik Oktatási Stúdió Kft. ügyvezetője

Nyomta: LAGrade Kft. Felelős vezető: Szutter Lénárd ISBN: 978-615-5012-13-6 Raktári szám: JO-0338

6

Tartalomjegyzék

Tartalomjegyzék
Előszó ............................................................................................................... 13 1. Bevezetés a „Windows Phone” platform-ba .................................................. 15
A Windows Phone Platform ............................................................................................... 15 Windows Phone hardver követelmények........................................................................... 16 A Windows Phone platform képességei ............................................................................ 16 Alkalmazás fejlesztés Silverlight alapokon ....................................................................... 19 Ismerkedés a XAML-lel ..................................................................................................... 19 XAML alapú felhasználói felületek..................................................................................... 21 Hello Windows Phone......................................................................................................... 22 Összefoglalás...................................................................................................................... 26

2. Felhasználói élmény tervezése Windows Phone-on ...................................... 27
A Windows Phone jelenség ............................................................................................... 27 Ikonografikus és infografikus felületek ............................................................................. 28 A METRO Dizájn Nyelv ....................................................................................................... 29 Ismerős megjelenés .......................................................................................................... 29 Tiszta és pehelykönnyű..................................................................................................... 29 Digitális eredetiség ............................................................................................................ 30 Gyönyörű tipográfia ........................................................................................................... 30 Állandóan mozgásban....................................................................................................... 30 A tartalom az elsődleges ................................................................................................... 30 Design vezérelt fejlesztés................................................................................................... 31 Tartalom és információs architektúra ................................................................................ 32 Használhatóság és ergonómia .......................................................................................... 32 Esztétika és vizuális élmény.............................................................................................. 32 Csináld magad! ................................................................................................................... 33 A dizájn szórakoztató! ....................................................................................................... 33 Innováció tervezés közben ................................................................................................ 33 A probléma megértése ...................................................................................................... 33 Magasabb termékminőség ................................................................................................ 33 Tervezés Sketchflow-val ................................................................................................... 34 Élmény vagy alkalmazás .................................................................................................... 35 Ismerjük meg a felhasználóinkat! ...................................................................................... 35 Releváns tartalom ............................................................................................................. 36 Személyes alkalmazások .................................................................................................. 36 Hasznos, jól használható, kívánatos ................................................................................. 36 Gyakorlati Dizájn ................................................................................................................. 36

7

................... 36 Windows Phone 7 specifikus komponensek tervezése ................................................................................................................................................................................................................ 81 Témák használata ............................................................................... Az alkalmazás életciklusa .. 74 Az alkalmazás állapotainak létrehozása VisualState-ek segítségével ............................................................................................................................................................................................................................................................. 103 Különbségek................... 101 Pivot és Panorama .............. 100 Az alkalmazás kiegészítése navigációs vezérlőkkel ............................................................................................................. Haladó alkalmazásfejlesztés Windows Phone-on . 113 8 ................................................................................................................................................................................................................... 97 Oldalak ......... 42 3............................... 44 Parancsvezérlők ............................... 109 Összefoglalás ..................................................................................................................................................................................................... 65 Erőforrások .................. 49 Szövegmegjelenítési vezérlők ......................................... 58 Listavezérlők ..................................................................................................................... 99 BackStack ..................................................................................................................................................................................................................................................................... 97 Adatátvitel az oldalak között ................................................................................................................................. 93 Navigáció ............................................................................................................................................................................. 37 Vezérlők használata ............ 65 Több vezérlő kötése egyazon forráshoz .......................................................................................................... 41 Összefoglalás ....... 84 4............................................................................................................................................................................. 62 Adatkötés ........ 111 5....................................................................................................................................................................................................................................................................................... 105 Telepítés ............................................................................. 43 Alapvető WP7 vezérlők ............................................................................................................................ 85 A Bing Maps vezérlő használata ............................................................................................................................................ Alkalmazásfejlesztés Windows Phone-on ......................................................................................................................Mozgás és animáció ..................................................................... 39 Érintőképernyős alkalmazások tervezése ............................................. 99 Navigációs metódusok............................................ 85 Térképek kezelése .............................................................. 90 Egyéb szolgáltatások ............ 105 Fontosabb vezérlők ................ 72 A vezérlők kinézetének testreszabása vezérlősablonokkal ......................................................................................................... 106 Példaprogram ...................................................................................................................................................... 89 Rétegek alkalmazása ........................................... 86 Pushpinek............................................................................. 78 Animációk hozzáadása ......................... 55 Szövegbeviteli vezérlők ............................................................ 85 Feliratkozás a szolgáltatásra .......................... 104 Silverlight Toolkit for Windows Phone7 .......................................................... 83 Összefoglalás ...................... 68 Adatkötés UI-elemek között .......................................................................................................... 70 Az adatok megjelenésének testreszabása adatsablonokkal ..................................................................................................

.................................................................................................................... 144 WebBrowserTask.................................. 125 Zenelejátszás integrálása saját alkalmazásokba ........................................................................... További telefonos funkciók használata..................................................................................................................................................................................................................... 150 Contacts................................................... 125 Elméleti áttekintés .................................................................................................................... 183 9 ............... 176 A gyorsulásmérő használata ...................................................... 114 A multitasking megvalósítása WP 7..... 180 Az érzékelők együttes használata a Motion API segítségével ......................................... 119 Folyamatok a háttérben ............................. 132 Adatok letöltése a háttérben.................................................................................... 176 A giroszkóp használata ..................................... 145 SearchTask .................... 117 Az alkalmazás állapotának mentése és helyreállítása ........................................................................................................................ 113 A feladatütemezés elméletben .......................................................... 163 Alapvető érintési események .................................................................................................................................................. 151 Appointments ............................................................................................................................................................................................................................................... 133 Összefoglalás................................................................................................................................................................................................................................................................................................... 126 Figyelmeztetések és riasztások kezelése........................................ 142 SmsComposeTask ........................................ 144 MediaPlayerLauncher ...................................................................................................................................5 platformon.......................... 153 Összefoglalás................................................................................................................ 115 Állapotok kezelése ................................................................................................................................................................................................................................................................. 137 A példaalkalmazás létrehozása............................................................................................................... 143 EmailComposeTask ........................................................................................................... 117 Életciklus-események kezelése ............................................................................ 149 PhotoChooserTask ......................................................................... 142 PhoneCallTask.......................................... 135 6................ 169 Helymeghatározás ............................................................................................................................................................................... 146 Chooserek .............................. Alapvető telefonos funkciók használata ................................................................................................................................................. 179 Az iránytű használata ............ 173 Helyzetmeghatározás ..................................................................................................................................................................... 149 Adatok megosztása alkalmazások között ................................ 163 Multitouch manipulációk ..................... 163 Az érintőképernyő kezelése ............................................................................................................... 161 7................. 148 CameraCaptureTask ........ 152 Kamera használata taszk nélkül ..................... 147 SavePhoneNumberTask ................................................................................................................... 138 Launcherek.......................................................................... 147 PhoneNumberChooserTask ............................................................................... 166 A nyers érintési adatok kezelése ............................................................................Tartalomjegyzék Multitasking .................................................................................................................

.... 231 Várakozási sorok (queue-k) .................................................................................................................................................................................................................................. 217 A kommunikáció módjai ........................................... 202 Linq To SQL ...................................................................................................................... 246 Méret ................................................................. 212 Összefoglalás ................................................................................................................................................. 246 A lapkák tulajdonságai .. 203 Mapping .................................................................................................... 211 Az adatbázis biztonsága .......................................................................................................................................................................................Összefoglalás ................................................................................. 218 Webszolgáltatás egy mintaalkalmazásban ....... 185 8........................................................................................................................................... 230 Fájlok (blob-ok) ........................................ 200 Lokális adatbázisok használata Windows Phone 7-en ......... 246 Kiszögezés és elrendezés ....................................................................................................... 206 Adatok felvitele − INSERT .......................................................................................................................................................................................................................................................................................................... Adatkezelés .............................. 247 Statikus és dinamikus lapkák ........................................... 239 Felhasználó-hitelesítés szerveroldalról ... 202 DataContext ..................................... 210 Adatok lekérdezése − SELECT ........................................................................................................ 194 Isolated Storage gyakorlat ............ 203 Adatbázis létrehozása ..................................................................................................... 215 9............................................................................................................................................................. 236 Árazás ............................................................................................................................................. Lapkák és értesítések ......... 247 A lapkák felépítése ........................................................................... 196 Önálló feladatok .. 204 Adatbázis létrehozása II............................................................................................................. 187 Isolated Storage ........................ 234 Táblák (table-k) ........................ 243 10........................................................................................................................................................................................................................ Kommunikáció szerverrel................. 245 Néhány példa a lapkák és értesítések használatára ............................ 217 Webszolgáltatások használata ................................................................................................................................................................................................................................................................................................................ 226 Adattárolás Windows Azure-ban ........ 240 Összefoglalás ............ 188 IsolatedStorageFileStream ................................................................................................................................................. 187 Application Settings .... 210 Adatok módosítása − UPDATE .......... ........ 212 Adatbázis kezelés gyakorlat .................................................................................. 224 Adatelérés az OData protokollon keresztül ............................................................................................................................................................................................................................................................................................................................................................... 219 Webes tartalom letöltése ............................................................ 200 IsolatedStorage – Tool ............................................................................ 247 10 ....................................... 218 A webszolgáltatások működése.................................................................................................................................................................. 211 Adatok törlése − DELETE ..............................................................................

.......................................................................... 249 Másodlagos lapka létrehozása .............................................................. 254 Lapkák frissítése ShellTileSchedule segítségével .... 291 Silverlight és XNA együtt a gyakorlatban............................................................................................................ 271 Grafikus programozási és XNA alapok ................................ 281 Bemenetek kezelése ..................................................... 260 A Push Notification szolgáltatás............................... 249 Lapka frissítése ....................... 277 Sprite-ok ..................................................................... 291 Összefoglalás .......................................................................................................................... 258 Időzítés beállítása egy másodlagos lapkára ................................................................................................................... 305 Screenshot készítés ..................................................... 262 Lapkák frissítése Push Notification-ök segítségével .................................................................................................................................................................................................Tartalomjegyzék Másodlagos lapkák .................................. 310 Windows Phone Marketplace Test Kit ................................................................................................................................... 301 Készüléken történő hibakeresés és regisztráció ....................................................................................................................................................... 268 Push Notification-önök és a Windows Azure ............................................................................ 283 Ütközések detektálása ......................................................... 253 Másodlagos lapka törlése ................................ 258 Időzítés beállítása az elsődleges lapkára .................................................................................................................................................................................... Marketplace .................................................................................................................................................................................... 272 A kép kialakítása ...... 311 Ikonok ............................................................................................................................................................................................... 304 Publikálás ........................................... 261 A Push Notification szolgáltatás működése .......... 272 A játékciklus .............................................. 299 12............ 249 A ShellTile API ... 301 Alkalmazások telepítése ....................................................................................................................................................................................................... 254 Lapkák frissítése Background Agent-ek segítségével ....................................... 285 Animációk ............. Játékok a Mango világában ..................................................... 303 ChevronWP7 ....................................................................................................................................................................................................... 267 Raw üzenetek fogadása a Push Notification szolgáltatáson keresztül............................................................................................................................................................................. 260 A felugró értesítések ..... 313 11 ............................................................................................................................................................................ 271 Windows Phone – a motorháztető alatt ............................. 277 Egy XNA program felépítése ........................ 286 XNA és Silverlight integráció .............. 269 Összefoglalás............................................. 249 Lapkák létrehozása és frissítése alkalmazásunkból ............................................................................................................................................... 270 11............................................................................................................................................................................................... 301 APPHUB ..... 260 Időzítés törlése............................................... 248 Deep Linking ...................................................................................................................................................................................................... 263 Értesítések megjelenítése Push Notification-ök segítségével ..................................................................................................................................................

........................................................................................ 320 Lassú betöltődés kezelése ........................................................................................................................................................................... 336 A folyamat jelzése . megoldása.............................................................................................................................. 339 Windows Phone Performance Analysis .................................... 334 Szubjektív teljesítmény .............................................. Compositor és Input szálak ............................... 331 Beépített animációk és a GPU ................ 328 Redraw Regions .................................................................................................................................................................................................................................................................................... 314 Trial Mode ...................................................................... 317 13.................................................. 343 12 ................Marketplace Task .................... 334 Listák ........................................................................................................................... 333 Általános tippek................................................................. 339 Összefoglalás ........................................................................................................................................................................................................... csillagok…................. 326 Akadozó animációk okai........ 335 Tilt effektus ................................................................................................................................................................................................. 316 Összefoglalás ...................................................................................................... 329 Használjuk a GPU-t! ............................................ 323 Splash Screen ..................... 319 A tipikus teljesítmény-problémákról ..................................................................................................................................... 326 Frame Rate Counters ..................................................... 337 Memória-optimalizálás ... 338 A memória foglalás kijelzése ................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................ 324 Háttérszálak alkalmazása ....................................................... 324 Inicializációs teendők elhalasztása .................... 337 Köztes animációk ......................... 332 Hosszú válaszidő kezelése ....................................................................................................................................................................................................................................... 324 Előre elvégzett munka ................................................................................................. 337 Amikor a lassabb gyorsabb(-nak tűnik) ....................................................... 323 Az elrendezés (layout) költségeinek csökkentése .................................. 320 Csillagok.................................. Teljesítmény .................................................. 325 Kis összefoglalás ......................................................................... 332 UI..................................... 319 A CPU és a GPU feladata ... 330 Cache vizualizáció ........................................................................................................................... 339 Optimalizálás ....................

.

és ezek piaci sikeréből akár meg is élni. az még egy kisebb diplomatatáska méretével egyezett meg. A könyv és a hozzátartozó programozási példák a weben is elérhetők a Devportal. és 6. fejezetek). Ugyanígy az okostelefonok felhasználói között is többen akadnak. Olyan szakemberek írták. Turóczy Attila (8. akik maguk is gépeket építenek. Fár Attila Gergő (5. 2011. amelyeken internetet is elérő alkalmazásokat tudunk futtatni. Szinte hihetetlen mértékű változáson estek azóta át a mobil készülékek! Ma leginkább az „okostelefon” megjelölést használjuk azoknak a tenyérben elférő − szinte kizárólag érintőképernyős − mini csodáknak a megnevezésére. és 12. Olyan eszközök.Előszó Amikor első hordozható telefonomat 18 évvel ezelőtt megkaptam. valamint Velvárt András (13. Az autók szerelmesei között vannak olyanok. nekem kellett előkeresni a számokat a noteszomból és bepötyögni azokat egy-egy telefonhívás során. és egyúttal betekintést is adnak annak működésébe és használatába. több korábbi kezdeményezéshez hasonlóan a magyarországi Windows Phone szakmai közösség aktív munkájával jött létre. fejezetek). és 10. Ebben a könyvben azokat az ismereteiket is átadják.hu oldalon. fejezetek). fejezetek). Ez a könyv az alkalmazásfejlesztőknek készült. Komjáthy Szabolcs (4. hogy értenek a platform használatához és programozásához. akik szeretik gépjárművüket maguk bütykölni. akik saját alkalmazásokat szeretnének készíteni. amelyek számítógépek. és 11. amelyek segítenek a Windows Phone fejlesztésbe frissen bekapcsolódó érdeklődőknek megismerni a platform legfontosabb alapelemeit. Egyetlen dolgot lehetett vele csinálni: telefonálni. amelyben személyes tapasztalataikon. fejezetek). hogy ismereteiket megosszák a fejlesztőközösséggel. és a telefonálás lehetősége csupán egyike tucatnyi képességeiknek. Farkas Bálint (9. Árvai Zoltán (1. fejezet) mindannyian rengeteg energiát fordítottak arra. akik korábban már megmutatták. Még csak telefonkönyve sem volt. Olyan magyar nyelvű könyvet hoztak létre. és 7. Fülöp Dávid (3. december 13 . és 2. Novák István Budapest. fejezetek). a platformhoz kapcsolódó élményeiken keresztül mutatják be a Windows Phone alkalmazásfejlesztés alapvető eszközeit és fogásait. A repülőgépmodellek megszállottjai között vannak olyanok.

.

új lehetőségeket. mit szeretünk csinálni és kivel. Sajnos az idő előrehaladtával egyre nehezebb sikertörténeteket írni. ezzel lehetőséget biztosítva a készülék gyártói számára saját termékpaletták kialakítására. mikor hol kellene lennünk. a fogyasztói piacnak azonban ezek az elvek és ez a termék nem tudott megfelelni. Az elmúlt években számos mesébe illő sikertörténetet hallhattunk olyan cégekről. de nagyon pontos specifikációt írt elő a telefon hardveres képességeit illetően. digitális identitásunk egyfajta kiterjesztéseként gondolunk rájuk. Az a telefon lehet Windows Phone. és maximálisan igyekeznek minket kiszolgálni. akik a semmiből. és újabb lehetőségeket kínál. 1-2 év alatt meghatározó szereplőkké nőtték ki magukat. A Windows Mobile termékcsalád hosszú utat járt be – még ha ez az út igencsak rögös is volt. A Microsoft valahol a kettő közötti utat választotta. új igényekhez igazítva tervezték.ezt a tényt felismerve szemmel láthatólag nem erőltette tovább ezt a vonalat. Az okostelefonok új piaca nemcsak a felhasználók számára jelentenek izgalmas. a Flickr és még számtalan online és folyamatos jelenlétet igénylő szolgáltatás világában ezek az eszközök robbanásszerű fejlődésen mentek át és hatalmas kereslet mutatkozik irántuk. Habár saját eszközt nem dobott a piacra. Nem csoda hát. Bevezetés a „Windows Phone” platform-ba Az utóbbi évek egyik legjelentősebb technológiai robbanásának lehettünk tanúi az okostelefonok. A telefonok tudják. gyakorlatilag a nulláról indulva. hogy bizonyos kategória alatt nem támogatnak telefonokat. Így nem csoda. kik vagyunk. az alkalmazást hány különböző eszközre és hardver konfigurációra kell elkészíteni. A Google platformján (Android) a fejlesztők számára komoly kihívást jelent az alkalmazások felkészítése a fragmentációra. amely az előírt hardver követelményeket maradéktalanul kielégíti. életünk. bármikor elérhetővé válik. a konkurrens termékekkel nem volt képes felvenni a versenyt. amely évről évre csak nő.1. és alapjaiban új operációs rendszerrel. Sokszor társként. Évente okostelefonok milliói találnak gazdára! Ezek az eszközök napról napra egyre inkább hétköznapjaink részévé válnak. a Windows Phone és saját alkalmazásboltja (Marketplace) megjelenésével új piacot nyit a vállalkozó szellemű fejlesztők számára. illetve a könyv írásának pillanatáig nem sokat foglalkozott. hogy ez vajon mekkora fragmentációt jelenthet a készülékek piacán. bármi. Az új igényeknek. Ez a mobil operációs rendszer azonban elsősorban üzleti használatra készült. A Microsoft . hogy az asztali Windows-t vihetjük a zsebünkben. A Windows Phone különlegessége. Ezt a terméket a megváltozott. A gyakorlott fejlesztők ezeket a sorokat olvasva biztosan felhördülnek és elgondolkodnak. az eddigi mobil operációs rendszerektől eltérő dizájnnal és szellemiséggel rendelkezik. Az Apple a fragmentáció kiküszöbölésére rendkívül egyszerű stratégiát alkalmaz: a készülékeket ő maga gyártja. hogy újabb sikertörténetek születhessenek. hogy az okostelefonok megjelenésével egyfajta fejlesztői „aranyláz” tört ki. A Microsoft egyike volt az elsőknek az okostelefonok piacán. 15 . a Windows Phone-nal jelent meg a piacon. csupán mobil operációs rendszert fejleszt. hanem a fejlesztőcégek számára is. A világot helyezik kezünkbe. A Windows Phone Platform A Windows Phone megjelenésében merőben újszerű. hogy a Microsoft készüléket nem. hogy a Twitter. hol vagyunk. de a Windows Phone újabb ilyen lehetőséget jelent! A Microsoft. kik a barátaink. sokszor kényszerülnek olyan döntéseket hozni. A Google ezzel a kérdéssel nem nagyon foglalkozik. a Facebook. azzal a gondolattal. illetve az okoskészülékek piacán.

1-ben ez a viselkedés nem módosítható. Integráció a felhővel 3. Operatív memória tekintetében legalább 256 MB memóriával kell rendelkeznie a készüléknek. A készüléknek hálózati kommunikáció tekintetében mobil adathálózatok kezelését. Kezdő oldal gomb (Home): A Start képenyőre navigál bárhonnan. ún. illetve XNA. Marketplace portál szolgáltatások 4. ezt a futtatókörnyezet szigorúan ellenőrzi. Saját termékek fejlesztése során két platform közül választhatunk: Silverlight. sandboxban („homokozó”) futnak. döntésének és egyéb pozícióinak követésére gyorsulásmérőt kell beépíteni. valamint Wi-Fi-t kell támogatnia. Műholdas navigáció tekintetében Assisted-GPS támogatás szükséges. Bevezetés a „Windows Phone” platform-ba Windows Phone hardver követelmények A Windows Phone készülékeknek számos hardveres előírásnak kell megfelelniük:  Fizikai gombok: A Windows Phone készülékeken kötelezően jelentkező hardveres gombok. Iránytű Giroszkóp (jóval pontosabb pozíció/állapot meghatározásra képes. Kereső gomb: Minden esetben a beépített Bing keresőt hozza fel. 7. Az alkalmazások ennek köszönhetően nem férhetnek hozzá kontrollálatlanul tetszőleges erőforráshoz. elsősorban biztonsági okok miatt. Futtatókörnyezet 2.) Adatok tárolásra minimum 8GB-os flash tárolóegységgel kell rendelkeznie a készüléknek. bármely alkalmazásból.     Kijelző:    A kijelzőnek legalább 800 x 480-as felbontással kell rendelkeznie. mint a gyorsulásmérő) Hátsó kamera Előlapi kamera A Windows Phone által támogatott egyéb opcionális hardverek listája:     A Windows Phone platform képességei A Windows Phone platform alapvetően négy részből tevődik össze: 1. Hálózati jellemzők:   Memória:     Navigáció:  Mozgásérzékelés: A telefon mozgásának. amelyek szorosan kapcsolódnak az operációs rendszer és a navigációs mechanizmus működéséhez. Vissza gomb (Back): Az alkalmazáson belüli navigációt. illetve futó taszkok közötti váltást szolgálja. A kijelzőnek támogatnia kell a kapacitív technológiát és minimum 4 pontos érintést meg kell tudnia különböztetni. (A gyártók döntő többsége 512MB-ot tesz a készülékeibe.1. 16 . Fejlesztőeszközök Futtatókörnyezet A Windows Phone alkalmazások izoláltan.

illetve komoly háromdimenziós modellekre épülő játékokat is írhatunk. médiaközpontú alkalmazásokat fejleszthetünk. Az XNA API számos játékfejlesztésben felmerülő gyakori problémára (textúra és modell betöltés. és mint ilyen. az akkumulátor üzemideje és egyéb erőforrásai nem engedik meg. Míg a BCL. A Windows Phone-ok támogatják az ún.NET platformon a jól ismert és leggyakrabban használt alapkönyvtárak jelentős részét tartalmazza. limitált erőforrással. mintha a . 1-1 ábra: A futtatókörnyezet felépítése Integráció a felhővel A Windows Phone alapvetően egy kliens oldali eszköz. cellainformációk. XNA segítségével menedzselt kódú kétdimenziós sprite alapú. Az 1-1 ábrán a futtatókörnyezet felépítését láthatjuk. hogy párhuzamosan alkalmazások tucatjai kommunikáljanak különböző szolgáltatásokkal és egyéb komponensekkel. ha valamilyen új információ áll rendelkezésre az alkalmazás és a felhasználó számára. Ezek a felhőben futó szolgáltatások üzeneteket küldenek a telefonok felé. operációs rendszerszintű képességeihez (kapcsolatok. csupán kisebb módosításokat kell végrehajtanunk. Ennek megfelelően menedzselt API-k biztosítják a telefon különböző szenzoraihoz. fény és árnyékhatások. A felhőben azonban folyamatosan futó szolgáltatások érhetők el. számítási kapacitással és tudáshalmazzal rendelkezik. Ennek oka az ún. Ágyazhatunk XNA tartalmat Silverlightos felületekbe és viszont. hogy a két technológia között az átjárhatóság biztosított. transzformációk. egy mobil eszközről beszélünk. amely a .A Windows Phone Platform Silverlight felhasználásával látványos. XNA-val a fejlesztés gyors és produktív. illetve az XNA ismerős koncepciókat hozott át az asztali Windows-os PC-k világából. A Silverlightnak köszönhetően csupán a kreativitásunk szabhat határt a felhasználói élménynek. Base Class Library (BCL). addig számos új elem is megjelent. illetve GPS adatok segítségével biztosítják a pontos helymeghatározást. vagy éppen külön értesítésként is.) kínál kompakt megoldást. felhasználói felületeknek. így a fejlesztők valóban a játék logikájára koncentrálhatnak. gyűjtemények vagy éppen a Linq. Windows Phone-nal ismerkedő fejlesztők számára a fejlesztési élmény olyan.1-es Mango operációs rendszer különlegessége. Ezek az értesítések megjelenhetnek az alkalmazás saját lapkáin. mint például szálkezelés. életciklus menedzsment) a hozzáférést. melyek komponensei jól integrálódnak a Windows Phone Metro stílusú látványvilágával. értesítéseket (push notifications). stb. Windows-ra és Windows Phonera is játékot. XNA felhasználásával fejleszthetünk Xbox-ra. A 7. Ennek köszönhetően a már korábban elsajátított értékes tudás hordozható a két platform között. a Silverlight.NET keretrendszeren dolgoznának. hogy azok a telefon tudását és képességeit kiterjeszthessék. Ezek WiFi.  Értesítések: A mai mobil eszközök kapacitása. hiszen egy új platformról. Térképszolgáltatások: A felhőben pozícionálási és térképszolgáltatások is elérhetők. 17  . email küldés.

com címen található portálon végezhető el. hogy az alkalmazásunk stabil. a http://create.msnd. Regisztráció fejlesztők számára A telefonra történő fejlesztést megelőzi a fejlesztői programba történő jelentkezés. egy tanúsítványt kap. statisztikákhoz juthatunk alkalmazásainkat illetően. üzeneteket küldhetünk nekik. az alábbi címről: http://www. Xbox Live szolgáltatások: A Windows Phone képes a felhőben futó Xbox Live szolgáltatásokhoz is kapcsolódni.  A Marketplace portálszolgáltatásai A Windows Phone Marketplace egy központi portál. így nyomon követhetjük barátainkat. Cserébe a publikációs lehetőségen túl számos szolgáltatást kapunk a portálon. A dokumentum a következő címen érhető el: http://msdn. ahol az ár és a régiók kiválasztása után az alkalmazás széles közönség számára válik elérhetővé. hubokon keresztül. A fejlesztőeszközök a Windows Phone fejlesztők számára ingyenesen elérhetők. és segítségükkel rendkívül gazdag és értékes információhalmazt biztosítani. nem szolgál rossz célt. amely a telefon legtöbb képességét képes emulálni.com/download/en/details. ahol a különböző tartalmak és alkalmazások közül válogathatnak. hogy a telefon egy kliens. amely szolgáltatások ezreihez képes csatlakozni. csupán erősen ajánlott. amely során a Microsoft egy szigorú tesztsorozat futtatásának segítségével meggyőződik arról. és ennek eredményeképpen saját alkalmazásokat tudunk rá telepíteni a Visual Studio 2010 segítségével. Microsoft Expression Blend for Windows Phone: A Windows Phone felhasználói felületek fejlesztésével és építésével foglalkozó dizájnerek és fejlesztők első számú eszköze. A felhasználók számára ez hatalmas piactér. feltöltésüket követően. Szerencsére elmondhatjuk. Bevezetés a „Windows Phone” platform-ba  Közösségi hálózatok: A Windows Phone nagyon fontos részét jelentik a közösségi hálózatok és az integrált élmény biztosítása az ún. ingyenes Visual Studio 2010 változat.92). Fejlesztőeszközök A Windows Phone-ra fejleszteni készülők számára fontos kérdés az indulás költségvonzata. A fejlesztőeszközök is erről a portálról tölthetők le közvetlenül. Az induláshoz csupán a Windows Phone SDK 7.1-es változatot kell letölteni. de teljes értékű változata. A Marketplace-en keresztül történik a számlázás és a frissítések kezelése is. amely egy Live ID segítségével az ún.aspx.aspx?displaylang=en&id=27570 Az SDK a következő fontosabb komponenseket tartalmazza:  Visual Studio 2010 Express for Windows Phone: Kizárólag Windows Phone projektek kezelésére alkalmas. egy hitelesítési folyamaton mennek keresztül.0 termék kizárólag Windows Phone projektek kezelésére alkalmas. ahol a fejlesztői vezérlőpulton értékes információkhoz. Ezek a szabályok az Application Certification Requirements for Windows Phone című dokumentumban kerültek rögzítésre.microsoft. Természetesen egy Windowst futtató PC-re szükség lesz.com/enus/library/hh184843(v=VS. A Microsoft Expression Blend 4. amellyel üzleti célra is fejleszthetünk alkalmazásokat. A regisztrációt és a hitelesítést követően a fejlesztői készülékek zárolását feloldhatjuk. Az éves fejlesztői díj 99 dollár.microsoft. összehasonlíthatjuk elért eredményeiket a miénkkel. bár ez utóbbi nem kötelező. Soha ne felejtsük el. Miután az alkamazásunk sikeresen átment a teszteken. Alkalmazások közzététele Az alkalmazások.   18 . továbbá egy Windows Phone készülék sem árt. és amelyen keresztül értékesíthetik azokat. App Hub-on. továbbá kielégíti az alkalmazások által követendő szabályokat. hogy a fejlesztési infrastruktúra költsége gyakorlatilag nulla. vagy akár otthoni Xboxunkat is vezérelhetjük telefonunkról.1. Windows Phone Emulator: Fejlesztési időben használható Windows-on futó emulátor. ahova a fejlesztők elkészült alkalmazásaikat tölthetik fel. ennek segítségével feltölthetjük a Windows Phone alkalmazás boltba.

majd abba egy DataGridet helyezhetünk el. Ultimate) a fejlesztőeszközök beépülnek a telepített változatba. A XAML (eXtensible Application Markup Language) egy kiterjeszthető alkalmazásleíró nyelv. akkor abból futásidőben egy Button példány fog elkészülni. esetleg a tartalmát. így nem felhasználói felület specifikus.és a vezérlőmodell. Annak érdekében. A technológia és a koncepció igazi bebetonozását a Windows 8 Metro stílusú alkalmazások XAML alapú fejlesztésének lehetősége jelenti. A Windows Phone fő alkalmazásfejlesztési platformja a 7. a státuszt pedig minden sorban jelölje egy százalékos érték. A gondolat nagyon egyszerű volt. mint egy cella lehetséges elemét.0 keretrendszer megjelenésekor. melyet reprezenáljunk egy ProgressBarral. a Windows Forms-nak a segítségével fejlesztették ki. Az ilyen típusú kötöttségek nagyon szűk korlátok közé szorították a termék készítőinek kreativitását. illetve terjeszti ki. melynek segítségével egészen különleges webes felületek építhetők! A Microsoft az új felhasználói felület leírására az ún. hogy a Windows Forms ListView vezérlője nem támogatja a ProgressBart. Míg az előbbi egyszerű értékek beállítása esetén elegendőnek bizonyulhat. A Button egyéb tulajdonságait. Gondoljunk csak a HTML-re. izgalmas és jól használható felhasználói felületek helyezkedtek el. attribútum. A technológia hatékony. mint például a szélességét vagy magasságát. Premium. hogy az évek elteltével a Silverlight egyre inkább próbált megszabadulni a böngészőtől és önálló életre kelni. hogy olyan alkalmazást fejlesztünk. Ismerkedés a XAML-lel Az új modell mellé egy másik fontos koncepció is párosult. A folyamatokat egy táblázat sorai reprezentálják. és a webre is célszerű lenne elkészíteni egy WPF-hez hasonló technológiát. A felhasználói felületek leírásának egyik és egyben talán legtermészetesebb módja a leíró nyelvek (Markup Language) használata. komplexebb értékadásoknál az utóbbi mechanizmust alkalmazzuk. A WPF számos új koncepció mellett egy nagyon fontos újdonságot hordozott magában − az új vezérlőmodellt. hogy a XAML alapú felületek jelentik a jövőt. illetve tulajdonság szintaxissal lehet meghatározni. amelyeknek középpontjában a modern. Alkalmazás fejlesztés Silverlight alapokon Nem is olyan régen a Windows platformra készülő alkalmazások jelentős részét a .Alkalmazás fejlesztés Silverlight alapokon Amennyiben korábban vásárolt teljes értékű Visual Studio 2010 változattal rendelkezünk (Professional. A WPF megjelenését követően a Microsoft hamarosan úgy ítélte. melyet nem sokkal később Windows Presentation Foundation (WPF) néven ismert meg a világ a . A Windows Forms maradiságának okán a technológia leváltására a Microsoft elindította az Avalon projektet. A megvalósítás során hamar belefutunk abba a rendkívül kellemetlen ténybe. aminek természetesen túl sok értelme ugyan nincs.NET keretrendszer egyik kulcstechnológiájának.0 változatban és a 7. XAML szintaktika – értékadás A XAML alapvetően az XML szintaktikai előírásait követi. a webes és intranetes környezetekben is komoly szerepet kaptak. amely a Windows Forms-ot jellemezte rendkívül rugalmatlan és merev volt. ahol különböző folyamatokat és annak státuszait kell megjeleníteni. Meghódították az asztali PC-k világát. melynek feladata a XAML értelmezése és a leírt objektumgráf felépítése. Az alkalmazás. 19 . Ezt a technológiát később Silverlightként ismerte meg a világ. játékterét. A XAML alapú rendszerek komoly sikertörténetet tudnak magukénak.1-ben is a Silverlight. illetve hordozható eszközökön fejleszthetünk alkalmazásokat XAML alapokon. XAML nyelvet választotta.NET 3. a vezérlők alapvetően tartalom jellegű vezérlők (ContentControl) és bármit tartalmazhatnak. Ennek következtében nem tudott megfelelni az új igényeknek. hogy érezzük ezt a kötöttséget. Az XML egyfajta kiterjesztése egy különleges XAML Parser-rel. Sajánlatos módon további sorsát megpecsételte saját képességeinek erős korlátozottsága. de nagyon jól példázza a modell rugalmasságát. képzeljük el. Ha XAML-ben leírunk egy elemet (pl <Button/>). Legújabban pedig különböző mobil. ez pedig a felhasználói felület deklaratív leírása. A sors különleges fintora. mint alkalmazás leíró nyelv. Ennek köszönhetően egy Button vezérlőbe egy másik Buttont. Ez lett a WPF legjelentősebb újdonsága. kiforrott és rendkívül produktív volt.

Content> <StackPanel> <Ellipse Fill="Red" Width="10" Height="10"/> <TextBlock Text="Hello World"/> </StackPanel> </Button.Content> </Button> A fenti példában a Button belső tartalmát egy némileg összetettebb vezérlőfa határozza meg. Markup Extension-öket. akkor a megfelelő névtérre kell hivatkoznunk. Ezek sajátos szintaktikája a következő: PropertyNév="{kiterjesztésneve [hivatkozás paraméterek]}" 20 .dll állomány MyControlsLibrary névterét rendeljük a myControls prefixhez. Figyeljük meg. Prefixszel együtt. amely egymás alá rendezi el az elemeket. Bevezetés a „Windows Phone” platform-ba Tartalom meghatározása attribútum szintaxissal: <Button Content="Hello World"/> A fenti példában a gomb tartalma egy egyszerű string. Ezt a belső tartalmat attribútum szintaxissal nem lehet meghatározni. XAML szintaktika – Leírónyelvi kiterjesztések Gyakran előfordul.assembly=MyControlsLibrary" A fenti példában a MyControlsLibrary. ezért a Content tulajdonságot „ki kell nyitni”. Ha a Windows Phone-ra egy saját Button vezérlőt fejlesztünk. Ezt követően a prefix felhasználásával könnyedén hivatkozhatjuk meg a saját komponenseinket. A belső panelbe pedig egy piros 10 x 10-es kör. akkor azt szeretnénk helyezni a felhasználói felületen használni. A Button belsejébe egy panel kerül. hogy amikor leírjuk az objektumok nevét. Saját komponens meghivatkozása prefixen keresztül <myControls:MyButton> </myControls:MyButton> A fenti példában a myControls prefix által reprezentált névtérben található MyButton komponenst hivatkozzuk meg. Tartalom meghatározása tulajdonság szintaxissal: <Button> <Button. hogy mi most melyik gombra gondolunk? A beépített Button érdekel minket. vagy éppenséggel túl körülményes lenne. azaz tulajdonság szintaxissal kell beállítani a tartalmat. Az ilyen esetekben (például adatkötés.1. hivatkozás statikus erőforrásokra) ún. Prefix definiálása saját komponens használatához: xmlns:myControls="clr-namespace:MyControlsLibrary. azaz leírónyelvi kiterjesztéseket használhatunk. az ún. ezért elegendő attribútum szintaxist alkalmaznunk. vagy a saját Buttont szeretnénk felhasználni? Erre a problémára a prefixek használata jelenti a megoldást. A megfelelő XAML elemeken definiálnunk kell a névtereket egy hivatkozással. XAML szintaktika – Prefixek használata A C#-ban vagy éppen a Visual Basic-ben megszokhattuk. amelyet vagy nem tudunk az XML szintaktikai eszközeivel leírni. De honnan tudhatja a XAML Parser. valamint a „Hello World” felirat kerül. hogy a kör (Ellipse) és a felirat (TextBlock) saját tulajdonságait attribútum szintaxissal határoztuk meg. hogy a XAML Parser számára valami különleges dolgot kell jeleznünk.

Controls.Shell.assembly=Microsoft. A prefix definíciók után néhány PhoneApplicationPage tulajdonság kerül beállításra. ha valami XAML-specifikus dologra van szükségünk.IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent"> </Grid> </phone:PhoneApplicationPage> A PhoneApplicationPage objektum egy Windows Phone képernyőt reprezentál. mint a betűkészlet típusa. 21 .IsVisible tulajdonság határozza meg azt. hogy melyik saját osztály származik a PhoneApplicationPage osztályból.SecondPage" xmlns="http://schemas. XAML alapú felhasználói felületek Egy egyszerű Windows Phone felhasználói felületet leíró XAML részlet anatómiája: <phone:PhoneApplicationPage x:Class="PhoneApp2. ha a fenti sorok egyelőre semmit nem jelentenek számunkra! A későbbi fejezetek során ezek jelentésére fény derül.microsoft.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480" shell:SystemTray. Az x prefix a XAML nyelv saját névterét reprezentálja. Azaz.assembly=Microsoft. óra. ahol nem szerepel prefix. Ez lesz az alapértelmezett névtér. A fenti SystemTray. Az mc:Ignorable paraméter azt határozza meg. illetve az előtér színe.com/expression/blend/2008" xmlns:mc="http://schemas.Alkalmazás fejlesztés Silverlight alapokon Néhány példa markup extension-ökre: <Button Style="{StaticResource buttonStyle}"/> <TextBox Text="{Binding FirstName. hogy a felső rendszerinformációs sáv (akkumulátor töltöttség. futásidőben nem játszanak szerepet.Phone.) látszik-e az alkalmazásban. A következő két tulajdonság azt határozza meg. Végül a PhoneApplicationPage elem kerül definiálásra. kiegészíthető.Phone" xmlns:d="http://schemas. már csak a benne levő tartalom – azaz az oldal tartalma –a kérdéses. De mi az az x prefix? Az x:Class-nál is feltűnt már korábban. ezt kizárólag a tervezőeszköz tartja számon. akkor azt a XAML névtérben találhatjuk meg. Jelen esetben egyetlen Grid panel található benne. Ezek rendszerszintű beállításokra (ún. ebből egy kiemelkedik.Phone" xmlns:shell="clr-namespace:Microsoft. erőforrásokra) hivatkoznak. hogy az alkalmazás milyen orientációkat támogat (SupportedOrientations) és mi az alapértelmezett orientáció (Orientation). csupán az xmlns definíció. stb. azaz ha prefix nélkül írunk le xaml-ben egy elemet. hogy a „d” prefixet nem kell figyelembe venni futásidőben.microsoft. továbbá a panel neve „LayoutRoot” lett.microsoft. A „d” prefixszel ellátott beállítások egytől egyig a tervezőfelület számára meghatározott értékek.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone. amelyen transzparens hátteret határoztunk meg. akkor azt ebben a névtérben fogja keresni a XAML Parser.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas. azaz melyik az az osztály. vagy elrejtjük.openxmlformats. mérete. A következő sorokban számos prefix definíciót látunk. Mode=TwoWay}"/> Ne aggódjunk amiatt. amelyhez az x prefix került hozzárendelésre. Az x:Class tulajdonság segítségével azt határozzuk meg. amelyik a kapcsolódó mögöttes kódban megtalálható.

mint különböző alkalmazás típusok. Egyelőre gondoljunk ezekre úgy. hogy számos különböző projektsablon áll rendelkezésünkre. A következő lépésben a Visual Studio megkérdezi tőlünk. Készítsük hát el első Windows Phone alkalmazásunkat! 1. Hozzunk létre egy új Windows Phone alkalmazást! Kattintsunk a File menüre. illetve különböző felépítéssel rendelkező alkalmazások speciális változatai. Vegyük szemügyre a Visual Studio által létrehozott elemeket! A Solutions Explorer ablak tartalma az 1-3 ábrán látható. Ezekkel a későbbi fejezetek során részletesebben is megismerkedünk majd.1 van kiválasztva. a többi beállítás alapértelmezett értékét hagyjuk meg (1-2 ábra)! Kattintsunk az OK gombra! A dialógus ablakban láthatjuk. 1-3 ábra: A projekt felépítése 22 . hogy el ne készítse rá a dedikált Hello World alkalmazását. Győződjünk meg róla. hogy melyik operációs rendszer változatra szeretnénk fejleszteni. válasszuk ki a New Project parancsot! Az elérhető alkalmazás típusok listájából válasszuk a Windows Phone Application sablont! A projektet nevezzük el HelloWindowsPhone-nak. majd kattintsunk az OK gombra! 3. 1-2 ábra: Új projekt létrehozása 2.1. Bevezetés a „Windows Phone” platform-ba Hello Windows Phone Egyetlen valamirevaló fejlesztő sem vághat bele egy új technológiával való ismerkedésbe anélkül. hogy a Windows Phone OS 7.

normal" Author="HelloWindowsPhone author" Description="Sample description" Publisher="HelloWindowsPhone"> <IconPath IsRelative="true" IsResource="false">ApplicationIcon.Hello Windows Phone A HelloWindowsPhone projekt elemeinek tartalmát az alábbi táblázat mutatja be: Elem neve Properties References App.com/windowsphone/2009/deployment" AppPlatformVersio n="7.png MainPage.xaml (App.0" Genre="apps. A legérdekesebb szekció azonban a Capabilities elem és gyerekei.xaml. hogy az alkalmazás alapbeállításai itt kerülnek meghatározásra: a háttérkép. töltési idő alatt látható kép A Properties alatt található WMAppManifest.xaml.xml fájl megér külön egy kis magyarázatot: <Deployment xmlns="http://schemas. stb.cs) ApplicationIcon.png Background.0.png Induláskor megjelenő. az alkalmazás felirata.microsoft.png</IconPath> <Capabilities> <Capability Name="ID_CAP_GAMERSERVICES"/> <Capability Name="ID_CAP_IDENTITY_DEVICE"/> <Capability Name="ID_CAP_IDENTITY_USER"/> <Capability Name="ID_CAP_LOCATION"/> <Capability Name="ID_CAP_MEDIALIB"/> <Capability Name="ID_CAP_MICROPHONE"/> <Capability Name="ID_CAP_NETWORKING"/> <Capability Name="ID_CAP_PHONEDIALER"/> <Capability Name="ID_CAP_PUSH_NOTIFICATION"/> <Capability Name="ID_CAP_SENSORS"/> <Capability Name="ID_CAP_WEBBROWSERCOMPONENT"/> <Capability Name="ID_CAP_ISV_CAMERA"/> <Capability Name="ID_CAP_CONTACTS"/> <Capability Name="ID_CAP_APPOINTMENTS"/> </Capabilities> <Tasks> <DefaultTask Name ="_default" NavigationPage="MainPage. Ezeknek a gyerekelemeknek a felvételével határozhatjuk meg.png</BackgroundImageURI> <Count>0</Count> <Title>HelloWindowsPhone</Title> </TemplateType5> </PrimaryToken> </Tokens> </App> </Deployment> A fenti XML kódrészletben jól látható.0.1"> <App xmlns="" ProductID= "{9bb8c371-293f-4726-a4ba-5b2e2efb152d}" Title="HelloWindowsPhone" RuntimeType="Silverlight" Version="1.xaml (MainPage. az ikon.cs Elem jelentése Az alkalmazás tulajdonságait és beállításait tartalmazó állományok Hivatkozott egyéb könyvtárak Az alkalmazást reprezentáló objektum és a mögöttes kódja A lapkához tartozó kép Az alkalmazás háttérképe Az alkalmazás főoldala és a kapcsolódó mögöttes kód SplashScreenImage.xaml"/> </Tasks> <Tokens> <PrimaryToken TokenID="HelloWindowsPhoneToken" TaskName="_default"> <TemplateType5> <BackgroundImageURI IsRelative="true" IsResource="false">Background. hogy az alkalmazásunk a telefon 23 .

0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <!--ContentPanel .ApplicationBar>--> </phone:PhoneApplicationPage> A PhoneApplicationPage beállítások már korábban tisztázásra kerültek.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas. 4.IsVisible="True"> <!--LayoutRoot is the root grid where all page content is placed--> <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.Shell.Row="0" Margin="12.Phone.0.17.17.0.RowDefinitions> <!--TitlePanel contains the name of the application and page title--> <StackPanel x:Name="TitlePanel" Grid.png" Text="Button 1"/> <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2. ezért koncentráljunk most a LayoutRoot elnevezésű Grid panel tartalmára! Ha sok benne az ismeretlen elem.12.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Row="1" Margin="12.microsoft.MenuItems> </shell:ApplicationBar> </phone:PhoneApplicationPage. a későbbi fejezetekben azokat részletesen bemutatják! Az érdekes rész az ApplicationTitle és PageTitle névvel rendelkező TextBlock vezérlők Text tulajdonságai.assembly=Microsoft.Row="0" Margin="12. ne aggódjunk.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.place additional content here--> <Grid x:Name="ContentPanel" Grid. Bevezetés a „Windows Phone” platform-ba mely képességeihez fér hozzá.png" Text="Button 2"/> <shell:ApplicationBar.0.-7.1. Módosítsuk az értékeket a következő módon: <StackPanel x:Name="TitlePanel" Grid. mit képes kihasználni.Controls.0.com/expression/blend/2008" xmlns:mc="http://schemas.0"></Grid> </Grid> <!--Sample code showing usage of ApplicationBar--> <!--<phone:PhoneApplicationPage.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray.ApplicationBar> <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True"> <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.28"> <TextBlock x:Name="ApplicationTitle" Text="MY FIRST APPLICATION" 24 . majd vegyük szemügyre annak tartalmát: <phone:PhoneApplicationPage x:Class="HelloWindowsPhone. hogy itt csak azok az elemek maradjanak meg. amelyeket ténylegesen is használunk.microsoft. Biztonsági szempontból érdemes ügyelni arra. Kattintsunk duplán a MainPage.MenuItems> <shell:ApplicationBarMenuItem Text="MenuItem 1"/> <shell:ApplicationBarMenuItem Text="MenuItem 2"/> </shell:ApplicationBar.MainPage" xmlns="http://schemas.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.xaml állományra. A Text tulajdonság határozza meg a felirat tartalmát.28"> <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="page name" Margin="9.assembly=Microsoft.Phone" xmlns:d="http://schemas.openxmlformats.microsoft.

majd futtatja rajta az alkalmazást. Ez azt jelenti.0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> 5. } 7. majd válasszuk ki a Start Debugging menüpontot! 9. telepíti rá.0. Keressük meg a ContentPanel elnevezésű Grid panelt! Ennek a belseje fogja reprezentálni az oldal tartalmát.cs kódállományt. ha szeretnénk közvetlenül egy valódi eszközön futtatni az alkalmazást.Show("Windows Phone says hello!").-7.0"> <Button Content="Greet Me" Click="Button_Click" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid> Ezzel egy középre igazított gombot helyeztünk el.0. Egészítsük ki a kódot.xaml.Row="1" Margin="12. Kattintsunk az egér jobb gombjával a Button_Click szövegre. közvetlenül a menü alatt láthatjuk a Windows Phone Emulator beállítást. 25 . Az emulátor elsőre lassabban indul el. RoutedEventArgs e) { MessageBox. A futtatás megkezdéséhez kattintsunk a Debug menüre. hanem a Visual Studióban érdemes a futást megszakítani. Figyelem: Az emulátort csak egyszer kell elindítani. hogy a Visual Studió alapértelmezett módon az emulátoron futtatja majd az alkalmazást. és a megfelelő eseménykezelő metódusra navigál. melyen a „Greet Me” felirat található. Ezen felül a Click eseményre is feliratkoztunk egy Button_Click eseménykezelő metódussal. Az éles eszközön való tesztelés esetén a következő feltételeknek rendelkezésre kell állniuk:    Zune Desktop alkalmazás fut a háttérben A telefon össze van kötve USB adatkábelen a számítógéppel A telefonon a lockscreen fel van oldva 8. Ha az emulátor még nem fut. az alábbi módon: private void Button_Click(object sender.12. de egyetlen futó példányon bármennyi tesztfuttatást indíthatunk! A lenyíló menüben a Windows Phone Device-t is kiválaszthatjuk. 6. nem érdemes leállítani azt. akkor indít egy újat. Teszteljük az alkalmazást! Kattintsunk a Greet Me gombra! Az eredmény az 1-4 ábrán látható.Hello Windows Phone Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="hello page" Margin="9. és válasszuk a Navigate To Event Handler parancsot! Ennek hatására a Visual Studio megnyitja a MainPage. Futtassuk az alkalmazást! A Visual Studio felső sávjában. ha végeztünk a futtatással. Helyezzük el benne az alábbi kódrészletet: <Grid x:Name="ContentPanel" Grid.

Bevezetés a „Windows Phone” platform-ba 1-4 ábra: A „Hello Windows Phone” alkalmazás futás közben Összefoglalás Ebben a fejezetben megismerkedhettünk a Windows Phone alkalmazásplatformmal. Betekintést nyerhettünk a platform legfontosabb építőelemeibe. beállításai. amelynek során részletesen megvizsgáltuk. 26 . A következő fejezetekben ezt a tudást mélyítjük el. hogy végül professzionális alkalmazásokat tervezhessünk és fejleszthessünk. a Silverlight és a XAML nyelv alapjaiba. melyek a legfontosabb elemei. valamint megírtuk életünk első Windows Phone alkalmazását. hogyan is épül fel egy Windows Phone projekt.1. Bemutatásra került a fejlesztőeszköz.

egyéb okostelefonok társaságában. ismeretlen. majd az ezt követő funkcionális innovációra. de számos kulcsfontosságú hozzávalót sikerült azonosítani a sikerhez vezető úton. A Windows Phone jelenség Ebben a történetben nem a Microsoft a felfedező. Ennek az „újraindításnak” eredményeképpen született meg a Windows Phone 7. amely az elmúlt években egy új területre gyűrűzött be. illetve Android alapú mobil rendszereiket. a felhasználói élmény tekintetében a versenytársakétól merőben eltérő. a felhasználók. az emberek felé. hogyan lépnek interakcióba a felhasználók telefonjaikkal. valós igényeitől. hogy ezúttal az innovátor szerepét kell magára vállalnia.2. 27 . Az évszázadok során a piacok talán legfontosabb mozgatórugójának az innováció bizonyult. amely jól elkülönül a többi konkurens terméktől. Ezen a piacon. Legtöbben talán emlékszünk még a fél tégla méretű. Felhasználói élmény tervezése Windows Phone-on A történelem során vállalkozások ezrei keresték a siker zálogát jelentő receptet. A Microsoftnak ilyen értelemben egy markáns piacra kellett belépnie. Ilyet senki nem hozott nyilvánosságra. sokkal inkább az Apple és a Google. Az újdonság alkotásának képessége felbecsülhetetlen értékű kincsnek számít az informatika világában is. melynek során a telefonok egyre okosabbak lettek. ahol számos esetben a felhasználók rákényszerülnek a lehetséges és elérhető megoldásokra. telefonálásra éppen csak alkalmas készülékek megjelenésére. Olyan készülékkel akart piacra lépni. alapjaiban gondolta újra. és egy ilyen belépés sohasem egyszerű. egyedi megjelenéssel rendelkezik. az írhatja a következő sikertörténetet. hogyan és mire használják azt. A Microsoft terméke valóban jól megkülönböztethető. a Windows Mobile-t hátrahagyva. és az a piaci szereplő lehet a nyerő. melyeknek köszönhetően ezek a szinte már számítógépnek nevezhető készülékek egyre inkább eltávolodtak a felhasználók gondolkodásától. akik komoly sikerre vitték saját iOS. Ennek az izgalmas és érdekes hullámvasútnak az egyik legfőbb oka az innováció (vagy éppen annak hiánya volt). mint a hagyományos értelemben vett IT szektor. Egyre komplexebb szoftverek és operációs rendszerek jelentek meg. aki felismeri ezt az új helyzetet. Az elmúlt években mamutokat láthattunk visszasüllyedni a középszerűségbe. A Microsoft korábbi okostelefon rendszerét. a fogyasztói termékek piacán a felhasználó diktál! Az ő igényei az elsődlegesek. vagy éppen csőd közeli cégeket mamutokká válni. hogy az okostelefonok szerepét és jelenségét alapjaiban újra kell gondolni és tervezni! Ez a piac más. Ennek az innovációs hullámvasútnak a legmarkánsabb területe éppen a mobilpiac. és egy új szellemiséget tükröz. A 2-1 ábrán látható a Windows Phone. A sikerhez azonban nem elég egy jó másolat elkészítése. A megszokott funkcionális innováció mellett újabb irányt vett. Néhányan azonban sikeresen felismerték. különösen nem ilyen versenytársak mellett. A Microsoft jól tudta. ezért a legfontosabb területen. más rendszert alkotott. A Windows Phone tökéletes példája ennek a történetnek.

hogy nem az alkalmazás és a vezérlők kerete vagy a „csicsa” az. ahol a felhasználók kiszolgálása. egyre nagyobb teret kapnak az infografikus felületek. a jól használhatóság különös jelentőséggel bír. A weben. Azokon a területeken. infografikus felület. 2-2 ábra: Infografikus megjelenés 2-3 ábra: Ikonografikus megjelenés 28 . Felhasználói élmény tervezése Windows Phone-on 2-1 ábra: Windows Phone 7 a versenytársak mellett Ikonografikus és infografikus felületek Az egyediség kulcsa egy új koncepció. az ún. Ez persze nem jelenti azt. az információ átadás. hanem a benne levő tartalom. Ikonografikus környezetben és koncepcióval is rendkívül jól használható. Az infografika az információközlés igazi művészete. (A csicsa jelen esetben semmiképp sem pejoratív értelemben értendő. izgalmas és szép felületeket készíthetünk. hogy azok a versenytársak. a reklám és a média világában ez az irányzat már jó ideje elsőbbséget élvez. akik az ikonografikus felületet részesítik előnyben. Ez az új gondolkodásmód egy igen izgalmas és markáns design nyelv létrejöttét eredményezte. A Microsoft által választott út kimondja.2. a tartalom. ami meghatározza egy alkalmazás jellegét. a 2-3 ábrán pedig egy ikonografikus felület látható. Míg a versenytársak termékei rendre a megszokott és egyébként nagyon jól bevált ikonografikus megjelenést részesítik előnyben.) A 2-2 ábrán egy infografikus. addig a Microsoft új utat választott. rossz úton járnának.

képek. szabad területben gazdag megjelenés 29 . amikor az elsődleges szempont a tájékozódás. jelzések. ahogyan ezt a 2-5 ábra is tükrözi. ami új és idegen számukra. A Metro is ebből az eszköztárból merít ikonok. A felhasználók nehezebben azonosulnak mindennel. rohamtempóban vette át a stafétát a régebbi felhasználói felületektől. A 2-4 ábrán láthatjuk a Metro dizájn forráselemeit.A METRO Dizájn Nyelv A METRO Dizájn Nyelv Az infografikus megközelítés szellemében a Microsoft kialakította saját ún. dizájn nyelvét. az egyértelmű vizuális kommunikáció és az érthetőség. de ugyanakkor pehelykönnyed működést és érzést kell biztosítania. valamint célorientált. Az életünk és a környezetünk tele van olyan elemekkel. A bonyolult felületek. Azóta ez a megjelenés gyakorlatilag a Microsoft összes termékében visszaköszönt. néhány alapvetést fektet le. Nézzük meg ezeket közelebbről! Ismerős megjelenés A felhasználói felület nem más. a bankokban. A dizájn nyelv csupán az alapvető szellemiséget határozza meg. bátran alkalmazza a szabad és üres területeket. mint a kommunikációs csatorna a felhasználókkal. amely a Windows Phone 7-es készülékeken jelent meg először. A Metro felület könnyed. a pályaudvarokon. hogyan is működik az alkalmazás. feliratok alkalmazásakor. a nehézkes megjelenés csupán a komplexitáshoz és a zsúfoltság érzéséhez járulhatnak hozzá. olyan termékekben. a metró aluljárókban. 2-4 ábra: Metro dizájn források Tiszta és pehelykönnyű A felhasználói felületnek gyorsnak és válaszképesnek kell lennie. mint például az Xbox360 Dashboard vagy éppen az új Windows 8 UI. letisztult és nyílt. 2-5 ábra: Letisztult. ezen keresztül adható tudtukra. az utcán. melyeket jól megszoktunk. ismerősek és könnyen érhetőek: jelzések és apró infografikák a reptereken.

a túl sok fölösleges. tágas felhasználói felületeket! 30 . letisztultak és modernek. Legyünk őszinték. ez egy digitális termék! Ma már nincs szükség arra. Állandóan mozgásban A mozgás. A tartalom az elsődleges A felhasználói élményt tervező szakértők körében jó ideje elfogadott és hangsúlyozott elv a „Content is King”. öncélú vizuális elem gátolja a felhasználó szabad mozgásterét. A felhasználók ezeket az alkalmazásokat érintéssel („tapogatással”) fedezik fel. Felhasználói élmény tervezése Windows Phone-on Digitális eredetiség Nincs szükség arra. A vizuális visszajelzés elsődleges eleme az animáció. Ilyenkor a felületen a keret. Gyors. hogy műveleteik. legyünk egyszerűek. hogyan használja az alkalmazásunkat. könnyed animációkkal pillanatok alatt megtaníthatunk bárkit. az egyensúlyra. Az egyik legfontosabb irányelv a Metro dizájnban a tartalom elsődlegessége a kerettel szemben. a gomb kattintható! Nincs szükség fölösleges grafikai elemekre. letisztult. és építsünk minimál-dizájnnal rendelkező. hogy egy gombot 3D-snek tüntessünk fel ahhoz. Az animációk nem öncélúak. A jól kidolgozott animációk meghatározzák az alkalmazás ritmusát és dinamikáját is. az animációk jelentik a felhasználók és az eszközök közötti kétirányú interakció gerincét. hanem tanító. hogy másnak mutassuk az eszközt. a felfedezést.2. a jó vizuális hierarchiára! Legyen a tartalom maga gyönyörű! Megfelelő betűtípusok és egyensúly alkalmazása mellett egyetlen fehér papírlap is lehet rendkívül esztétikus és vonzó. tevékenységük milyen hatással bír a felületre nézve. Az érintőkijelzőnek köszönhetően természetes mozdulatokkal vezérelhetjük az alkalmazásainkat. képekkel. hogy jelezzük. koncentráljunk a lényegre! 2-6 ábra: Digitális megjelenés Gyönyörű tipográfia Fölösleges grafikai elemek nélkül is készíthetünk rendkívül ízléses és gyönyörü felhasználói felületeket. Különösen fontos szerepet játszik ez a gondolat érintőképernyős alkalmazások tervezésekor. videókkal próbálnak interakcióba lépni. hagyjuk el a fölösleges keretet. azaz a „tartalom mindenekfelett” elv. megértését az alkalmazás működésére vonatkozóan. informatív jellegűek. A felhasználók számára azonnal jeleznünk kell. a hangsúlyozásra. Koncentráljunk a szép betűtípusokra. Koncentráljunk a tartalomra. figyeljünk oda a méretekre. mint ami valójában. szavakkal.

ahol felhasználók ezrei. hogy az esetek többségében nem bízhatjuk a fejlesztőre a felhasználói élmény kialakítását. kellő 31 . de ugyanakkor konzisztens.Design vezérelt fejlesztés 2-7 ábra: Tartalom a középpontban A Metro dizájn nyelv. A User Experience Design (UXD). Annak az esélye azonban. hanem azt a megfelelő szakembereknek kell kezükbe venniük. melynek elveit szem előtt tartva professzionális. Ebben az esetben ugyanis a fogyasztói piacra fejlesztünk.és szórakozáscentrikus Xbox Live Hub-bal. a szociális hálókat összefogó People Hub-on át. hogy komoly szakmák létrejöttét eredményezték ezek a körülmények. elég csekély. mint például a Office termékcsalád (2-8 ábra). hogy egy teljes UXD csapatot alkalmazhatunk mobil alkalmazásaink fejlesztésénél. Nem véletlen. amely alkalmazza ezeket az elveket minden szoftverében. El kell fogadnunk. remélhetőleg tízezrei fogják használatba venni és „nyúzni” alkalmazásainkat. innovatív. Elkeserednünk azonban nem érdemes. kezdve a játék . Ennyi különböző ember igényeinek kielégítése igen komoly és nehéz feladat. egészen a professzionális alkalmazásokig. Komolyabb rendszerek építésekor ezekre a területekre külön specializálódott szakembereket alkalmaznak. új generációs felületeket alakíthatunk ki. vagyis a felhasználói élmény tervezése mint tevékenység számos területet foglal magába. A Windows Phone 7 az első olyan termék. 2-8 ábra: Metro-s megjelenés alkalmazás típustól függetlenül Design vezérelt fejlesztés A Windows Phone 7 alkalmazásfejlesztés eszenciája némileg eltér az eddig megszokottól. mára a Microsoft saját termékeinek elsődleges dizájnjává nőtte ki magát. Ők a User Experience Designerek.

grafikonokat. A középszerűségből csak úgy emelkedhetünk ki. nekiállhatunk megtervezni. Ehhez azonban tisztában kell lennünk a kulcsfontosságú területekkel! Tartalom és információs architektúra A Metro egész szellemisége a tartalom köré épül. hogy a tartalom megfelelően tálalva. hogy gondosan elemezzük. hogy mit és hogyan mutatunk meg a felhasználónak! Ne a vizualitásból induljunk ki.2. annak kell ragyognia. hogy miként reprezentálhatjuk ezt látványosan. melyeket láttatni kell a felhasználóval. hogy hajtson végre valamit az alkalmazásunkkal. esztétikus alkalmazás. hogy a felhasználó fejével gondolkodjunk. amelynek ki kell emelkednie. ezért létfontosságú. prioritás és érték szerint kerüljön megjelenítésre (2-9 ábra)! 2-9 ábra: Tartalom meghatározása Metro elvek szerint Használhatóság és ergonómia A felhasználói élmény tervezésének másik fontos területe az ergonómiai kérdések tisztázása. nem elegendő. amelyben a vizuális hierarchiától kezdve a navigáción át. A legfontosabb dolog. infografikákat! Végig tartsuk szem előtt. folyosó tesztek: kapjunk el valakit a folyosón és kérjük meg. Teszteljünk minél többet. sok mindent gondosan meg kell terveznünk. a vizuális dizájnra nem. Használjuk bátran a vizuális eszközöket. hogy a Metro dizájn elveit betartjuk. az információból! Döntsük el. A weben tömegével megtalálható infografikai példák komoly segítséget nyújthatnak. a használhatóság biztosítása. amit csinál. A fogyasztói termékek piacán azonban elengedhetetlen a szép. Ezért a legfontosabb a kezdő ergonómus számára. Ne essünk tévedésbe! Az a gyakorlat. hanem az értékből. 32 . melyek a legfontosabb elemek. előbb-utóbb nem vesszük észre benne a finomságokat. a kiemelkedő vizuális élmény. Ez igen tág témakör. ha maradandó élményt nyújtunk! Sok mindenre sajnálhatjuk az erőforrásainkat. egészen az apró részletekig. a tartalom az. mi a legértékesebb információ! Miután ez a tudás már a birtokunkban van. rosszabb esetben a nagyobb bajokat sem. és egy fekete-fehér alkalmazást készítünk. Szintén sok ötletet meríthetünk egyéb sikeres alkalmazásokból. és folyamatosan finomítsuk a felhasználói felületünket! Esztétika és vizuális élmény A dizájnerek fontossága soha sem volt kétséges. Ha elég sokat foglalkozunk a saját termékünkkel. és ennek megfelelően alakítsuk ki a felhasználói felületet! Sajnálatos módon az objektivitásukat még a gyakorlottabb szakemberek is igencsak nehezen tudják megőrizni. hogy tesztelje le. kérjük ki mások véleményét. Rendkívül sokat segíthetnek az ún. Az alkalmazás középpontjában a tartalom van. Felhasználói élmény tervezése Windows Phone-on odafigyeléssel mi magunk is kellemes élményt alakíthatunk ki. figyeljük a felhasználóink „ügyetlenkedését”.

amikor a funkciók. melyeknek a felhasználói felületét előre megtervezték. Azok a termékek. A dizájn szórakoztató! Tervezzünk magunk! Csupán három dologra van szükségünk a munkához! Papírra. amikor az alkalmazás körvonalazódni látszik. sokkal jobb minőségűek. hogy egyre jobb és minőségibb termék szülessen. amit építünk. és ennek eredményeképpen jóval kevesebbet fogunk hibázni a fejlesztés alatt. születnek azok a gondolatok. hogyan alakulnak majd a felületek. az ötletek záporoznak. Magasabb termékminőség A pontos UI tervezés komoly előnye. az ötletelésről szól. Az ötletelés. a brainstorming hozzájárul ahhoz. A dizájn szórakoztató. Az egyik legizgalmasabb pillanat és folyamat. egyre jobban megértjük a problémakört. Számtalan szoftver szenved a dizájn és a UI tervek hiánya következtében előálló káosztól. Írjuk le az ötleteket. és az innovatív gondolatok születnek. Időközben nem árt újra és újra végigszaladni a terveken és újraértékelni. mint az ad-hoc. azt hogy a felhasználóknak . „evolúciós” felhasználói felülettel rendelkező társaik. A probléma megértése Miközben a tervezés zajlik. napok. ceruzára és arra. Innováció tervezés közben Amikor az alkalmazás megjelenik a szemünk előtt. mi is az. amit csinálunk. semmit se zárjunk ki! A csoportos ötletelés fantasztikus eredményekre vezethet. amelytől a termék igazán innovatív lehet. amelyek meghatározzák. Gondolataink rendszerezéséhez nagy segítséget nyújthatnak a különböző mindmapping szoftverek. 33 .mind a funkciók. hogy az elkövetkező hónapok kemény munkájának eredménye gyümölcsöző lesz vagy éppen csúfos bukás.Csináld magad! 2-10 ábra: Dizájn alkalmazása a tartalom fölött Csináld magad! A dizájn-vezérelt tervezés legfontosabb eleme maga a tervezési folyamat. a használati esetek alapján történő fejlesztés nem visz közelebb a jó felhasználói élményhez. Sokkal jobban átlátjuk a feladatot. hogy a fejlesztés során sokkal egyértelműbb. a hibás gondolatok. Ez nagyon fontos „mellékhatása” a tervezési folyamatnak. Ezek azok az órák. A szöveges specifikáció. mind a felhasználói felület tekintetében – hol helyezkednek el a prioritások és a súlypontok. az újratervezés minimális lesz. és hogyan szolgálhatja a legjobban a felhasználó igényeit. helyenként még a szoftver és a felület instabilitásához is hozzájárulhat. a felhasználói felületek épülnek. illetve az interakciós folyamat végiggondolása közben azonnal megmutatkoznak a rossz koncepciók. Rajzolás. hogy ne munkának fogjuk fel.

Tervezés Sketchflow-val A Microsoft Expression Blend for Windows Phone termék rendkívül hatékony eszköz. Windows Phone fejlesztéshez elérhető a Codeplex-en. melynek segítségével Windows Phone alkalmazások prototípusát készíthetjük el. Sketchflow projektek létrehozására is. Az Expression Blend egyéb változataiban lehetőségünk van ún. Sketchflow-s Projekt sablon a Blend-hez (http://wp7sketchflow. Ezek a projektek kizárólag sketchek.com/).2. használhatunk erre specializálódott eszközöket is. Felhasználói élmény tervezése Windows Phone-on Amennyiben a felhasználói felület tervezését formális eszközökkel támogatni kívánjuk. (2-11 és 2-12 ábrák) 2-11 ábra: Sketchflow-val tervezett dinamikus prototípus 2-12 ábra: Sketchflow navigációs térkép 34 . Ez a fejlesztőeszköz Windows Phone fejlesztéshez ingyenesen elérhető. a hatékony és gyors munkában elengedhetetlen szerepe van. vázlatok. mint például az Expression Blend Sketchflow.codeplex. A felhasználói felület végleges kialakításában. dinamikus prototípusok készítésére alkalmasak.

„app”-ként gondolnak. amelyeknek nem céljuk a felhasználói bázis kialakítása. A konkurens okostelefon gyártók az alkalmazásokra szó szerint alkalmazásként.com/products/windows-phone-sketch-pad) vagy a Windows Phone 7 Sticky Padet (http://www. a funkciók. Ők Anna és Miles (2-13 ábra). Hogyan érdemes hát nekiállnunk az alkalmazás megtervezésének? Windows Phone alapú rendszerek esetén egy különleges koncepcióval gazdgabbak lehetünk. Könnyebb és precízebb a tervezés minden fázisa.com/products/windows-phone-sticky-pad). Saját alkalmazásunk tervezésekor is kiemelkedő szerepe van a célközönség pontos meghatározásának. sokkal inkább integrált élményről. melyekben azt elemzik. Élmény vagy alkalmazás Mobilalkalmazás boltok nem olyan régóta léteznek.Élmény vagy alkalmazás Sketchflow-t használva akár saját magunk számára. A Metro Design kialakításakor a Microsoft is meghatározta saját célközönségét két ún. A Sketch projektek tervezése elsősorban a felhasználói élmény tervezésről szól. Ennek részben a temérdek „egy funkciós” alkalmazás az oka.uistencils. csupán az egyszeri letöltés. akár ügyfeleink számára egyértelműen kommunikálhatjuk. Azaz ebben a fázisban ergonómiai szempontokat veszünk figyelembe. a logikus és helyes működés az elsődleges. Windows Phone alatt azonban nem csupán egyszerű alkalmazásokról van szó. amennyiben 35 . 2-13 ábra: A Windows Phone 7 átlagos felhasználói Anna sikeres PR szakértő és elfoglalt fiatal anyuka. néhány dolgot szem előtt kell tartanunk! Ismerjük meg a felhasználóinkat! Az alkalmazás fejlesztésekor a célközönség megválasztása és azonosÍtása kulcsfontosságú. Általános mintaként azonosították. Papíralapú tervezésnél érdemes lehet külső sablonokat felhasználni. A legsikeresebb alkalmazások – amelyek folyamatosan a top 50-ben szerepelnek – sok energiát fektetnek felhasználói bázisuk megtartásába és kielégítésébe. hogy az alkalmazások mindössze 10%-a éri meg a használatbavételt követő 100-ik napot. pontos definiálásában. de már megjelentek olyan tanulmányok. perszóna definiálásával. hogy az alkalmazások életciklusa hogyan alakul. miként fog működni az alkalmazásunk. Ahhoz. hogy kiemelkedő élményt nyújtsunk. Miles pedig építész saját vállalkozásában. A Windows Phone 7 tervezésekor az UX csapat ezt a két fiktív személyt használta a felhasználói igények meghatározásában.uistencils. Például: a Windows Phone 7 Sketch Padet (http://www. Az alkalmazások nagy részét a letöltést követő pár napban a felhasználók elhagyják.

mintha szinte csak neki íródtak volna. Azok az alkalmazások. netán akadozó animációk nagyban rontják a felhasználói élményt.és hírközpontú alkalmazások. amelyek róla szólnak. illetve weboldala: releváns. könnyen használható és egyszerűen tanulható. annál nagyobb sikerre számíthatunk! 2-14 ábra: Személyes alkalmazás (Facebook) Hasznos. melyek segítségével jó eséllyel népszerű és közkedvelt alkalmazást készíthetünk felhasználóink körében. Jól integrálódik az operációs rendszer megszokott jellemzőivel (pl. újdonság szolgáltatása nélkül szinte lehetetlen a felhasználóinkat visszavonzani. Ezek a tényezők együttesen fektetik le azokat a jellemzőket és alapvetéseket. személyes. a nem. nehézkes. A mozgás és az animáció minősége és jellege határozza meg elsősorban. személyre szabott. A korosztály. A Windows Phone alkalmazások felhasználói felületén alkalmazott mozgásokat két részre érdemes bontani: 36 . A felhasználói kör számára értékes és érdekes tartalmat próbáljuk szolgáltatni a lehető leggyakoribb rendszerességgel! Személyes alkalmazások Az ember számára a legérdekesebb saját maga. Felhasználói élmény tervezése Windows Phone-on megszemélyesítjük a jellemző felhasználóinkat. a közös jellemzők meghatározása jelentősen leegyszerűsítik a tervezés folyamatát. jól használható. mint objektumok folyamatos átpozicionálásáról. Windows Phone esetén a mozgás és az animáció a legfontosabb visszajelzése annak. amelyek vele foglalkoznak. Nagyon jó példa erre az Amazon alkalmazása. amelyek úgy tesznek. és kívánatos. sokkal sikeresebbek. sima és könnyed animációk ezt az érzetet keltik. az ő igényeiről. Gyakorlati Dizájn Mozgás és animáció A Mozgás jelentősége A mozgás és az animáció többről szól. jó érzés használni. navigáció). Friss és értékes tartalom. a felhasználó számára értékes funkcionalitással bír. Minél inkább a felhasználó képére tudjuk formálni az alkalmazást. hogy a felhasználó mennyire érzi folyamatosan válaszra késznek az alkalmazást. míg a lassú. A gyors.2. naprakész tartalom és ajánlatok. Releváns tartalom Az alkalmazások élettartamát és életciklusát vizsgáló tanulmányokban a legtovább élő alkalmazások jellemzően a sport. kívánatos A tökéletes alkalmazás hasznos. hogy a felhasználói interakciónak virtuális értelemben vett fizikai hatása van.

élményt nyújtanak. Átmenetek bevezetésével elrejthetjük ezt az átmeneti időszakot. megértést segítő animációk (pl. 30 fok lesz Budapesten. vezérlők. és nagyobb biztonsággal fog a képernyők között navigálni. az első vizuális elem. Ennek megfelelően saját élő lapkákra. Ezek együttesen hívják fel a figyelmet az adott feladatokra. releváns információkra. élő lapkák) Felhasználói tevekénységhez kapcsolódó vizuális visszajelzések (pl. melyek az operációs rendszerben található vezérlőkkel azonos működést. a Splash képernyő. hogy azok ne öncélúak legyenek. értesítések. prioritásokra. Ennek megfelelően fontos. a felhasználó dönti el. szép és kellemes Splash képernyőkre van szükség. A Start lapka. míg anélkül – azonnali nézetváltás esetén – esetleg üres képernyő fogadhatja a felhasználót. annál nagyobb a valószínűsége. és alapinformációkat közölnek – például öt új olvasatlan levél van a postaládában. fontos információk közlése (pl. A mozgás segíthet a teljesítmény-problémák palástolásában. A lapkák lehetnek élő lapkák is. Az adatok betöltése. A Start képernyő átrendezhető. hogy egyik nézetről másik nézetre váltunk. ami számít: koncentráljunk a jelenre. ikonok. navigáció) Tanító jellegű. lapkák (tile).    Windows Phone 7 specifikus komponensek tervezése A szépség és a konzisztents kinézet a mobil alkalmazások integráns része. Ha az átmeneteinket ügyesen és egységesen alakítjuk. az információ megjelenítése okozhat némi késleltetést. A mozgás konzisztens működéshez vezethet. de szívesen nézzük. gombnyomás. Így minél dekoratívabb. Start Menü és a lapkák Windows Phone 7 esetén a hagyományos Asztal és az ikonok koncepcióját felváltotta a Start képernyő és a rajta elhelyezett ún. amely lehetőleg segítse a felhasználó megértését az alkalmazás működését illetően. A teljes összképet számos komponens együtt határozza meg. melynek forrása nem feltétlenül felhasználói tevékenység (például értesítések). animálódnak. hogy „az adott pillanat és az adott hely az. melyek az időben változnak. informatívabb egy alkalmazás lapkája. hogy mely alkalmazásokat jeleníti meg a Start képernyőn. játszunk vele. stb. Nemcsak vizuális előnyt jelent az élő lapka. a megjelenés egyik legfontosabb eleme. Az érintőképernyős felület a legtöbb ember számára szórakoztató és érdekes. akkor az alkalmazást a felhasználó konzisztensnek fogja találni. A gyors és sima animációk azt az érzést keltik a felhasználóban. a jól megtervezett szép animációk esztétikai élményt biztosítanak az alkalmazás felhasználói számára. Nemcsak tanító hatása van.Gyakorlati Dizájn   Átmenet (transition): Vizuális visszajelzés arról. Az átmeneteket a felhasználó idézi elő. hogy a Start képernyőre kerülhet. majd bezáráskor oda kerül/zsugorodik vissza) A mozgás mint élmény A mozgás a felhasználói élmény kialakításában kulcsfontosságú szerepet játszik. animált ikonokra. mindig valamilyen fontos célt szolgáljanak. A mozgás eleganciát kölcsönöz az alkalmazásnak. melyeket szép és megkapó módon célszerű tálalnunk.    Érintés nélkül. magabiztosabban fogja az alkalmazást használni. Nem titok. A mozgások tervezésénél fontos figyelembe venni. hogy a telefon használatbavételekor a felhasználót milyen élmény és látvány fogadja. de bizony jóval használhatóbbá is teszi az alkalmazást! A lapka az alkalmazás belépési pontja.   A mozgás kellemes a szemnek. egy kép a helyéről kerül kinagyításra érintés hatására. Ezek gyakorlatilag az ikonokat helyettesítik. Animáció: Vizuális visszajelzés. hogy egyedi. A mozgás karaktert kölcsönöz az alkalmazásnak. hasznos és különleges legyen (2-15 ábra)! 37 . A lapka kinézete jelentősen befolyásolja. koncentráljunk az élményre”.

melyek a megfelelő Windows Phone témák esetén „transzparens” háttérként funkcionálnak (2-16 ábra) Transzparens háttereket. ellenkező esetben az alapértelmezett lapka kerül átméretezésre. Felhasználói élmény tervezése Windows Phone-on 2-15 ábra: Helyes és helytelen lapka dizájnok A dizájn fontos A lapkák esetén a dizájn a legfontosabb! Az elégtelen minőségű. vágáshoz vezethet. felfelé vagy lefelé. árnyékok alkalmazását Lekerekített lapkákat Fekete vagy fehér háttereket. Ezenfelül az alkalmazás listába érdemes külön 63x63 pixeles képet biztosítani. ami torzításhoz. Az ennél nagyobb vagy kisebb képek átméretezésre kerülnek. hogy a Marketplace-ből kisebb eséllyel kerül letöltésre.2. gyengén megtervezett és megrajzolt lapkával rendelkező alkalmazás azt is kockáztatja. Fontos. Különböző képek használata esetén azonban maradjunk minden esetben konzisztensek! A lapkák tervezése során kerüljük el az alábbiakat:      3D-s lapkák használatát A gradiensek használatát. hogy megragadja a szemet! A lapka képeknek 173x173 pixel méretűeknek kell lenniük. színes belső képekkel 2-16 ábra: Helytelen háttérszínek használata lapkáknál 38 . JPEG vagy PNG formátumban.

és alapvetően navigációs modell is egyben. hogy a felhasználók használatba vegyék az alkalmazást. legérdekesebb és legizgalmasabb dolgok szerepelnek (2-18 ábra). jelentősen meghatározza a felhasználó hozzáállását az alkalmazás többi részéhez. ami itt fogadja. melyekkel érdemes mélyebben is megismerkedni. 39 . az operációs rendszerre jellemző vezérlő is helyet kapott. mint az alkalmazás reklámjára. instrukciók elhelyezése teljesen fölösleges. ahol a legfontosabb. Leginkább úgy gondolhatunk rá. Fontos tehát a jó betöltő képernyő megtervezése. hangulatfokozóra. 10) másodpercet. Ezek a vezérlők a fejlesztők számára is elérhetők az SDK-ban vagy a Toolkiten keresztül. Ilyenkor a felhasználói felület még nem áll készen arra. Erre a képernyőre célszerű úgy gondolni. görgethető teljes képernyős konténer. A Panorama vezérlő A Panorama vezérlő egy széles jobbra-balra csúsztatható. 2-17 ábra: Splash képernyők alkalmazása Vezérlők használata Windows Phone 7-ben a hagyományos vezérlők mellett számos specializált. mint egy magazin főoldalára. Ez a két vezérlő a Panorama és a Pivot.Gyakorlati Dizájn Splash képernyő Az alkalmazások indításakor számos inicializációs feladat elvégzésére lehet szükség. amellyel a felhasználó találkozik. közvetlenül a lapkák után. A betöltés során alkalmazunk Splash képernyőket! A Splash képernyő ennek megfelelően a második szint. Minden vezérlőhöz saját tervezési és használati útmutató tartozik. A betöltési idő lehet egy rövid pillanat is. így az itt töltött idő és az élmény. Hosszabb szövegek. A Windows Phone-ra jellemző vezérlők közül kettő kiemelkedik. A betöltő képernyőn a felhasználó könnyedén eltölthet néhány (max. mielőtt szembetalálná magát a felhasználó a tényleges alkalmazással (2-17 ábra). így nem érdemes komolyabb információt megjeleníteni ezen a képernyőn.

A vezérlő használatakor néhány dolgot célszerű szem előtt tartani:      Pivot vezérlőket ne ágyazzunk egymásba! Ne kombináljuk a Pivot és a Panorama vezérlőket! Ne használjunk túl sok Pivot elemet. Háttér meghatározásakor gondoskodjunk a megfelelő kontrasztról a fontok és a háttér között! Ne menjen a design az olvashatóság kárára! Ne használjunk olyan egyéb vezérlőket a Panorama egyes nézeteiben. A vezérlő önálló. valamint az átméretezés elkerülését. a görgetés során pedig egészen egyedi animációval és tulajdonságokkal rendelkezik. Az animáció során a tartalom és a feliratok különböző sebességgel. a felhasználók könnyen elveszhetnek bennük! A Pivot alapértelmezett navigációs mechanizmusát ne írjuk felül! Bizonyos vezérlőket nem célszerű használni a Pivot belsejében (például Slider. A vezérlő használatakor néhány dolgot célszerű szem előtt tartani:       A hátteret célszerű egyetlen színnel vagy egy óvatosan választott háttérképpel kitölteni. elkülönített nézeteket helyez el egymás mellett. Ez biztosítja a jó teljesítményt és a gyors betöltést.2. és biztosítja a navigációt közöttük. amelyek magukban is görgethetők horizontális irányban! Teljesítmény megfontolások miatt szorítkozzunk maximum négy különböző nézetre egyetlen Panorama vezérlőben! A Panorama címe célszerűen sima szöveg legyen! A Pivot vezérlő A Pivot vezérlő a Windows Phone saját Tab vezérlője. Map vezérlők). időben eltolódva hajtódnak végre. dinamikus parallaxszerű effektust eredményezve. A navigáció a menüelemek fejlécét érintve. 40 . illetve 1024x800-as felbontásban. Toggle. A Panorama vezérlővel ellentétben nem egyetlen nagy téren helyezkednek el az egyes szekciók. illetve horizontális mozgatással lehetséges. Felhasználói élmény tervezése Windows Phone-on 2-18 ábra: A Panorama vezérlő A Panorama vezérlő messze túlnyúlik a látható területen. Háttérképként jellemzően JPEG ajánlott 480x800-as. ezáltal rendkívül látványos.

41 . az objektumok közötti szabad területek és a vizuális elemek között. linket. ergonómus) segítségére is. Az új követelmények Érintőképernyős alkalmazások létrehozásának lehetősége teljesen új távolatokat nyit a szoftveripar szereplői előtt. érintés-kombinációk bevezetése kockázatos lehet. Tap. mint például a Pinch. Slide. Méretkorlátok az érintőkijelzőn A felhasználó számára a célobjektumokkal történő érintkezést követően. eddig még nem ismert vagy nem használt interakciós modellek születését teszik lehetővé. A technológia jellemzőinek köszönhetően rendkívül sima és folyamatos élményt lehet biztosítani. közvetlenül. képet vagy bármilyen objektumot elsőre eltalálni. A Windows Phone 7 telefonok követelményei között szerepel. Pontos és csupán könnyed érintést igényel. Az ilyen nagy lépésekhez a fantázián túl szükség lehet szakember (pszichológus. a felhasználó számára legfrusztrálóbb negatív élmény. Ellenben számos elfogadott multitouch mozdulat közül választhatunk (2-19 ábra). így a ma kapható modern okostelefonok jelentős része ilyen típusú kijelzőket alkalmaz. Az egyik legfontosabb áttörés a kapacitív értintőképernyők megjelenése volt.Gyakorlati Dizájn Érintőképernyős alkalmazások tervezése A hardver A kijelzők technológiája rengeteget fejlődött az elmúlt években. Interakciós modellek Habár nem beszélhetünk szabványosított modellekről. 2-19 ábra: Használható gesztusok Windows Phone-on A Windows Phone 7 jelen pillanatban 12 különböző mozdulatot képes megkülönböztetni API szinten. ha nem tudja az adott gombot. Az ilyen típusú felületek új. így az új típusú modellek kidolgozása során figyelembe kell venni az emberi tényező mellett a méretkorlátokat is. hogy az ideális célobjektum területe minimum 81mm2-es (9mm x 9mm). Ennek megfelelően bizonyos korlátokat célszerű szem előtt tartanunk. Ugyanakkor a kijelzők mérete – okostelefonokról lévén szó – erősen korlátozott. Az egyik. vizuális visszajelzést kell biztosítanunk. hogy az eszközöket kapacitív kijelzővel kell ellátni. Hosszas használhatósági tesztelés során megállapították. teljesen új mozdulatok. Minimum méretek érintéshez Az érintésre működő felületek kialakítása finom egyensúlyozás a méretek. és így tovább. TapAndHold.

a 2mm-es minimum jó alsó határértéknek tekinthető. Az ideális méret. Ez az érték csupán a kis vizuális elemekre értendő. A helyes interkaciós modellek megválasztása és támogatása kulcsfontosságú szereppel bír a felhasználói élmény. Felhasználói élmény tervezése Windows Phone-on 2-20 ábra: Érintéskor a célobjektum ajánlott területe Ennél kisebb objektumok is elképzelhetők. holt terület helyes meghatározása. A helyzeten tovább javít az ún. Ilyenkor azonban célszerű a célobjektum szélességét magasabb értékben megállapítani! 2-21 ábra: Ajánlott sormagasság Minimum méretek vizuális elemek tekintetében A vizuális elemeket illetően minden olyan elemnek. amelyen már a vizuális visszajelzés (lenyomás animáció) is érzékelhető 10-15mm2 között mozog. Vizuális elrendezés A sikertelen találatnál csak egy frusztrálóbb dolog van: amikor a felhasználó nem azt az objektumot érinti meg. és semmilyen interakcióval nem rendelkezik. melyek mind számunkra. Ezeket az elveket betartva olyan stabil termékek születhetnek. örömteli perceket szerezhetnek. Holt területnek nevezzük azt a szabad területet. mind a felhasználóink számára élvezetes. amely érintésre reagál. A gyakorlati tippek fontos útmutatóként szolgálnak az ergonómiai követelmények kielégítésében. tipikusan listák esetében.2mm2-esnek kell lennie. a használhatóság vonatkozásában! Összefoglalás Ebben a fejezetben megismerkedtünk a Metro Design legfontosabb elveivel. 42 .2. minimum 4. A fenti szempontok figyelembevételével ennek a kockázata jelentős mértékben csökkenthető. amely két célobjektum között helyezkedik el. azaz „félrenyom”. Ezenfelül az érinthető. Bár a holt területet célszerű arányaiban megállapítani. Ennél kisebb területet a felhasználók nem fognak interaktívnak tekinteni. itt a minimum korlát a 7mm-es magasság. amelyet szándékozott. valamint a dizájnvezérelt tervezés módszerével. interaktív területet is célszerű nagyobbnak választani a vizuális elem területénél.

Ezek azok az alapvető építőelemek. a Windows Phone 7-re átszabott változatban is két nagyobb részben jelenik meg ennek megvalósítása: a vezérlőkönyvtárban. Mivel már rengeteg könyv megjelent Silverlight 4 témában. illetve saját vezérlőket hozzunk létre. ezenfelül pedig könnyedén animálhatjuk azokat. Szerencsére a Microsoft nagy hangsúlyt fektet a különböző technológiái közötti átjárhatóságra és a hordozható tudásra. Különböző vizuális állapotokat hozhatunk létre. A Silverlight alapú fejlesztésre – mint azt a korábbi fejezetek már említették – két eszközt is biztosít számunkra a Microsoft. de korábban megszerzett tudása azonnal és közel száz százalékosan átvihető WP7-re. amelyek testre szabhatóvá. ez a fejezet csak egy gyors. Ebben a fejezetben ezeket a témaköröket nézzük meg közelebbről.3. Az Expression termékek elsősorban a dizájnereknek készültek – ahogy a Silverlight elődjét. és megismerkedünk még néhány fontos koncepcióval – például az erőforrások és a témák használatával –. és az ezekben leírtak komolyabb változtatások nélkül alkalmazhatók Windows Phone 7-fejlesztésben is. adatfüggő felületeket. hogy segítsék a dizájnerek és a fejlesztők együttműködését. A Visual Studio 2010 elsősorban a fejlesztőknek készült. amelyek segítségével a legegyszerűbbtől a legbonyolultabb üzleti alkalmazásokig bármilyen felhasználói felületet átlátható. és lehetőséget adnak arra. A vezérlők kinézetét egy nagyszerű vezérlősablonrendszerrel. Az adatkötésirendszerrel és az adatsablonok használatával pedig rengeteg kódot megspórolva építhetünk dinamikus. kézre álló módon felépíthetünk. tökéletes választás a fejlesztés teljes életciklusának felügyeletéhez a kezdeti kódírástól a tesztelésig és a telepítésig. egységes módon. az is találhat néhány új dolgot (például az InputScopeok). A Silverlight UI-építést és -működést támogató részének másik része azoknak a szolgáltatásoknak a halmaza. ezért. hogy a korábbi UI-keretrendszerek által biztosított lehetőségeknél jóval több mindent tehessünk meg – sokkal kisebb erőfeszítéssel. illetve a keretrendszer UIhoz kapcsolódó szolgáltatásaiban. Aki a WP7-es Silverlight nagytestvérének használata során már találkozott az itt leírt típusokkal és koncepciókkal. könnyen használhatóvá teszik a vezérlőket. akár a teljes felület bizonyos helyzetekben felvett megjelenítését írhatjuk le központi. Ahogy a Silverlight „asztali” verziójában is. amelyekkel akár az egyes vezérlők. amelyek a felületek építéséhez elengedhetetlenek. ahogy látni is fogjuk. összetett felhasználói felületek (a továbbiakban UI – User Interface) kialakításának támogatása. 43 . viselkedést adjunk nekik –. Ennek a fejezetnek az első részében ezekkel az építőelemekkel ismerkedünk meg. a Windows Presentation Foundationt is azzal a céllal hozták létre. akár több már meglévő elem együttes használatával. Előbbiben értelemszerűen a vezérlőket találjuk. A fejezet során végig az Expression Blend 4 segítségével hozzuk létre és szabjuk testre a felületeket. akár őstípusokból való leszármaztatás és a vezérlő teljes funkcionalitásának megvalósítása segítségével. hogy kiterjesszük azokat – új tulajdonságokat. sok minden megegyezik az „asztali” Silverlighttal. Azonban a felületek kialakítása egyes esetekben eléggé fájdalmas tud lenni a VS használatával. Az itt ismertetett vezérlők használatán felül a vezérlők osztályhierarchiájának kialakítása lehetővé teszi. illetve stílusok segítségével változtathatjuk meg. áttekintő összefoglalást kíván adni. Többek között a VS ezen gyenge pontját ellensúlyozandó hozta létre a Microsoft az Expression termékcsaládot. Alkalmazásfejlesztés Windows Phone-on Az eredetileg RIA fejlesztésre kialakított Silverlight keretrendszer talán legfontosabb alapgondolata a gazdag tartalmú. izgalmassá.

Elindítása után egy nyitóképernyő fogad. A ListBox osztályon keresztül áttekintjük a listavezérlők általános használatát. Az egyszerűség kedvéért egyetlen alkalmazáson belül helyezzük el ezeket a vezérlőket. 3-2 ábra: Sablon kiválasztása 44 . illetve segítséget kérhetünk a program használatával kapcsolatban (Help fül). hogy milyen projektet szeretnénk létrehozni. amelyen létrehozhatunk új projektet vagy megnyithatunk egy már létezőt. a Close gombbal (Alt+C) bezárhatjuk az alkalmazást. érjük be a C#-pal). kifejezetten WP7-fejlesztésre kihegyezett verzióval. 3-1 ábra: Új projekt létrehozása Expression Blenddel A megjelenő ablakban választhatjuk ki. Alapvető WP7 vezérlők Ebben a részben először az alapvető parancskiadási vezérlőkkel foglalkozunk.1). majd áttérünk a szövegmegjelenítésre és a szövegbevitelre. a jobb oldalon pedig a Windows Phone Application projektsablont kell választanunk. A legtöbb programnál szokásos főmenü itt is elérhető. Hozzunk is létre egy alkalmazást a Blend 4 segítségével! Az Expression Blendet a Start Menü az All Programs menüpontban a Microsoft Expression mappában találjuk. Alul nevet adhatunk az alkalmazásnak (BaseControlsSample). illetve beállíthatjuk a Windows Phone verziót (7. A Samples fülön mintaalkalmazásokat tekinthetünk meg. amelyek részét képezik a WP7 fejlesztői csomagnak.3. Alkalmazásfejlesztés Windows Phone-on Megjegyzés: mind a Visual Studio 2010. amint azt a 3-2 ábra mutatja. kiválaszthatjuk a projekt fizikai helyét a merevlemezen. A bal oldali listából a Windows Phone pontot. A File menü New Project menüpontjára kattintva hozhatunk létre új projektet (3-1 ábra). mind az Expression Blend 4 rendelkezik ingyenes. illetve megadhatunk egyéb beállításokat. nyelvet választhatunk (főtt marha nincs.

a szövegvezérlők (keretes T betű).7720. annak ikonja a duplanyíl alatt jelenik meg. ahonnan egyéb. a toolboxon nem szereplő vezérlőket és egyéb felhasználható típusokat érhetünk el. Lejjebb. jobbra mutató nyíl. mint a Visual Studio. amelyeknél van ilyen nyíl. Erre kattintva érjük el az ún. Lejjebb. Azoknál az ikonoknál. néhány ikon jobb alsó sarkában egy kis nyilat vehetünk észre – ez azt jelenti.5-ösként reklámozott OS belső verziószáma 7. A tetején a kiválasztáshoz szükséges kurzorok foglalnak helyet (ezek használatával tudunk valamit közvetlenül a tervezőfelületre kattintással kiválasztani. A toolbox legalsó eleme jelen pillanatban egy dupla. Ha kiválasztunk valamit az Asset Library-ban. Ha közelebbről megnézzük. négy részre osztott négyzet ikon). hanem a C:\Users\<felhasználónév>\<dokumentumok>\Expression\Blend 4\Projects mappában! A választott 7. Ismerkedjünk meg a felülettel. hanem minden a felület kialakításával kapcsolatos eszközt tartalmaz. amelynek elemeit a 3-3 ábra mutatja be! 3-3 ábra: Az Expression Blend felületének részei 0: A menüsor 1: A toolbox (szerszámosláda) Ez jelentősen eltér aVisual Studióban megszokottól: nem egyszerűen a vezérlők listája.Alapvető WP7 vezérlők Tartsuk észben. A nagyító ikon segítségével nagyíthatunk a felület egy részére. Az OK gombra kattintva a Blend létrehozza a projektet.68. Asset Library-t. a harmadik csoportban találjuk a primitív vezérlőket szimbolizáló egyszerű négyszöget. 7. szerkeszteni). hogy nem egy eszközről van szó. illetve egyéb gyakran használt vezérlők (gomb ikon). hanem egy csoportról. hogy a Blend alapbeállításként nem ugyanabban a könyvtárban hozza létre a projekteket. a kéz ikonnal tudjuk egyszerűen görgetni a tervezőfelületet. Alatta találhatók az elrendezés-vezérlők (Grid.10.1-es OS verzió ne tévesszen meg senkit! A Mangóként ismert. a 45 .

Ahogy a 3-3 ábrán is látható. PasswordBox. hogy a keretes T betű. Ha úgy döntünk. a XAML-nézet és az osztott nézet között. Az elrendezési rendszerről és vezérlőkről szóló további információkért érdemes az alábbi linkről elindulni: http://msdn. hogy a teszteléshez az emulátort vagy egy fizikai eszközt szeretnénk-e használni. és itt iratkozhatunk fel az eseményekre. ami azt mutatja. egy LayoutRoot nevű elem a legfelső vezérlő. mellyel beállíthatjuk. hogy az itt kiválasztott vezérlőt tudjuk létrehozni. A Resources fülön találjuk az alkalmazás erőforrásainak listáját (ezekről később bővebben is szót ejtünk). amelyet használni szeretnénk. elrendezés-vezérlőre (layout control) lesz szükségünk. és rendszerezi. A States fülön találhatjuk meg és szerkeszthetjük a kiválasztott vezérlő vizuális állapotait – erről később szó lesz még. hogy éppen milyen elemet választottunk ki (a fenti képen Nothing Selected. itt nem térünk ki rá bővebben. RichTextBox. minimális helyigény alapján felsorakoztató StackPanel.com/en-us/library/cc645025(v=vs. és helyette a PasswordBox ikonja jelent meg.microsoft. azaz éppen semmi sincs kiválasztva). A tervezőfelület jelentős részét az oldal interaktív megjelenítő felülete foglalja el. hogy az animáció indulása utáni adott időpillanatban hogyan nézzen ki a felület.3. Alkalmazásfejlesztés Windows Phone-on jobb egérgombbal kattintva előhívhatjuk a helyi menüt. A Data fül alatt a projekt adatforrásai találhatók. „breadcrumb”. hogy ne csak egyetlen vezérlőt helyezhessünk el az oldalon. Ezen helyezhetjük el és méretezhetjük át a vezérlőket. mely a TextBlockot hivatott jelképezni. alatta pedig az ún. A megjelenítőtől jobbra. és azzal kiválaszthatjuk az eszközt. TextBox. és a vezérlőket egymás alá vagy egymás mellé.xaml). felül három ikont találhatunk. 4: A tervezőfelület Legfelül az éppen nyitva lévő fájlok listája látható (jelenleg csak a MainPage. hogy ez például egy gomb lesz. Az oldal tartalmaként mindössze egyetlen vezérlőelemet adhatunk meg. valamint referenciákat a külső szerelvényekre.95). pixel alapú pozicionálást lehetővé tevő Canvas.aspx 46 . Ennek annyi a jelentősége. Kattintsunk a PasswordBoxra (ezúttal a bal egérgombbal). ebben helyezhetjük el a tartalmat. mely a Silverlight felülettel kapcsolatos típusokat gyűjti össze. és látható. Egy sablon szerkesztése esetén itt láthatjuk a sablon felépítését. eltűnt. egy animáció vagy VisualState szerkesztésénél pedig itt jelenik meg az idővonalat (timeline) ábrázoló ablak. a Silverlight Toolkit használata nélkül háromféle elrendezés-vezérlő áll rendelkezésre a Windows Phone 7-ben: a táblázatos elrendezést lehetővé tévő Grid. Ezek a vezérlők azt teszik lehetővé. a Windows Formsból (vagy korábbról) már ismerős. 5: Tulajdonságok és adatok A Properties fülön állíthatjuk be a kiválasztott vezérlő tulajdonságait. Kattintsunk a jobb gombbal például a keretes T betűre (szövegvezérlők)! Az ikon mellett megjelenő lista négy eleme: TextBlock. ezek segítségével válthatunk a tervezési nézet. Alapesetben. Második füle az Assets. akkor a gomb kitölti majd a teljes oldal felületét – leszámítva az ApplicationBar és az ún. 2: A fejlesztési ablak Legelső füle (a sorrend megváltoztatható) a Projects. system tray által elfoglalt részeket. hogy több gyermekvezérlőt is elrendezhessünk az elrendezés-vezérlő által lefoglalt területen. A Device fül segítségével pedig az alkalmazásainkat futtató emulátor orientációját és témáját állíthatjuk be. ami a VS Solution Explorerének helyi verziója: ebben találjuk meg a projektet alkotó összes fájlt és könyvtárat. illetve itt adhatjuk meg azt is. illetve itt hozhatunk létre teszteléshez használt adatforrást. Ahhoz. Mivel az elrendezés futásidejű működése megegyezik az „asztali” Silverlightéval. ha a tervezőfelületen kijelöljük az új vezérlő helyét. 3: Objects and Timeline Alapesetben itt láthatjuk az alkalmazásunk egy oldalának (PhoneApplicationPage) vizuális hierarchiáját.

láthatjuk ennek gyökérelemét. meg kell adnunk a ContentPanelnak. hogy egy nem megfelelő típusú elrendezés-vezérlőt helyeztünk el a felületen. érdemes madártávlatból is szemügyre venni a Properties panelt! Ahogyan azt a 3-5 ábra mutatja. Mindezek alatt pedig a keresődoboz helyezkedik el. hogy az alkalmazás illeszkedjen a sok másik által kialakított jól felismerhető sémába. A név mellett találjuk a tulajdonságok és az események között váltó két gombot. hogy valaki ténylegesen egyetlen vezérlőt akarjon elhelyezni alkalmazása felületén. Ez az egyetlen tartalma az oldalunknak. illetve az alatta lévő oldalnevet („page name”). Mivel több vezérlőt is szeretnénk elhelyezni az alkalmazáson – pontosabban a ContentPanelen – belül. de a struktúrához nem kell hozzányúlnunk. illetve mert a Silverlight vezérlői tényleg nagyon sok tulajdonsággal rendelkeznek. hogy a vezérlőkre kattintgatva az Objects and Timeline panelen (vagy valamelyik nyíl alakú kurzorral magán a tervezőfelületen). Érdemes ezt használnunk. Az Objects and Timeline ablakban kattintsunk jobbal a lecserélni kívánt vezérlőre. 3-4 ábra: Az Objects and Timeline panel A TitlePanel nevű gyermekelem egy StackPanel. Ha nincs különleges igényünk. a LayoutRoot nevű vezérlőt. a jobb oldalon lévő Properties panel tartalma azonnal frissül. Ahogy az a 3-4 ábrán látható. hogy a „<No Name>” felirat szerepel ebben a szövegdobozban. Mielőtt azonban elvesznénk a millió tulajdonság között. A ContentPanel nevű gyermekelem a leginkább érdekes rész: ebben a Gridben helyezhetjük el a tényleges tartalmat adó és funkciót szolgáló vezérlőket. a Silverlight Phone Application projektsablon rögtön egy teljes vizuális hierarchiát épít fel a felületen. alatta pedig a kijelölt elem típusát. Ha az Objects and Timeline ablakra nézünk. Ezt úgy tehetjük meg. nem kell XAML-t túrni a cseréhez. mivel a szűrés kellőképpen intelligens (nemcsak a tulajdonságok nevének kezdete alapján szűrhetünk). Bár a kezdeti időkben nem túl gyakran kerülnek elő. amely az alkalmazás felső részét írja le: az alkalmazás nevét („MY APPLICATION”) tartalmazó TextBlockot. esetleg szeretnénk. legfelül a kijelölt objektum nevét láthatjuk – ezzel a névvel hivatkozhatunk a vezérlőre a mögöttes kódban. illetve egyéb helyeken a XAML-ben. hogy hány oszlopból és sorból álljon. hogy a vezérlőktől jobbra látható két piktogrammal tudunk eltüntetni egy-egy vezérlőt a tervezőfelületről. majd a Properties panelen megkeressük annak RowDefinitions illetve ColumnDefinitions tulajdonságait. azaz védeni a véletlen módosításoktól. Észrevehetjük. amely történetesen egy Grid. érdemes tudni. hogy itt ennél bonyolultabb struktúrának kell lennie – a LayoutRoottól balra lévő apró nyílra kattintva megtekinthetjük a Grid belsejében lévő felületi elemeket is. hogy kijelöljük azt. Előfordulhat.Alapvető WP7 vezérlők Tipp: ha utólag rájövünk. és válasszuk ki a Change Layout Type pont alatt a megfelelő típust! Mivel viszonylag ritka az a helyzet. illetve zárolni. 47 . ugyanis a Silverlightban nem feltétlenül kell egy vezérlőnek nevet adni. ha megváltoztatjuk a két TextBlock tartalmát. a LayoutRoot két elemet tartalmaz. A tervezőfelületre pillantva érezhető. akkor elég.

ha hozzáadunk a RowDefinitions és a ColumnDefinitions tulajdonságokhoz két oszlopot és három sort. Visszatérve a ContentPanelre.3. hat egyforma cellára bontják a felületet. (Az adatkötésről és az erőforrásokról a későbbiekben lesz szó. ezzel érhetjük el a ritkábban használt tulajdonságokat. akkor a tulajdonság az alapértelmezett értékén áll. A másik. valamilyen adatkötésből kapja az értékét. 3-6 ábra: Hat egyforma cellára bontott ContentPanel Grid Ennyi áttekintés után vegyük sorra azt a néhány alapvető vezérlőt. hogy sok tulajdonságtól jobbra egy kis négyzet található. akkor kézzel állították be valamilyen értékre. ha sárga. ahogyan azt a 3-6 ábra mutatja. látható. amelyek nélkül nincs élet a Silverlightban! 48 . Ez nemcsak dizájnelem. ha fehér. Az egyik.) A gomb színe is jelentőséggel bír: ha szürke. illetve egyebek mellett alapértelmezett értékre is visszaállíthatjuk a tulajdonságot. amelyeket elsőre könnyű nem észrevenni. és így tovább. hogy a csoportok alján található egy lefelé mutató nyíl. Alkalmazásfejlesztés Windows Phone-on 3-5 ábra – A Properties panel A keresődoboz alatt találjuk a tulajdonságokat – értékeikkel egyetemben — csoportokra osztva. Itt két dologról is érdemes szót ejteni. hanem funkcióval is bír! Az Advanced options „gomb” segítségével hozhatunk létre adatkötést (esetleg erőforráshoz kötést) az adott tulajdonság kapcsán. hogy a tervezőfelületen is megjelennek a cellák határoló vonalai.

hogy alapbeállításként a Blend a Margin tulajdonság segítségével méretezi a vezérlőt. majd a pluszjel formájúra változott kurzorral megrajzoljuk a felületen. melyet az Objects and Timeline ablakban kijelöltünk. hogy a felhasználó rákattinthat (illetve. 49 . A Properties panelen a Content tulajdonság melletti szövegdobozban írhatjuk át a gomb feliratát. amit szokás átállítani egy gombon. hogy pontosan melyik elrendezés vezérlőbe. hogy ha túl hosszú feliratot rendelünk a gombhoz. rátapinthat). ahogyan azt a 3-8 ábra is mutatja: 3-8 ábra: A Button Content tulajdonságának átállítása a Properties panelen Észrevehetjük. hogy egyszer kattintunk az ikonjára. 3-7 ábra: A Buttont jelölő gomb a Toolboxon Vezérlőt úgy is létrehozhatunk.Object típusú. Ennek oka. a tervezőfelületen nem jelenik meg a teljes szöveg. ez a tulajdonság viszont System. hogy rögtön meghatározhatjuk a vezérlő pontos pozícióját. mivel érintőképernyős eszközről beszélünk: megérintheti. hogy egyetlen tartalmat tudnak fogadni – Content tulajdonságukon keresztül –. vagyis meghatározza. Az első. Canvas használata esetén viszont ez a módszer nagyon hasznos. annak felirata. egy Grid esetén melyik cellá(k)ba is akartuk helyezni az új vezérlőt. A Button a ContentControl ősosztályból származik. A ContentControlból származó vezérlők közös ismérve. megjelenik egy gomb az alkalmazás felületén. Ennek a módszernek többek között az az előnye. illetve méretét. tehát bármilyen objektumot felvehet értékéül. hogy a tartalmazó vezérlő (a ContentPanel nevű Grid [0.0] cellája) széleitől mekkora távolságot tartson a vezérlő (3-9 ábra).Alapvető WP7 vezérlők Parancsvezérlők A Button vezérlő használata A Toolboxon duplán a Button ikonjára kattintva (3-7 ábra). Alapértelmezés szerint abban a vezérlőben jelenik meg az új elem. hogy egy összetettebb vizuális hierarchiában a Blend néha eltéveszti. A Button az elsődleges parancsvezérlő: funkciója általában mindössze annyi. és ennek hatására lefuttathatunk egy eseménykezelő metódust a mögöttes kódban. Hátránya viszont.

Itt kapcsolhatjuk azt a kódot a felülethez.3. 3-12 ábra: A Properties panel átkapcsolása esemény-nézetbe Ahogy elkészül a metódus – melynek neve meg is jelent a Click mellett –. a Blend átvált az aktuális oldal mögöttes kódjára. Alapértelmezés szerint nem kell. Alkalmazásfejlesztés Windows Phone-on 3-9 ábra: A túl kicsi gomb és a Margin esete Ha az Advanced options segítségével alaphelyzetbe állítjuk a Margint (3-10 ábra). viszont ha hivatkozni szeretnénk rájuk a mögöttes kódban. a Button Click eseményéhez kell hozzárendelnünk egy eseménykezelő metódust. hogy nevet kapjanak a vezérlők. Marginok nélkül Azt is észrevehetjük. amellyel megvalósíthatjuk az elvárt működést. 50 . 3-10 ábra: A Margin alaphelyzetbe állítása az Advanced options Reset parancsának segítségével 3-11 ábra: Gomb. amikor a felhasználó megnyomja a gombot. hogy gombunk még nem rendelkezik névvel. A Properties panel tetején válthatunk át eseménynézetbe.) Ahhoz. széltében kitölti a cellát (3-11 ábra). a gomb szélesebb lesz. akkor érdemes nevet adni nekik. (Esetünkben ez btnOne lesz. és itt a Click felirat melletti szövegdobozba való dupla kattintással készíttethetjük el az eseménykezelőt a Blenddel (3-12 ábra). hogy valamilyen kód lefusson.

Josh Smith WPF-guru cikke az MVVM-ről WPF alatt itt található: http://msdn.Windows.org/wiki/Model_View_ViewModel linken található.com/en-us/magazine/dd419663. aztán annak aktuális értékét megjeleníti a gombon.Content = taps.RoutedEventArgs e) { taps++. illetve több keretrendszer is létezik implementálására.silverlight. Ennek leírása túlmutat e könyv határain. vagy a PC-hez csatlakoztatott telefonra telepíti az alkalmazást. majd az előbb elkészült eseménykezelőben megnövelem az értékét. és átadom a gombnak mint tartalmat. } private void btnOne_Click(object sender.wikipedia.net/learn/advanced-techniques/the-mvvm-pattern/using-the-mvvm-pattern-insilverlight-applications. A teljes kód – leszámítva a using direktívákat – így néz ki: namespace BaseControlsSample { public partial class MainPage : PhoneApplicationPage { int taps = 0. public MainPage() { InitializeComponent(). Ebben az MVVM (Model-View-ViewModel) alkalmazásfejlesztési minta lehet segítségünkre. Ehhez először létrehozok egy System. vagy kiválaszthatjuk a Project menüből a Run Project menüpontot. A Devices panel beállításai szerint a Blend vagy a WP7 emulátort indítja el. Ahogy az alkalmazás elindult. a gombot nyomogatva növekszik az érték (3-13 ábra). Az ismertebb MVVM-keretrendszerek leírása a http://en. btnOne.Alapvető WP7 vezérlők A bonyolultabb programoknál érdemes szeparálni a felület mögötti logikát és a tényleges üzleti logikát. } } } Az alkalmazás futtatásához vagy megnyomjuk az F5 billentyűt.microsoft. Egy önállóan megírható alkalmazás elkészítésének leírása Silverlight MVVM-mel itt van részletesen leírva: http://www. növel egy számlálót.aspx. (Az Open source MVVM frameworks c. hogy amikor megnyomják. System. rész alatti linkeket érdemes megnézni. 3-13 ábra: A program az emulátoron futtatva 51 .Int32 típusú változót az oldal mögöttes kódjában.) Itt annyit fog tenni a gomb.

ahogyan azt a 3-14 ábra mutatja. és a HyperlinkButton megkeresése A Toolbox új elemére duplán kattintva megjelenik egy HyperlinkButton a felületen. 3-15 ábra: A HyperlinkButton elhelyezése a felületen Akárcsak a Button. Alkalmazásfejlesztés Windows Phone-on Nem telepíthetünk minden telefonra alkalmazásokat a Marketplace megkerülésével.msdn. fejlesztői telefonná tesszük az eszközt. A HyperlinkButton vezérlő használata A HyperlinkButton vezérlő a webes hivatkozások megfelelőjének tekinthető. Tulajdonképpen működése nem sokban különbözik a Buttonétól: valami. A Toolbox alján lévő dupla nyílra kattintva megjelenik a fent nevezett ablak. de az Advanced options négyzetre kattintva kiválaszthatjuk a Custom Expression menüpontot. ezért az Asset Library segítségével kell előkeríteni. de beírhatunk egy webcímet is. ahová navigálni szeretnénk. amelyet aztán a kurzor segítségével elhelyezhetünk (3-15 ábra).com/) Windows Phone fejlesztőként. hogy a navigáció működjön. Közvetlenül ezt nem tehetjük meg.) Ahhoz.hu. ez a vezérlő is a ContentControlból származik.3. Be kell regisztrálnunk magunkat az App Hubon (http://create. a keresődoboz segítségével gyorsan megtalálható a HyperlinkButton vezérlő. Szintén a Properties Panel Common Properties csoportjában található a NavigateUri tulajdonság. tehát pl. (Protokollal együtt kell megadni. ezután arra a Marketplace megkerülésével is telepíthető alkalmazás. Alapértelmezésként itt az alkalmazásban lévő PhoneApplicationPage-eket látjuk.: http://devportal. ami kattintás hatására végrehajtja a hozzárendelt kódot. 52 . be kell állítanunk a TargetName tulajdonságot is „_blank”-re. Ennek segítségével állítható be az oldal. Ezzel feloldjuk a zárolást. A HyperlinkButton alapértelmezésben nem található meg a Toolboxban. tartalmát a Content tulajdonsággal szabályozhatjuk. amellyel szabadon szerkeszthető az érték (3-16 ábra). amely ezután egy kattintással helyezhető el a Toolboxon. és megadni telefonunk gyári azonosítóját. 3-14 ábra: Az Assets panel megnyitása.

és megérintjük a linket. köztes állapotba kerülés esetén) és Unchecked (bejelölés törlése esetén) eseményekre iratkozhatunk fel. akkor a Buttonnál látott módon feliratkozhatunk a Click eseményre. hogy a felhasználó utólag visszaállíthassa köztes állapotba. és betöltődik a NavigateUri-ban megadott webcím. határozatlan (indeterminate) állapotot is. azaz jelölőnégyzet. a felhasználó már nem állíthatja vissza köztes állapotba. Ha az IsThreeState tulajdonság igaz (true) értékű. hogy a jelölőnégyzet kétállapotú legyen. Ez hasznos lehet. vagy felvehessen-e egy harmadik. hogy szabályozza a program működését. RoutedEventArgs e) { MessageBox. mert például azt dinamikusan szeretnénk előállítani. Előbbi megmondja. deklaratívan megadjuk a navigáció címét. A Toolboxon ugyanabban a menüben található. engedélyezzen vagy letiltson valamilyen opciót. ha például nem akarjuk. amikor a jelölőnégyzet állapota megváltozik. A CheckBox felirata.Alapvető WP7 vezérlők 3-16 ábra: A NavigateUri és a TargetName beállítása Ha ezek után elindítjuk a programot. és a mögöttes kódban tetszőleges kódot végrehajthatunk. ahol a Button. hogy melyik állapotba kellene állítani alapértelmezetten a jelölőnégyzetet. a legjobb választás a CheckBox.Show("Herbert Garrison"). A CheckBox használata Ha szeretnénk felkínálni a lehetőséget a felhasználónak. Ha szeretnénk valamilyen kódot futtatni. Legfontosabb tulajdonságai az IsChecked és az IsThreeState. ugyanakkor nem szeretnénk azt sem. a Content tulajdonságon keresztül változtatható meg. megnyílik az Internet Explorer. a Checked (bejelölés esetén). ahogy a már bemutatott vezérlőknél is. Ha nem elég. hogy a jelölőnégyzetet bejelölték-e. hogy így. vagy nem tudjuk előre megmondani. 3-17 ábra: A CheckBox beállítása private void cbGenderIsMale_Checked(object sender. } 53 . Indeterminate (eldöntetlen. Ha hamis (false) értékű. akkor is felveheti a harmadik állapotot. de csak programozottan. Utóbbival azt szabályozhatjuk. a jelölőnégyzet három állapotot vehet fel.

hogy ha az rbIncrement választógombot jelöli be a felhasználó. private void btnOne_Click(object sender. növeli az értéket. Checked.Show("Sheila Broflovski"). Az alábbi példában a korábban elkészített Button eseménykezelőjét módosítjuk úgy. A mögöttes kódban a RadioButtonök IsChecked tulajdonságát figyelembe véve írhatjuk meg a program logikáját. Ezért kell előbb Booleanné alakítani. GroupName tulajdonságuk segítségével csoportosíthatjuk őket. ha a felhasználó több lehetőségből egyet választhatna. System. úgy. hogy minden csoportban kölcsönösen kizárják egymást a lehetőségek.Windows. Unchecked. azaz a true és false értékén kívül null értéket is felvehet. IsChecked. de a különböző csoportokban lévők között már ne legyen kapcsolat. Ilyen esetekben használhatjuk a RadioButtont (rádiógomb). else taps--.RoutedEventArgs e) { if ((bool)rbIncrement.Show("Liane Cartman"). Alkalmazásfejlesztés Windows Phone-on private void cbGenderIsMale_Unchecked(object sender. RoutedEventArgs e) { MessageBox.Content = taps. btnOne. RoutedEventArgs e) { MessageBox. 3-18 ábra: A RadioButton tulajdonságainak beállítása Ha több csoportba szeretnénk rendezni a rádiógombokat. Előfordul azonban.vagy bekapcsolását adhatjuk a felhasználó kezébe. IsThreeState. Indeterminate). 54 . hogy azt szeretnénk. } Mind a CheckBox. } private void cbGenderIsMale_Indeterminate(object sender. csökkenti azt (3-19 ábra). ha pedig nem. A RadioButton legfontosabb tulajdonságai és eseményei nevükben és működésükben is megegyeznek a CheckBoxnál látottakéval (Content.3. hogy true/false-ként vizsgálhassuk az értékét. } A RadioButton használata A CheckBox vezérlőkkel egyes lehetőségek egymástól független ki. mind a RadioButton IsChecked tulajdonsága Nullable<Boolean> típusú.IsChecked) taps++.

dőlt. a betűk méretét. bonyolultabban formázott megjelenítésre pedig a RichTextBoxot. Egyszerű szövegmegjelenítés a TextBlockkal Ahogy korábban láttuk. Vegyük szemre a PageTitle nevűt! A TextBlock által megjelenített szöveget a Text tulajdonság segítségével adhatjuk meg (3-20 ábra). amelynek nem kell szöveget megjelenítenie.Alapvető WP7 vezérlők 3-19 ábra: Parancsvezérlők a felületen Szövegmegjelenítési vezérlők Nagyon kevés olyan program van. aláhúzott) betűformázási lehetőségeket is megkapjuk (3-21 ábra). a Windows Phone Application sablon rögtön két TextBlockot is beépít alkalmazásunk felületébe. Egyebek között átállíthatjuk a betűtípust. A Silverlightban erre elsősorban két vezérlőt használunk: egyszerű szövegmegjelenítésre a TextBlockot. 55 . 3-20 ábra: A TextBlock szövegének beállítása A Text csoportban található tulajdonságok segítségével szabhatjuk testre a szöveg kinézetét. illetve a szokásos (félkövér.

3-22 ábra: Túl hosszú szöveg Két dolgot tehetünk.3. Ilyenkor alapértelmezésként egyszerűen „kicsúszik”. Ennek hatására a TextBlock több sorban próbálja meg elhelyezni a szöveget. hogy kiküszöböljük ezt a problémát. Amikor egy szó már nem fér ki. 3-23 ábra: Túl hosszú szöveg TextTrimminggel kezelve A másik lehetőség. Ennek eredményeképpen. Az első. hogy a TextWrapping tulajdonságot Wrap értékre állítjuk. hogy a szöveg túl hosszú. és nem fér ki a TextBlock rendelkezésére álló helyen. és három ponttal helyettesíti őket (3-23 ábra). amelyek már nem férnek ki. Alkalmazásfejlesztés Windows Phone-on 3-21 ábra: A TextBlock szövegének tulajdonságai Előfordulhat. amikor a TextBlock túl sok szöveget tartalmaz. a következő sorba kerül (3-24 ábra). 3-24 ábra: Túl hosszú szöveg TextWrappinggel kezelve 56 . hogy túl sok szöveg kerüljön egy TextBlockba. levágja azokat a szavakat. vagyis a vége nem jelenik meg (3-22 ábra). hogy a TextTrimming tulajdonságot None értékről WordEllipsis értékűre állítjuk. de erre nem mindig van lehetőség. Általában érdemes elkerülni.

Amint elhelyezünk egyet a felületen. csupán arra ad lehetőséget. ahol egyszerre látjuk a tervezőfelületet. képek stb. és a XAML-t. 3-25 ábra: Többféleképpen formázott szöveg egy RichTextBoxban A RichTextBoxot a szövegvezérlők csoportjában találjuk a Toolboxon. hanem akár karakterenként mást és mást (3-25 ábra). Sajnos erre a tervezőfelületen belül nincs lehetőség. rögtön hivatkozást is befűzhetünk a szövegbe. Sőt. hogy a TextBlockkal ellentétben nem csupán egyféle formázást adhatunk az egész szövegnek. A szöveg bármely része kijelölhető. a legalsóval válthatunk osztott nézetbe. Amellett. milyen linket kell megnyitni. 57 . a helyzet azonban — legalább is jelen pillanatban — nem ez. A RichTextBox WP7-es implementációja nem teszi lehetővé szöveg bevitelét vagy szerkesztését a felhasználó számára. és átállíthatóak jellemzői. 3-26 ábra: A szöveg egy részének kijelölése. hogy a hivatkozás tudja.Alapvető WP7 vezérlők Formázott szövegek megjelenítése a RichTextBoxszal A RichTextBox neve azt sugallja. A tervezőfelület jobb felső sarkában találjuk a nézetváltó ikonokat (3-28 ábra). hogy egy szövegbeviteli vezérlőről lehet szó. hogy programozottan töltsük fel szöveggel. itt is meg kell adnunk a TargetName tulajdonságot. kézzel kell beleírni a XAML-be. hogy az egyszerű szövegeknél bonyolultabb elemeket is meg tud jeleníteni. tartalma rögtön szerkeszthetővé is válik (3-26 ábra). hogy hivatkozássá alakítsuk 3-27 ábra – A Create Hyperlink gomb és ablak Ahogy korábban a HyperlinkButton esetén. a RichTextBox igazi előnye. ha a Text csoportban lévő földgömb gombra kattintunk (3-27 ábra). – a vezérlőt. illetve egyéb elemekkel – hivatkozások.

megnyílik az Internet Explorerben a megadott weblap. hogy ne csak a felkínált lehetőségek közül választhasson. amit a program fel tud dolgozni. és TargetName tulajdonságának a „_blank” értéket kell adni. de legáltalánosabb adatbeviteli vezérlő mindig is a TextBox marad. hogy megkönnyíthessék a felhasználói adatbevitelt. vagy éppen választhat lehetőségek közül. 3-29 ábra – Osztott nézetben egyszerre látjuk a tervezőfelületet és a hozzá tartozó XAML-t Szövegbeviteli vezérlők Szövegeket kiírni már tudunk. A Silverlight számos speciálisabb vezérlőt kínál a fejlesztőknek.3. De gyorsan szembe kerülünk azzal az igénnyel. és a felhasználó különböző parancsokat futtathat. Ha ezek után fut az alkalmazás. a link már jól fog működni – ha megérintik. hanem ő maga adhasson meg valamilyen bemenetet. Alkalmazásfejlesztés Windows Phone-on 3-28 ábra: A tervezőfelület jobb felső sarkában található nézetváltó gombok A XAML-ben meg kell keresni a Hyperlink elemet. 58 .

a MaxLength csak a felhasználói adatbevitelt szabályozza. ahogy a két előző vezérlőnket is a szövegvezérlők csoportjában találjuk a Toolboxon (3-30 ábra). hogy legfeljebb hány karaktert írhasson be a felhasználó a szövegdobozba.Alapvető WP7 vezérlők Szövegbevitel a TextBoxszal A TextBox. illetve kódból itt állíthatjuk be a szövegdoboz szövegét. 3-31 ábra A TextBox tulajdonságainak beállítása a Properties panelen 59 . Az IsReadOnly tulajdonságával tehetjük csak olvashatóvá a szövegdobozt – ilyenkor a felhasználó nem állíthatja át a beleírt szöveget. A MaxLength tulajdonsággal megszabhatjuk. a Toolboxon Nem meglepő módon a TextBox vezérlő Text tulajdonságán keresztül érhetjük el. 3-30 ábra – A TextBox helye a szövegvezérlők között. avagy szövegdoboz segítségével a felhasználó a telefon virtuális vagy fizikai billentyűzete segítségével adatokat vihet be az alkalmazásba. Programozottan ennél többet is meg lehet adni. A TextBoxot.

Text. Ha például tudjuk. private void tbTitle_TextChanged(object sender. } 3-32 ábra: Adatbevitel a TextBoxon keresztül A virtuális billentyűzet beállítása Egy néhány colos billentyűzeten gépelni sosem lesz annyira kényelmes és gyors. mint egy teljes értékű és méretű fizikai billentyűzeten tenni ugyanezt. hogy esetleg megakadályozzuk a felhasználót érvénytelen adatok bevitelében.Text = tbTitle. illetve. az oldal címe automatikusan frissül. TextChangedEventArgs e) { PageTitle. Ahogy gépel. hogy a felhasználó egy szövegdobozba csak számokat fog gépelni. elkaphatjuk a TextChanged eseményt. hogy néhány kattintással pontosan beállíthassuk a TextBox vezérlők virtuális billentyűzetét.3. Ezt az InputScope tulajdonsággal tehetjük meg (3-33 ábra). Az alábbi kódrészlet segítségével a felhasználó írhatja be az oldal címét – a korábban meghatározott MaxLength miatt legfeljebb 10 karakterben. a Silverlight for Windows Phone 7 lehetővé teszi. 60 . miért nehezítsük meg a dolgát egy teljes billentyűzettel? Elég lenne a számbillentyűket megjeleníteni! Éppen ezért. Alkalmazásfejlesztés Windows Phone-on Amikor a TextBox szövege megváltozik.

NameValue= InputScopeNameValue. 3-34 ábra: Number InputScope-úra beállított TextBox Ugyanezt természetesen kódból is beállíthatjuk. insName.Alapvető WP7 vezérlők 3-33 ábra: Az InputScope kiválasztása egy TextBoxnál Ha például a Number beállítást választjuk.InputScope = ins.Add(insName). ins. 61 . InputScopeName insName = new InputScopeName().Number. így akár futás közben is változtatható egy TextBoxhoz rendelt billentyűzet: InputScope ins = new InputScope(). tbTitle. a felhasználó csak számokat tud majd beírni ebbe a szövegdobozba (3-34 ábra).Names.

Mi a helyzet. mely egy speciális TextBox. a Toolboxon az általános vezérlők között találjuk (3-36 ábra).aspx Jelszavak bevitele a PasswordBoxon keresztül Ha alkalmazásunk vagy egy hozzá kapcsolódó webes szolgáltatás jelszavas azonosítást igényel. Ez történhet egy normál TextBoxon keresztül is. amelyekkel eddig foglalkoztunk. a PasswordChar tulajdonsággal pedig az alapértelmezett pöttyöt cserélhetjük le egy nekünk tetsző helyettesítő karakterre.3. A ListBox használata A ListBox talán a legalapvetőbb elemvezérlő. Ezekben közös. erre a későbbiekben még kitérünk.input. hogy a jelszó utólag visszaolvasható legyen. saját objektumot. ezzel megakadályozva. hogy rendelkeznek egy Items nevű tulajdonsággal. Listavezérlők A vezérlők. (Azt most ne firtassuk. Alkalmazásfejlesztés Windows Phone-on Az InputScope rengeteg lehetséges értéket felvehet. 62 . más vezérlőknél pedig a Text vagy Password tulajdonságban megadott egyszerű szöveg.com/enus/library/system. mely megpróbálja azokat legjobb tudása szerint megjeleníteni. A PasswordBox is a szövegvezérlők csoportban található (3-35 ábra).microsoft. Miután a felhasználó beírt egy karaktert. mely objektumok listája. Az alábbi linken mindegyikről találhatunk egy rövid leírást: http://msdn.inputscopenamevalue(v=vs. legalább egyszer a jelszót is be kell kérni a felhasználótól. hogy elkerülhetetlenül a felhasználó fülébe szuszog!) Ilyen esetekre a megfelelő megoldás a PasswordBox használata.95). hogy ehhez olyan közel kell állnia. lelesheti a jelszót a kijelzőről. Ezen keresztül adhatunk hozzá elemeket a listavezérlőhöz.windows. Bizonyos vezérlőknél ez a Content tulajdonságon keresztül megadott objektum. aztán egy pöttyre cseréli le a PasswordBox. hogy bárki. egyetlen tartalmat tudtak megjeleníteni. 3-35 ábra: A PasswordBox kiválasztása a Toolboxról A Password tulajdonságon keresztül érhető el a beírt jelszó. A megjelenítés testreszabható. bármit) szeretnénk megjeleníteni. ha nem egy elemet (szöveget. az még egy másodpercig látszik. aki éppen a felhasználó mögött áll. azonban ennek az a hátránya. hanem több azonos típusú elemet? Erre a problémára szolgáltatnak megoldást a listavezérlők.

a -1 azt jelenti.) 3-37 ábra: A Todo-lista program kinézete A ListBox kijelölése után a Properties panelen szétnézve ismét a Common Properties csoport rejti a leggyakrabban használt tulajdonságokat. Az Items listán keresztül adhatunk elemeket a ListBoxhoz. (3-38 ábra) 63 . Mindössze annyit tud. hogy több elem is kijelölhető legyen-e. végletekig egyszerűsített tennivaló-listát valósítjuk meg.Alapvető WP7 vezérlők 3-36 ábra: A ListBox kiválasztása a Toolboxról A működés megértéséhez a 3-37 ábrán látható. a SelectionMode-dal pedig megadhatjuk. A SelectedIndex segítségével állíthatjuk be. nincs kijelölt elem. hogy a TextBoxba írt szövegeket a gomb megnyomásával a ListBoxhoz rendeli. A számozás 0-tól indul. hogy hányadik elem legyen alapértelmezetten kijelölve. (Az elemek törlése már feláras funkció.

Az egyes elemek sorrendjét az ablak alján lévő nyilakkal változtathatjuk meg. melyben szerkeszthetjük a ListBox tartalmát. Az „Add another item” gombra kattintva kiválaszthatjuk a ListBoxhoz hozzáadni kívánt elem típusát. Egy stringet hozzáadva (az mscorlib|Systemben találjuk) a szerkesztőablak jobb oldalán megjelenik a karakterlánc.3. illetve az „X” gombbal törölhetünk egy elemet (3-39 ábra). 3-39 ábra: Stringek hozzáadása a ListBox tartalmához A gomb Click eseményére felírt eseménykezelővel hozzáadhatjuk a felhasználó által megadott új elemet: 64 . amit átírhatunk. az Object Collection Editor ablak jelenik meg. Alkalmazásfejlesztés Windows Phone-on 3-38 ábra: A ListBox tulajdonságainak beállítása a Properties panelen Ha az Items melletti „…” gombra kattintunk.

Text)) lbxTodo. típusos listába rakni őket. ha később szerettük volna feldolgozni azokat. Adatkötés Az előző példákban szerepeltek olyan kódrészletek. Az alábbi kód egy MessageBoxban jeleníti meg a felhasználó által kiválasztott elemet: private void lbxTodo_SelectionChanged(object sender. és ennek a listának a tartalmát megjeleníteni. Erőforrások Vannak olyan értékek (számok. és aztán az adott oldalon vagy az egész programban újra és újra felhasználni.Add(tbNewItem. anélkül. A gomb megnyomásának hatására lefutó eseménykezelő nemcsak megnövelt egy értéket. szövegek). holott. Az adatkötés segítségével különböző objektumokat. vezérlőket tarthatunk automatikusan szinkronban. SelectionChangedEventArgs e) { MessageBox. másrészt pedig szinkronban tartja az összes olyan objektumot. tbNewItem. Ha valami megváltozik az egyik helyen. A XAML-ben mélyen be van ágyazva az adatkötés technológiája. hogy ehhez bármilyen kódot kellene írnunk. mely felhasználja az erőforrást. Ez egyrészről a memóriafoglalást is csökkenti.Items. A SelectedItem tulajdonságon keresztül érjük el a kiválasztott elemet (ha több is van.Show(lbxTodo. érdemesebb lett volna egy háttérben lévő. a kijelölt elem a telefonon beállított „accent” színnel jelenik meg. Érdemes lenne tehát egyszer létrehozni őket. amikor megváltozik a kijelölt elem. amelyeket nem csak egy helyen szeretnénk felhasználni egy programban.Empty. megjelenítsék rajta az új. amelyek pusztán arra szolgáltak. amelybe közvetlenül helyeztük bele az elemeket. megváltozott adatokat.Adatkötés private void btnAddItem_Click(object sender. A TextBoxba írt szöveg megváltozásakor lefutó TextChanged esemény minden karakter leütése után frissítette az oldal címét. hogy frissítsék a felületet.ToString()). Könnyebb lesz 65 . } 3-40 ábra: Az alkalmazás működés közben Ahogy a 3-40 ábrán is látható. a változás azonnal megjelenik a másik helyen is. } A ListBox SelectionChanged eseménye akkor következik be.Text). objektumok. Ezen kívül pedig ott volt még a ListBox. a SelectedItemsen keresztül kapjuk meg mindet). RoutedEventArgs e) { if (!string.SelectedItem. hanem utána explicit módon ki is írta a számot a gombra.IsNullOrWhiteSpace(tbNewItem.Text = string.

XAML-ben is megadhatjuk őket. Alkalmazásfejlesztés Windows Phone-on megtartani a program konzisztenciáját. melynek egyik eleme a „Convert to New Resource…” névre hallgat (3-41 ábra). hogy hol lesz látható: előbbi esetben csak az aktuális oldalon belül. Alkalmazásaink címe például nem változik. A megjelenő párbeszédablakban beállíthatjuk az erőforrás nevét (Name). A harmadik lehetőség. és ha több ablakból áll egy alkalmazás. Így még jobban elválasztható a felület leírása a kódban megírt logikától. ha a változtatás igénye esetén csak egy helyen kell frissíteni egy adott objektumot. hogy hol kerüljön definiálásra az erőforrás: az oldalon vagy az alkalmazás szintjén. utóbbinál viszont ha vannak más oldalaink. Az erőforráskönyvtárak különálló XAML-fájlok. illetve meghatározhatjuk. azokban is elérhető lesz. amit éppen a Text tulajdonság tartalmaz. hogy egy erőforráskönyvtárban (resource dictionary) hozzuk létre. Ezeket a közös használatú objektumokat definiálhatjuk kódban. Az ApplicationTitle TextBlockot a Properties panelen kiválasztva a Text tulajdonság mellett található Advanced options gombra kattintva megjelenik a menü. 3-42 ábra: Az erőforrás nevének és tárolási helyének beállítása 66 . hogy gyakran magához a felülethez köthetők (például egy-egy vezérlő háttérszínét meghatározó Brush). de tekintve. valószínűleg mindegyik ablakban szeretnénk majd felhasználni azt.3. Ez meghatározza azt is. 3-41 ábra: Erőforrás létrehozása egy meglévő értékből Erre kattintva alakíthatjuk egy újrafelhasználható erőforrássá azt a stringet. melyeket csak erőforrások tárolására szokás létrehozni.

3-45 ábra: Már létező erőforrás kiválasztása egy tulajdonsághoz Ez egy nagyon hasznos lehetőség a XAML-ben. ha nem egy előre elkészíthető erőforráshoz akarunk kötni. hanem valami máshoz. 3-43 ábra: A zöld keret és pötty jelzi. hogy a Blend nagyon szépen jelzi. hogy a tulajdonság egy erőforrásból kap értéket Továbbá. illetve a Silverlightban. hogy egy tulajdonság nem lokálisan kap értéket. hanem egy erőforráshoz kötöttük hozzá (3-43 ábra). például egy CLR-objektumhoz. létrehozva ezzel az erőforráshoz kötést (3-44 ábra). 3-44 ábra: Az adatforrások a Resources panelon Ugyanezt elérhetjük. 67 . Mi a helyzet akkor. ha átváltunk a Resources panelra. ott is megtalálható az erőforrások között az újonnan létrehozott string. ha a kiválasztott tulajdonság melletti Advanced optionsre kattintva a Local Resource menüpont alatt kiválasztjuk a megfelelő erőforrást (3-45 ábra). A kész erőforrás innen azonnal.Adatkötés Az is észrevehető. vagy kötést szeretnénk létrehozni a UI különböző elemei között? Erre szolgál megoldással az adatkötési rendszer. drag-and-drop módszerrel áthúzható egy felületi elemre.

Ezzel véletlenszerű mintaadatokkal feltöltött adatforrásokat hozhatunk létre. A megjelenő ablakban válasszuk ki a Character osztályt. ahol a tényleges adatok még nem állnak rendelkezésre. Hasznos a fejlesztésnek abban a fázisában.) 68 .} public Character() { Name = "Hubert Farnsworth".3. majd annak jobb felső sarkában a „Create data source” gomb alatt válasszuk a „Create Object Data Source…” pontot (3-47 ábra)! 3-47 ábra: Adatforrás létrehozása a Data panelen A Data panel tetején találunk egy másik gombot is. illetve adjuk meg az adatforrás nevét! (Ha még nem jelenne meg az osztály. a „Create sample data” nevűt. set. vagy hiányzik a program szerelvénye a listából. set. és jelenítsük meg mindkét tulajdonságát egy-egy TextBlockban (3-46 ábra)! 3-46 ábra: A program felülete Ehhez kattintsunk a Data panelre. és megjelenik. fordítani vagy futtatni kell. Alkalmazásfejlesztés Windows Phone-on Több vezérlő kötése egyazon forráshoz Tekintsük az alábbi osztályt: public class Character { public string Name {get.} public string City {get. City = "New New York". } } Hozzunk létre egy példányt ebből az oldalon.

szép. 3-49 ábra: Az új adatforrás tulajdonságai a Data panelen 3-50 ábra: Az adatforrás részeinek adatkötése drag-and-drop módszerrel Szép. de ha sok tulajdonságot szeretnénk egyazon objektumról megjeleníteni. és létrejön az adatkötés (3-50 ábra). nem lehetne egy kicsit központosítani az adatkötést? Természetesen lehet. Vezérlőink DataContext tulajdonsága szolgál 69 .Adatkötés 3-48 ábra: Az adatforrás típusának kiválasztása A Data panelen megjelenik az új adatforrás (3-49 ábra). Drag-and-drop módszerrel az egész adatforrást vagy egyes részeit ráhúzhatjuk egy felületi elemre.

Logikus tehát. A Blend ehhez is hathatós támogatást nyújt. és a ListBoxra kattintani (3-52 ábra). ha a TextBlockokban a ListBox kiválasztott eleme jelenne meg. egyenként létrehozott Bindinggal szemben. hogy egy objektumot megadva neki beállítsuk. hogy nem kell egy-egy bonyolultabb adatkötést újra és újra megírni. azaz az előbb létrehozott Character objektumra. Alkalmazásfejlesztés Windows Phone-on arra. Adatkötés UI-elemek között Az előző példát egészítjük ki! A TextBlockok alatt egy ListBox foglal helyet. hogy a vezérlő vagy a benne lévő vezérlők tulajdonságai alapértelmezetten milyen objektumra legyenek rákötve. felbecsülhetetlen lehet.) Ezek után az egyik TextBlock Text tulajdonsága melletti Advanced optionsre kattintva a DataBinding menüpontot kell választani. Szeretnénk. a két TextBlock objektumot pedig ennek egyes tulajdonságaihoz kössük hozzá. melyben Character típusú elemeket helyezünk el. automatikusan mindegyik. de ha kézzel szerkesztjük a XAML-t. (Érdemes nem a felületen. majd jóval egyszerűbb szintaxissal a felület egyes részeihez kötni. hanem a ListBox kiválasztott eleméhez. Tehát arra van szükség. Ehhez első lépésként magát az adatforrást kell megfogni. hogy Blendben az ember hajlamos mindent „csak összekattintgatni”. A fenti két TextBlock egy StackPanel gyermeke. hogy a StackPaneltől örökölt kontextus melyik tulajdonságára szeretnénk a Textet kötni (3-51 ábra). vagyis az adatkötést két UI-elem között hozzuk létre. és drag-and-drop módszerrel a StackPanelre húzni. hogy a StackPanel DataContextjét állítsuk be a CharacterDataSource-ra. ahol kiválaszthatjuk. az oldalon lévő vezérlő képes lesz adatot kötni hozzá. hanem az Objects and Timeline ablakon elengedni a vonszolt objektumot. hanem elég egyszer létrehozni. A megjelenő ablak automatikusan a DataContext fület nyitja meg. A DataContext öröklődik lefelé a vizuális fán.3. Elég a StackPanel DataContextjénél az Advanced options alatti „Element Property Binding…” pontot választani. 3-51 ábra: Adatkötés létrehozása egy szülő DataContextjén keresztül Tekintve. hogy a StackPanel DataContextjét most ne egy háttérben lévő objektumhoz kössük. itt még nem olyan nagy a DataContext előnye a sok. tehát ha például a PhoneApplicationPage-en állítjuk be. 70 .

Mivel csak megjeleníteni szeretnénk a szöveget. a Create Data Binding ablakban nem kapunk segítséget. 3-53 ábra: Tulajdonság és irány kiválasztása adatkötésnél Ezután már csak a TextBlockok Text tulajdonságát kell a korábbiakban megismert módon kötni. és a TwoWay. ami egyirányú kötés. a OneWay. Az ablak alsó részén található szövegdobozban adhatjuk meg manuálisan a tulajdonság nevét (3-54 ábra). amelyre kötni szeretnénk (SelectedItem). a forrásból történő kiolvasása után nem lesz szinkronizálás. tehát a cél változása is visszahat a forrásra. tökéletesen elég az alapértelmezett OneWay kötés (3-53 ábra). vagyis az adatok első. 3-54 ábra: Saját elérési út megadása a forrástulajdonságra 71 . Mivel azonban a ListBoxban lévő elemekről statikusan semmit nem tudunk. Silverlightban három kötési mód van: a OneTime egy egyszeri kötés. ahol a változáskövetés kétirányú.Adatkötés 3-52 ábra: Adatkötés egy vezérlőre A megjelenő ablakban kiválaszthatjuk a tulajdonságot. valamint megadhatunk különböző beállításokat. vagyis a forrás változása kihat a célra. például a kötés irányát. hogy kiválasszuk a Name vagy a City tulajdonságokat.

Ez nem meglepő: honnan tudná a Silverlight. Hogyan tehetjük ezt szebbé? Listavezérlőink rendelkeznek egy DisplayMemberPath nevű tulajdonsággal. nem enged szünet karaktert belerakni.microsoft. 3-56 ábra: A DisplayMemberPath tulajdonság beállítása 72 . Utóbbiról egy leírás és példa: http://msdn. 3-55 ábra: A ListBox egy elemének kiválasztásával a két TextBlock tartalma frissül Ha teszteljük az alkalmazást. azok gyönyörűen megjelentek. már nem működik annyira szépen a megjelenítés. ahogy más elemre állunk a ListBoxban (3-55 ábra). DependencyProperty-kkel szokás megoldani. Ennek eredményét láttuk a képernyőn. a két TextBlock felirata automatikusan frissül. hogy a szövegnél bonyolultabb objektumokat (a Character osztály már két stringet is tartalmaz). vagy ne rakjunk bele szünetet.com/enus/library/ms229614. hogy ha Name tulajdonságot lát. vagy változtassuk meg a Name-et másra! Emellett írhatunk morcos leveleket a Microsoftnak.aspx Az adatok megjelenésének testreszabása adatsablonokkal Amikor szövegeket helyeztünk el a ListBoxban. Alkalmazásfejlesztés Windows Phone-on A Blend és a Visual Studio XAML értelmezője olyannyira kifinomult. hogy az objektum melyik tulajdonsága jelenjen meg a ToString hívása helyett (3-56 ábra). az egyéb típusoknál pedig az INotifyPropertyChanged interfész implementálásával. hogy egy XAML-ben megadott string nem megfelelő a Name tulajdonságnak. Az adatkötési keretrendszernek alapvető része a változásokról való értesítés. mellyel megadhatjuk. Ezt a vezérlők esetében ún. Ha azt jelzi az IDE. hogy hogyan kell megjeleníteni egy Character típus példányát? Jobb híján csak annyit tehet. hogy visszatér a kályhához: meghívja a számára ismeretlen típusú objektum ToString metódusát. Most.3.

3-58 ábra – Az új adatsablon nevének és helyének megadása 3-59 ábra – A tervezőfelület tetején látható „breadcrumb” jelzi. ha egyetlen tulajdonságot jelenítünk meg. a tervezőfelület sablonszerkesztési módba vált (3-59 ábra).Az adatok megjelenésének testreszabása adatsablonokkal Mivel a mobilképernyő alapvetően kicsi. mint ahogy az oldalakét is tettük. gyakran elég lehet. 3-57 ábra: Adatsablon létrehozása a ListBox elemeihez Ha a következő ablakban (3-58 ábra) megadjuk a sablon nevét. Ezen belül elsőre csak a „Create Empty…” választható. 73 . A ListBoxban lévő elemek sablonját úgy változtathatjuk meg. Sokszor viszont több adatot is szeretnénk megjeleníteni egy elemről. hogy jobb gombbal a ListBoxra kattintunk. majd az „Edit Additional Templates” menüpont alatt az „Edit Generated Items (ItemTemplate)” parancsot választjuk. hol jöjjön az létre (az erőforrások létrehozásából már ismerős lehet). hogy sablont szerkesztünk Itt ugyanúgy rakhatjuk össze a felületet. Ilyenkor használhatunk adatsablonokat (data template). ezzel hozhatunk létre új adatsablont (3-57 ábra). és azt.

Egy gomb mindössze. A korábban megismert adatkötési eljárással ez is könnyedén megoldható. a vezérlőt leíró osztály csupán a működést definiálja. a kinézetet nem. Appearance és Layout csoportokba a Properties panelen. De mi a helyzet magukkal a vezérlőkkel? A Silverlight vezérlői jól testreszabhatóak pusztán tulajdonságaikon keresztül: elég belenézni a Brushes. tehát a fent elkészítettet átadhatjuk egy másik oldal másik ListBox objektumának is. Azonban ha ez nem elég.) 3-63 ábra: Az adatsablonnal megerősített program működés közben Az adatsablonok — ha erőforrásként hoztuk létre őket — újra felhasználhatóak. (Advanced options. hogy két TextBlock van a sablonban. Data Context. Alkalmazásfejlesztés Windows Phone-on 3-60 ábra: A Gridből és az abban lévő két TextBlockból álló adatsablon A 3-60 ábrán látható. amire rá lehet kattintani” — esetünkben tapintani. Data Binding…. A vezérlők kinézetének testreszabása vezérlősablonokkal Adatok megjelenését már testre tudjuk szabni. A Silverlight (illetve eredetileg a WPF) vezérlői „kinézetmentes” (lookless) vezérlők. Tartozik hozzá egy alapértelmezett kinézet – 74 . „valami. custom expression.3. akár teljesen ki is cserélhetjük megjelenésüket.

A vezérlők kinézetének testreszabása vezérlősablonokkal legtöbbször chrome-ként hivatkoznak erre –. mert jelen pillanatban nem tud képet megjeleníteni. és kiválaszthatjuk a helyét (3-64 ábra). ha mi nem szabjuk meg. akkor elérhetővé válnak az „Edit Current” (jelenlegi szerkesztése) és az „Apply Resource” (használat erőforrásként) parancsok is.” – a példában ezt teszem). Hogyan cserélhetjük le ezt az alapértelmezett megjelenést? Az előző. amivel új Charactereket lehet hozzáadni a listához. ha a gombok kisebb feliratokkal jelennének meg. és egy-egy kép is kapcsolódna hozzájuk. az „Edit Template” menüpontot kell választanunk. 75 . 3-62 ábra: Új vezérlők az előző példaalkalmazáshoz Szeretnénk. hogy hogyan nézzen ki egy gomb. így. Jobb egérgombbal kattintva az egyik gombra. 3-63 ábra – Egy vezérlő sablonjának lecserélése üresre A megjelenő ablakban szokás szerint nevet adhatunk a sablonnak (erőforrásnak).. Ha már van egy saját sablon. Ehhez testre kell szabnunk a vezérlőt. adatkötéses alkalmazást kiegészítettük még egy sorral. Itt vagy egy üres sablont hozhatunk létre („Create Empty. vagy a jelenlegit másolhatjuk le. és szerkeszthetjük.. illetve a lista kijelölt elemét törölni (3-62 ábra). ezt az alapértelmezett kinézetet kapja.

Két dolog maradt már csak hátra:   . A projektbe fel kell vennünk a megjelenítendő képet. Alkalmazásfejlesztés Windows Phone-on 3-64 ábra – Az új vezérlősablon nevének és helyének megadása Az üres Gridben egy Image és egy TextBlock vezérlőt elhelyezve (és tulajdonságaikat megfelelően beállítva) az alapvető elrendezés néhány másodperc alatt összeállítható. vagy többnyelvűvé tenni. Ehhez a TemplateBindingot használjuk fel. ha a gomb szövege meg is jelenne. Az első probléma egyszerűen megoldható. mint a korábbi adatsablon létrehozása. A TextBlocknak meg kell mondani.szeretnénk. illetve . majd az Image vezérlő Source tulajdonságánál kiválasztani azt a lenyíló listából (3-65 ábra). melyre adatkötést lehet létrehozni (3-66 ábra). 3-65 ábra: Kép kiválasztása egy Image elem forrásául Ez egyszerű volt. A TextBlock kijelölése után. ugyanúgy működik. hogy Text tulajdonságában annak a Button vezérlőnek a Content tulajdonságát jelenítse meg. a Text tulajdonság melletti Advanced optionsre kattintva a Template Bindingot kell választani.3.kell egy kép az Image-nek. amelyre éppen alkalmazzák – elvégre egy sablont több gombra is rá lehet majd húzni. 76 . mert előre rendelkezésre állt a kép. esetleg egyszerűen csak nem akarjuk a vezérlősablonban rögzíteni. Mi a helyzet a felirattal? Azt esetleg változtatni szeretnénk. A megjelenő listában a sablon célvezérlőjének (esetünkben a Button) összes olyan tulajdonságát láthatjuk.

3-68 ábra: Mindkét gomb külön sablonnal ellátva Mivel most a két gomb felépítése tulajdonképpen ugyanaz. illetve a tervezőfelületen látszik.A vezérlők kinézetének testreszabása vezérlősablonokkal 3-66 ábra: Vezérlősablon tulajdonságának a vezérlőhöz kötése a TemplateBinding segítségével A Content tulajdonság kiválasztása után meg is jelenik az adatkötést jelző sárga keret. amelynek egy plusz ImageSource tulajdonságot adunk. a képet természetesen egy másikra állítva a Hozzáadás gomb is megszépíthető (3-68 ábra). 77 . Érdemes a képeket Visual Studióban hozzáadni a projekthez. ez pedig elengedhetetlen. érdemes saját vezérlőt készíteni. hogy a sablon már a gombtól veszi a feliratát (3-67). csupán a képeik térnek el. és az Image vezérlő forrását erre kötjük rá a TemplateBindinggal. mert a Blendben sajnos nem tudjuk Build Action tulajdonságukat átállítani. 3-67 ábra: A vezérlősablon átveszi a vezérlőtől az értéket Ugyanezeket a lépéseket eljátszva.

3-69 ábra: A VisualState-eket bemutató program kinézete és szerkezete Ezt az egyszerű logikát leírhatjuk kódban is. tehát az alkalmazás egy VisualStateGroupnak egyszerre csak egy VisualState-jében lehet. hogy olyan kódot írjunk. ezért először egy csoportot kell létrehozni (3-70 ábra). ami a felület megjelenését közvetlenül befolyásolja. Ezzel központosíthatjuk a felületleírást. 78 . az egyik kép tűnik elő.3. és az egyes állapotok közötti váltás is jelentősen leegyszerűsödik a korábbi módszerekhez képest. de ha egy mód van rá. 3-70 ábra: Új állapotcsoport hozzáadása a States panelen A csoport létrehozása és elnevezése után létrehozhatjuk állapotainkat (3-71 ábra). hogy ha a felhasználó megnyomja az egyik gombot. a másik pedig engedélyezetté (3-69 ábra). Emellett pedig a megnyomott gomb letiltottá válik. próbáljuk meg elkerülni. Az egy csoportban lévő állapotok kölcsönösen kizárják egymást. Alkalmazásfejlesztés Windows Phone-on Az alkalmazás állapotainak létrehozása VisualState-ek segítségével A Silverlight 3 óta alkalmazásainkban különböző vizuális állapotokat adhatunk meg. ha a másikat. melyekben leírhatjuk a felület elvárt állapotát bizonyos helyzetekben. Vegyük példának az alábbi egyszerű alkalmazást! Két gombból áll. a másik kép. amelyek két képhez kapcsolódnak olyan módon. Ehelyett a States panelen hozzunk létre két állapotot! VisualState-jeink csoportokba rendezhetők.

Ha egy állapot szerkesztése közben 0%ra állítjuk az Opacity értékét. hogy a gombnyomás hatására lefusson az állapotváltás. de ha tartjuk magunkat ahhoz. 79 .Az alkalmazás állapotainak létrehozása VisualState-ek segítségével 3-71 ábra: Új állapot hozzáadása egy állapotcsoporthoz Vegyük észre. 3-72 ábra: Egy állapot szerkesztése közben a tervezőfelület piros keretet kap A vezérlők átlátszóságát az Opacity tulajdonsággal tudjuk állítani. Ha például arra van szükségünk. akkor más módszerre lesz szükség. a tervezőfelület állapotszerkesztési módba vált. Meg kell oldani. átadva neki a célállapot nevét). az nem az alkalmazás normál állapotában fog megjelenni. A Behaviorök segítségével meglévő vezérlőkhöz rendelhetünk hozzá extra viselkedéseket. hogy egy gomb valamilyen eseménye hatására (nem kell feltétlenül a Clicknek lennie) egy állapotváltást végezzen. A States panel tetején lévő Base gombra kattintva térhetünk vissza bármikor az állapotokon kívüli szerkesztéshez (3-72 ábra). 3-73 ábra: Az Opacity beállítása A gombokat az IsEnabled tulajdonság állításával engedélyezhetjük. hogy amikor kijelölünk egy VisualState-et. illetve tilthatjuk. vagyis bármit változtatunk a felületen. amikor ebbe az állapotba lép az alkalmazás. a GoToStateActiont aggathatjuk rá a gombra. hanem csak akkor. Ezt megtehetjük kódban (a Click eseménykezelőkben meghívjuk a VisualStateManager GoToState metódusát. hogy deklaratív módon szeretnénk a felületet leírni. A Behavioröket az Assets panel Behaviors listájában találjuk (3-74 ábra). a vezérlő eltűnik (3-73 ábra).

az alkalmazás felülete rögtön abba a vizuális állapotba vált. és rákattintunk valamelyik gombra. hogy mely esemény hatására (EventName) mely állapotba szeretnénk átváltani (StateName). Alkalmazásfejlesztés Windows Phone-on 3-74 ábra: A GoToStateAction Behavior az Assets panelen Innen egyszerűen ráhúzhatjuk őket a gombokra. Ennek eredményét az Objects and Timeline ablakban is láthatjuk (3-75 ábra).3. miután rádobtuk egy gombra A GoToStateActiont kiválasztva a Properties panelen beállíthatjuk. 3-75 ábra: A GoToStateAction Behavior. 80 . amelyet meghatározunk a gomb számára (3-77 ábra). 3-76 ábra: A Behavior beállítása Ha futtatjuk az alkalmazást.

Maga az animáció egy tulajdonság értékének adott idő alatti megváltoztatását jelenti. Ezután csak annyit kell tenni. hogy minden állapotban a másik állapotba váltó. Szebb lenne. animált. amikor a változtatásokat végzi az ember. „átúszna” a másik képbe. A XAML előnye pedig. hanem csak írja le (deklarálja). hanem látványos. kinézetét a kiinduló. amikor ennyi nem elég. Vagy például szeretnénk azt elérni. és utána (gyakran pixelről pixelre) kirajzolni a vezérlőt. Szépen. (A *  Célállapot nevű átmenet a bármely más állapotból az adott célállapotba történő animálást jelenti. de nem árt arra ügyelni. hogy az ehhez hasonló látványelemeket ne imperatív kóddal valósítsa meg a fejlesztő. hogy könnyen generálható… A két korábban létrehozott VisualState egyikében cseréljük fel a gombok helyzetét! A lényeg. gyorsan. milyen végértékre szeretnék hozni”. hogy mindig az a gomb legyen felül. hogy az egyes állapotokat kiválasztva (States panel) az állapoton lévő „Add transition” gombbal hozzárendelünk egy állapotátmenet-animációt egy adott átmenethez. ha például a kép nem egy pillanat alatt váltana át. abban pedig kiszámolni a vezérlő aktuális elhelyezkedését. menyi idő alatt.és a végállapot között. a Microsoft a WPF-fel előtérbe helyezte azt a megoldást. hogy gyorsan leírható. engedélyezett gomb legyen felül! Ez a tervezőfelületen. hogy mit is szeretne elérni. amit a felhasználó megnyomhat – és a gombok helycseréje se pillanatszerű legyen. Mivel ennek az implementálása értékes időt vett el a fejlesztőtől. de érezhetően kicsit fapados a kinézet működése. mindenféle kód nélkül össze tudjuk állítani a felületet a különböző állapotokban. Ennek előnye. Korábban a legtöbb fejlesztőeszköznél ennek a leprogramozása teljes egészében a fejlesztő feladata volt: másodpercenként harmincszor feldobni egy eseményt.Az alkalmazás állapotainak létrehozása VisualState-ek segítségével 3-77 ábra: A program felülete „rage” állapotban Animációk hozzáadása Vannak esetek. és a háttérben az erre optimalizált keretrendszer elvégzi helyettünk a bonyolult kód megírását. dragand-drop módszerrel érhető el. Vagyis az animációkat elég XAML-ben megfogalmazni: „milyen tulajdonságot. hogy a megfelelő állapot legyen kijelölve.) 81 . hanem egy másodperc alatt elhalványulna.

és a gombok is egy másodperc alatt csúsznak egyik helyről a másikra. hogy a felületen lévő vezérlők közül melyek animáltak. és pontosan mely tulajdonságaik. 3-79 ábra: Az idő és az EasingFunction beállítása Érdemes egy pillantást vetni az Objects and Timeline ablakra is. illetve hogy milyen görbe mentén történjen (EasingFunction). Amikor kijelölünk egy állapotátmenetet a States panelen. hogy mennyi ideig tartson (1s). A VisualState-ek témaköre ennél természetesen jóval terebélyesebb. ahogyan azt a 3-79 ábra jelzi.tutsplus. egyszerűen törölhetjük innen az animációt (3-80 ábra).com/tutorials/silverlight/understanding-visual-states-in-silverlight/ 82 . hanem egy másodperc alatt változik az Opacity értéke 1-ről 0-ra és vissza. Néhány link a továbblépéshez: Mike Taulty bevezető screencastja a VisualState-ekhez: http://active. Ha valamelyik tulajdonságot mégsem szeretnénk animálni. megadhatjuk. 3-80 ábra: Az animáció megjelenítése az Objects and Timeline panelen Mindezeket beállítva a program tesztelhető: az állapotok közötti átmenet nem pillanatszerűen megy végbe. Alkalmazásfejlesztés Windows Phone-on 3-78 ábra: Állapotátmenet hozzáadása egy állapothoz Ha létrejött az animáció.3. itt jelzi a Blend.

hogy az egy ilyen erőforrást használjon.com/2010/11/using-visualstates-in-custom-controls-in-silverlight/ Témák használata Ha szeretnénk. A PageTitle TextBlock kijelölése után a Brushes csoportban található Foreground tulajdonsággal állítható be egy szöveg betűszíne (3-81 ábra). A PhoneAccentBrush az a szín. hogy ezek a méretek. hogy alkalmazásaink illeszkedjenek a Windows Phone 7 megjelenésébe. a chooserek.Témák használata VisualState-ek használata egyéni vezérlőkben: http://www. A Silverlight az összes rendszerszintű alapbeállítást erőforrásként elérhetővé teszi számunkra. Az alábbi példában a legutóbbi program (troll és rage) oldalcímének színét állítjuk be a telefonon kiválasztott alapszínre.timmykokke. 3-82 ábra: A PhoneAccentBrush rendszerszintű erőforrás kiválasztása 83 . hogy a kiválasztott tulajdonság kapcsán néhány kattintással beállítjuk. illetve egyéb operációs rendszerszintű integrációk elvégzése előtti első lépés. színek. ez is adatköthető. amelyet a felhasználó beállított a rendszer alapszínének? Vagy szeretnénk egy szöveget pontosan azzal a betűtípussal és betűmérettel megjeleníteni. betűtípusok milyenek is. amely az operációs rendszernek a felhasználó által bármikor átállítható alapszíne (3-82 ábra). hogy a felületet konzisztenssé tesszük magával az operációs rendszerrel. A mellette lévő „Advanced options” gombra kattintva ezúttal a System Resources listából kell választani. Ez a lista felsorol minden olyan rendszerszintű erőforrást. launcherek (választók és indítók) használata.vagy vezérlősablonban szeretnénk felhasználni azt a színt. 3-81 ábra: A színek beállítása a Properties panelen Ahogy szinte minden. amelyet az oldalak címénél használnak az alkalmazások? Nem kell pontosan tudnunk. Mindössze annyit kell tennünk. Mi a helyzet például. amelynek típusa megegyezik a beállítani kívánt tulajdonság típusával. ha egy adat.

hogyan lehet felhasználni az operációs rendszer vizuális erőforrásait saját alkalmazásainkban. valamint a több elem megjelenítésére képes listavezérlőket. hogy a beépített vezérlőtípusokon milyen szolgáltatásokat tesz elérhetővé a Silverlight. Mindezt a Visual Studio nélkül.3. hogyan lehet adat. Megnéztük. hogy gazdag tartalmú és tudású felületeket építhessünk. hogy a PageTitle-ben megjelenő felirat mindig az operációs rendszer színsémáját követi (3-83 ábra).és vezérlősablonokkal testre szabni egy adattípus megjelenését. Ezután áttekintettük. Megismerkedtünk az adatkötés fogalmával és az adatkötési keretrendszer használatával. 84 . szövegmegjelenítési és szövegbeviteli vezérlőket. illetve hogy hogyan cserélhetjük le egy vezérlő kinézetét a nekünk megfelelőre. szinte teljes egészében elhagyva a saját kód megírását a felhasználói felület elkészítésénél. Alkalmazásfejlesztés Windows Phone-on Ennek kiválasztása után − ha elindítjuk az alkalmazást − látható. 3-83 ábra: A PageTitle a telefon aktuális „accent” színével jelenik meg Összefoglalás Ebben a fejezetben röviden megismerkedhettünk a Silverlight grafikus felhasználói felületének alapvető elemeivel. kizárólag Expression Blend felhasználásával tettük meg. az animációból. Számba vettük a leggyakrabban használt parancsvezérlőket. és megnéztük. Ezután ízelítőt kaptunk a vizuális állapotok használatából.

hogy teljes világtérképet tartalmaz. egyszerűen tudunk kiemelt helyeket (Point of Interest. amelyek egyik megtestesülése a Bing Maps szolgáltatáscsomag. Végül megismerkedünk a Silverlight Toolkit Windows Phone 7-hez tartozó részeivel. útvonaltervezésre. Feliratkozás a szolgáltatásra A szolgáltatás igénybevételéhez először regisztrálnunk kell a https://www. Haladó alkalmazásfejlesztés Windows Phone-on Az előző fejezetekben megismerkedhettünk azokkal az elvekkel és vezérlőkkel. Erre két módszert alkalmazunk: a tartalomegységeket az egyik esetben külön oldalakon jelenítjük meg – az ezek közti információcsere biztosításával –. mivel igen szigorú szabályok vonatkoznak például a telefonos felhasználásra. amelyek amellett. és mindezt a Silverlightban megszokott teljes testreszabhatóság megtartásával tehetjük. akár teljesen kicserélődik egy videolejátszóra. testreszabhatóságát vesszük át. ezek között optimális útvonalat tervezni. ez kiegészül egy képpel. hogy ezeket a térképeket – és a kiegészítő szolgáltatásokat – saját alkalmazásainkban is elérhetővé tegyük. a webes verzióban is fellelhető kétféle nézet között váltogatni. a horizontális strukturálást lehetővé tevő Panorama és Pivot vezérlők segítségével. újság. segítenek a platformhoz illő felhasználói felületek és interakciók megteremtésében is. forgalomadatok szerzésére használhatunk. hogy ez a jelölés távolról csupán egy szövegdobozból álljon. Egyszerű DataTemplate definiálásával létrehozhatunk akár egy olyan oldalt. mégpedig úgy. Például. ha ezekkel a lehetőségekkel nem mindig élünk.4. Egy Live Id-t felhasználva jelentkezzünk be és fogadjuk el a feltételeket! Itt kivételesen érdemes elolvasni a feltételeket tartalmazó dokumentumot. majd rátérünk a tartalmak rendszerezésére. Nem használhatunk pornográf pushpineket. böngészőket vagy a Mango óta XNA játékokat is megjelenítünk a kiemelt helyeken. amit kedvenc keresőnket alkalmazva címkeresésre. de amint a felhasználó ráközelít a területre. amelyek a platform lehetőségeit még jobban kihasználják – a Metro felhasználói felülettel konzisztens módon. míg a másik esetben egy oldalon. amelyek mindenképpen szükségesek egy Windows Phone 7 alkalmazás fejlesztéséhez. De természetesen itt a fejlesztő teljes szabadságot kap. lehetővé teszi.com/ weblapon. rajzszeg) emel ki. 85 . Ez a csomag azon túl. Térképek kezelése A Microsoft az utóbbi években folyamatosan növekvő erőfeszítéseket fektet online szolgáltatásainak továbbfejlesztésébe. rádió. hogy számos új elemmel egészítik ki eszköztárunkat. ha akarunk. A közlekedési adatok nem használhatók televízió. Nem tárolhatunk közlekedési adatokat. A programunk nem működhet együtt más térképszolgáltatásokkal. amikbe jobb nem egy – esetleg több hónapon át tartó – fejlesztés végén belefutni. Pár ezek közül:      Nem írhatunk valós idejű navigációt megvalósító alkalmazást. azaz média esetében.bingmapsportal. POI) megjeleníteni. de valószínűleg nem baj. A fejezet első részében a térképek megjelenítését. amely megadott pozíciókat „pushpin”-ekkel (gombostű. Ebben a fejezetben olyan eszközöket fogunk áttekinteni.

.assembly=Microsoft. tehát a referencia hozzáadásával sem kell majd bajlódnunk. ahogyan azt a 4-1 ábra is mutatja.0"> <maps:Map /> </Grid> A kód futtatásakor már láthatjuk is. hogy a Bing Maps vezérlő megjelenik. 4-1 ábra: Bing Maps kulcs létrehozása A kitöltést követően meg is kapjuk az alkalmazás kulcsát.Controls. 86 . Ehhez a fiókhoz alkalmazásokat regisztrálhatunk. Ezt természetesen kézzel is megtehetjük az alábbi kód segítségével: xmlns:maps="clrnamespace:Microsoft. Mivel még nem adtuk meg a regisztrációkor kapott kódot. aminek első feladata a kliens hitelesítése lesz. akkor annak névtere automatikusan belekerül a XAML kódba.Phone.0. erre szükségünk lesz a kliens hitelesítéséhez A Bing Maps vezérlő használata Hozzunk létre egy új Windows Phone Application projektet Visual Studioban. amire majd szükségünk lesz a Bing Maps vezérlő létrehozásakor (lásd a 4-2 ábrán).Phone.Controls.Maps"> . Haladó alkalmazásfejlesztés Windows Phone-on Mindenesetre ha ezek után is akarunk térképeket használni. hogy már az alap SDK-ban is megtalálható a számunkra fontos Map vezérlő (4-3 ábra). megpróbáljuk mozgatni a térképet.12. 4-2 ábra: A kapott kulcs. nevezzük el „Advanced Development”-nek! A Toolboxot kinyitva láthatjuk. <Grid x:Name="ContentPanel" Grid. Ha nagyítunk. ez az. akkor a vezérlő elkezd kommunikálni a szolgáltatással. amint az a 4-4 ábrán látható..4. akkor létrejön számunkra egy felhasználói fiók. és elfogadtuk a feltételeket.Maps. ez meg fog hiúsulni. amit a térkép közepén megjelenő hibaüzenet tudat velünk.Row="1" Margin="12. ha a menü Create or view keys elemére klikkelünk. 4-3 ábra: A Map vezérlő megtalálható a Toolboxban Ha drag-and-drop módszerrel hozzáadjuk ezt a vezérlőt a megnyitott oldalunkhoz.

A vezérlő viszont még ezt követően is a teljes világtérképet fogja megjeleníteni. amelyeken az előző nézet útvonalai természetesen ugyanúgy ki vannak emelve.. hanem az ezek alapján készített. " Center="47. AerialMode: Teljes műholdképek. ami a MapMode osztályból származik – ez a megjelenítéshez szükséges 87 . Ezt a ZoomLevel megadásával változtathatjuk meg: <maps:Map Name="myMap" CredentialsProvider="Ajdyq5FaN2RZvzvogm_. A módok közötti váltáshoz egy kicsit többet kell dolgoznunk.Térképek kezelése 4-4 ábra: A térkép. függetlenül a Center pozíciótól.129404" ZoomLevel="17" /> Az egyszerűbb felhasználás kedvéért és a tesztelés miatt is érdemes megjeleníteni a ZoomBar gombjait.. Adjunk meg egy középpontot a térképen a Center tulajdonság segítségével! Ez a tulajdonság GeoCoordinate típusú. és XAML kódból a pozíciót leíró koordinátákat is felhasználhatunk az értékadás során. ugyanis a térkép Mode tulajdonsága egy olyan objektumpéldányt vár... csak az utakra összpontosító nézetet kapunk.. Ez az alapértelmezett mód. és rendesen használhatjuk a vezérlőt. középen a hitelesítés hiányát jelölő hibaüzenettel Állítsuk be tehát a hitelesítéshez szükséges kulcsot a vezérlő tulajdonságai között.. hiszen nem állítottuk még be a nagyítás fokát. Ezek az emulátoron különösen hasznosak tudnak lenni a kicsinyítés és nagyítás gombokkal való vezérelhetősége miatt: ZoomBarVisibility="Visible" A térkép két különböző módban jelenhet meg:   RoadMode: Ebben az esetben nem a műholdképekkel találkozhatunk.639655. és nevezzük is el a térképet! <maps:Map Name="myMap CredentialsProvider="Ajdyq5FaN2RZvzvogm_.-122."/> Ennek hatására a figyelmeztetés eltűnik.

" Center="47. beállításokat tartalmazza..Controls. például az alábbi módszerrel: using Microsoft. myMap.Mode> <maps:AerialMode /> </maps:Map.639655.639655.-122. Az előbb leírt módok használatához szerencsére léteznek előre definiált osztályok.. középen a Microsoft főhadiszállásával.4.Mode> <maps:AerialMode /> </maps:Map.Mode> </maps:Map> A kód hatására meg is jelenik egy teljes funkcionalitással bíró térkép.Phone. //.Mode = new AerialMode().. 88 .129404" ZoomLevel="17" ZoomBarVisibility="Visible"> <maps:Map..129404" ZoomLevel="17" ZoomBarVisibility="Visible" LogoVisibility="Collapsed" CopyrightVisibility="Collapsed"> <maps:Map. } Természetesen erre ugyanúgy lehetőségünk van a XAML leírásból is: <maps:Map Name="myMap" CredentialsProvider="Ajdyq5FaN2RZvzvogm_. public MainPage() { InitializeComponent(). azokat csak példányosítani kell.Maps." Center="47. amint az a 4-5 ábrán látható..-122. akkor a teljes eddigi kódunk (a névtér definíciója mellett) csupán ennyi: <maps:Map Name="myMap" CredentialsProvider="Ajdyq5FaN2RZvzvogm_. Haladó alkalmazásfejlesztés Windows Phone-on értékeket.Mode> </maps:Map> Tűntessük még el a Bing logoját és copyright feliratát a LogoVisibility és CopyrightVisibility Collapsed-re állításával! Ha mindennel végeztünk..

-122.63876. Content = "C#" }).Children. Az így kapott jelöléseink végtelenül egyszerűek. csupán koordináták és kiírandó szöveg megadásával használható vezérlő. Ezeket a pushpineket akár egyesével. Ennek eszköze a szintén a Maps vezérlő névtérhez tartozó Pushpin osztály.Device.Location. megjelölt pozíciók nélkül. XAML vagy C# kódból hozzáadogathatjuk a térképhez.639655.Add(new Pushpin { Location = new System. de akár dinamikus listákat is köthetünk a vezérlőhöz.129404" Content="Microsoft" /> Ugyanez a feladat kódban az osztály példányosításával és a térkép Children kollekciójához való hozzáfűzéssel jár: myMap.GeoCoordinate(47.12862). címek. viszont szükség esetén a Silverlightban megszokott könnyedséggel testre is szabhatjuk azt. csupán a tartalomnak beállított szöveget mutatják az adott pozíción. Ez egyszerűen. 4-6 ábra: Egyszerű Pushpinek a térképen 89 .Térképek kezelése 4-5 ábra: A térkép pozicionálva és nagyítva Aerial módban Pushpinek Egy térkép mit sem érne kiemelt információk. amint azt a 4-6 ábra is mutatja. Egy Pushpin felvétele XAML-ben az alábbi módon történhet: <maps:Pushpin Location="47. -122.

4. ugyanis itt csupán a Content attribútumszerű értékadását kell kicserélni az ún.-122. } public string Name { get. Az adatkötés miatt használjunk ObservableCollection típust.GeoCoordinate(47. „property element” szintakszissal való leírásra: <maps:Pushpin Location="47. csak get metódussal rendelkező tulajdonságon keresztül érünk el. Ez a POI-k egyszerű hozzáadásával körülményes lenne. a benzinkutakat rejtsük el).Location. Ennek példányait két listába. Name = "Old Man's" }. a benzinkutak és a bárok listájába fogjuk sorolni: public class POI { public GeoCoordinate Location { get.640055.120204).639655.Device. -122. bár itt ennek előnyeit nem fogjuk kihasználni: private readonly ObservableCollection<POI> _pubs = new ObservableCollection<POI> { new POI { Location= new System. set.63876. ami tartalmaz egy pozíciót.12862).-122. csak olvasható lista tartalmazza. vagy akár teljes kikapcsolása. 4-7 ábra: Testreszabott Pushpin Rétegek alkalmazása Sokszor elvárt funkcionalitás a kiemelt helyek szűrése egy adott kategória alapján (például a környező kocsmákat jelenítsük meg.129404" Background="Transparent"> <StackPanel> <TextBlock Text="MS" HorizontalAlignment="Center" /> <Image Source="http://www. set. amit az oldal létrehozásakor töltünk fel pár elemmel.png" Width="50" /> </StackPanel> </maps:Pushpin> Ezzel a kis módosítással már teljesen kézben tarthatjuk a pushpin megjelenítését. new POI { Location = new System. } } A példányokat egy privát. Ennek kipróbálására hozzunk létre egy POI osztályt.Device. azonban rétegekbe rendezve a megjelenített tartalmat a feladat sokkal egyszerűbbé válik. Haladó alkalmazásfejlesztés Windows Phone-on A megjelenítés felüldefiniálása a XAML leírásból egyszerűbb. Name = "Oportó" } }.com/download/128133698/ Windows_Vista_Icon_HD_by_magbanuamicah. 90 . és egy publikus.Location.deviantart. Egy valós projektben a listákat természetesen bármilyen adatforrás vagy webszolgáltatás előállíthatja.GeoCoordinate(47. az itt alkalmazott kód például a 4-7 ábrán látható kinézetet eredményezi. valamint a hely megjelölését.

xap csomag egy mappájába kerül. A kódban egy PushPin-t tűzünk ki a Location által meghatározott pozícióra. ami például benzinkutakat tartalmaz: 91 . Képeknél a Build Actiont érdemes Contentre állítani. hogy előállítottuk a megjelenítendő listát. } Most futtatva a programot a definiált POI-k már meg is jelennek (4-8 ábra). Ha kódunkat így próbáljuk futtatni. Ez tartalmazza a hely nevét. hogy később tudjunk rá hivatkozni.ItemTemplate> <DataTemplate> <maps:Pushpin Location="{Binding Location}"> <StackPanel> <TextBlock Text="{Binding Name}" HorizontalAlignment="Center"/> <Image Source="Images/Beer. ennek egy nevet is adtunk. ahogyan azt az ItemTemplate részben meghatározzuk. de magát az adatkötést még nem végeztük el.ItemTemplate> </maps:MapItemsControl> </maps:MapLayer> A réteget egy MapLayer példány reprezentálja. Így a relatív hivatkozások révén könnyebb azt felhasználni programunkban. hogy ne csak egy-egy elemet jelenítsünk meg. akkor a POI-k még nem fognak megjelenni a térképen. this.DataContext = this. Az előző módszerhez hasonlóan hozzunk létre egy listát. méghozzá úgy. hozzunk létre egy új réteget a térképen belül: <maps:MapLayer Name="lPubs"> <maps:MapItemsControl ItemsSource="{Binding Pubs}"> <maps:MapItemsControl.png" Width="50" /> </StackPanel> </maps:Pushpin> </DataTemplate> </maps:MapItemsControl. amit korábban az Images mappába mentettünk. ha ezt most az oldal konstruktorában tesszük meg az alábbi kóddal: public MainPage() { InitializeComponent(). hanem az egész lista tartalmát. } } Most. mivel ekkor a médiaelem nem lesz a szerelvény része. Ezen belül a MapItemsControl teszi lehetővé azt. valamint egy olyan képet.Térképek kezelése public ObservableCollection<POI> Pubs { get { return _pubs. hanem a . hiszen hivatkoztunk ugyan a bekötendő adatokra. Legegyszerűbb.

Visibility == System.png" Text="Benzin" Click="PetrolStations_Click"/> </shell:ApplicationBar> </phone:PhoneApplicationPage.Windows.Visible.Visibility = System. melyekkel a megfelelő réteg megjelenítését tudjuk ki-be kapcsolni: <phone:PhoneApplicationPage. amely két külön rétegen jelenít meg testreszabott pushpineket.Visible) { lPubs. } else { lPubs.Visibility. 92 . valamint a lenti vezérlőgombokkal ezeknek a rétegeknek a megjelenítését váltogathatjuk. Eddigi munkánk végeredménye tehát egy olyan térkép. Haladó alkalmazásfejlesztés Windows Phone-on 4-8 ábra: A pozíció-listák a térképen megjelenítve Ahhoz.Visibility = System.Windows. hogy kihasználjuk a rétegek előnyeit.Collapsed. EventArgs e) { if (lPubs.Visibility.Visibility.png" Text="Bárok" Click="Pubs_Click"/> <shell:ApplicationBarIconButton IconUri="/Images/petrol.ApplicationBar> A gombokhoz tartozó eseménykezelők elvégzik a réteg Visibility tulajdonságának átbillentését: private void Pubs_Click(object sender.Windows. } } A benzinkutak rétegéhez kapcsolódó PetrolStations_Click kódja teljesen hasonló ehhez. amint azt a 4-9 ábra mutatja.ApplicationBar> <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True"> <shell:ApplicationBarIconButton IconUri="/Images/beer. helyezzünk el két gombot az ApplicationBar-on.4.

majd a felugró listán válasszuk az Add Service Reference opciót (4-10 ábra)! 93 . amit egy térképprogramtól elvárhatunk.net/webservices/v1/geocodeservice/geocodeservice.és végpontot adhatunk meg.svc A szerverrel való kommunikációról bővebben a 9.virtualearth. Search Service – Nevezetes helyek. nevezetes helyek. itt csak a feladathoz szükséges mélységig érintjük a témát. távolság. sőt akár a forgalmi helyzettel való számolást is kérhetjük).Térképek kezelése 4-9 ábra: Gombok az ApplicationBaron a rétegek megjelenítésének szabályozására Egyéb szolgáltatások A térképen kívül számos egyéb rendkívül hasznos szolgáltatást kínál számunkra a Bing Maps.net/webservices/v1/routeservice/routeservice. mozik keresése – ez pozícióhoz is köthető. földrajzi nevek keresése.  A fenti szolgáltatások az alábbi címeken érhetők el: Szolgáltatás Geocode Service Route Service Search Service Cím http://dev.virtualearth.svc http://dev. Route Service – Útvonalak tervezése általunk megadott köztes pontok között. fejezet szól. hogy milyen szempontból keressen optimális eredményt (sebesség. Gyakorlatilag az összes főbb funkció.net/webservices/v1/searchservice/searchservice. koordinátákká alakítása vagy koordináták alapján ezek kinyerése. Ezen a listán a tervező algoritmus sorban végigmegy. szabványos SOAP webszolgáltatásokon keresztül elérhető a fejlesztők számára. A szolgáltatások hozzáadásához kattintsunk a projektre az egér jobb gombjával. például éttermek. Lehetőségünk van az utazás módjának beállítására (gyalog / autóval).virtualearth. valamint meghatározhatjuk. Néhány fontosabb ezek közül:   Geocode Service – Címek.svc http://dev. majd ezt a gráfot bejáró ponthalmazt ad vissza nekünk. Azaz nem csupán kezdő. hanem érintett pozíciók egész listáját.

4. } Ezeknél a szolgáltatásoknál szintén szükségünk lesz arra az azonosítóra. Haladó alkalmazásfejlesztés Windows Phone-on 4-10 ábra: Szolgáltatás referenciájának hozzáadása Az itt felugró ablakon adjuk meg a választott szolgáltatás címét.DataContext = this. amelynek metódusai a szolgáltatást címzik meg. de mi itt csak kliens alkalmazást fejlesztünk. A dialógusban lévő Discover gomb lehetőséget biztosít. így a távoli metódusokat egyszerű függvényhívásokkal érhetjük el programunkból. Ezt érdemes egy külön változóban tárolni. természetesen a RouteService névteret fel kell vennünk egy using taggal a file elején: public MainPage() { InitializeComponent(). ehelyett egy Credential típusú objektumot is létre kell hoznunk: 94 . amit a Bing Maps regisztrációjánál kaptunk. és ennek címét adjuk meg az Add Service Reference dialógusban! A generált osztály névtere legyen RouteService! Az OK gombra kattintva létrejönnek a kapcsolatot felépítő és a kommunikációt biztosító osztályok. a MainPage osztály elején. hogy a keretrendszer megtalálja ezt az osztályt. majd kattintsunk a Go gombra (4-11 ábra)! Ekkor a Visual Studio lekéri a cím mögött lévő szolgáltatás WSDL leírását. Itt már nem használhatjuk a XAML-ben rendelkezésünkre álló egyszerűsített értékadást. és kiolvassa belőle az elérhető interfészeket és azokon belül a felkínált funkciókat. RouteServiceClient proxy = new RouteServiceClient(). 4-11 ábra: A szolgáltatás leírása alapján a Visual Studio felismeri az elérhető funkciókat Útvonaltervezés A táblázatból válasszuk ki a Route Service-t. this. hogy a környezet a mi saját Solutionünkön belül keressen elérhető szolgáltatásokat. Hozzuk is létre ezt a proxyt a MainPage konstruktorában! Ahhoz. így erre nem lesz szükségünk. Ezt követően példányosítással létrehozhatunk egy proxy objektumot.

Waypoints = points }. // leggyorsabb útvonal keresése Optimization = RouteOptimization. // autóval közlekedünk Mode = TravelMode.TrafficBasedTime.MinimizeTime. a kiindulási és az érkezési pontot: // érintett pozíciók var points = new ObservableCollection<Waypoint> { // kezdőpont new Waypoint{Location = Pubs[0]. és állítsuk össze az útvonaltervezéshez szükséges kérést! Szükségünk lesz egy olyan objektumra.Location}. // forgalom alapján is optimalizáljon az időre TrafficUsage = TrafficUsage. Erre a RouteOptions osztályt alkalmazhatjuk.Térképek kezelése private const string credStr = "Ajdyq5FaN2Rzvzvogm_. hogy a jelenlegi forgalmi helyzetet is figyelembe vesszük. készítsük fel a megjelenítő felületet az adatok fogadására. amelyben az egyéb beállítások mellett arra mindenképp figyeljünk.Location} }. Hozzuk most létre a bejárandó pontok listáját! Ez egy szintén a RouteService névtérben (vagy amilyen nevet a szolgáltatás referenciájának hozzáadásánál választottunk) lévő osztály. amelyeket csupán egyenesekkel össze kell kötnünk és fel kell rajzolnunk a térképre. ". és egészítsük ki az alábbi sorokkal: 95 . Térjünk vissza ezután a konstruktorba. Ezzel a konfigurációval tehát olyan útvonalat keresünk... Mielőtt megpróbálkoznánk az útvonal előállításával. ami a kalkuláció szempontjait definiálja. azaz az érintett pontok lekérdezését külön igényelnünk kell! var options = new RouteOptions { // a pontok listáját igényelnünk kell! RoutePathType = RoutePathType. private readonly Credentials cred = new Credentials { ApplicationId = credStr}.Points. Ez a lista az út „töréspontjait” írja le. Itt tartalmazzon csak két elemet. hogy a RoutePathType tulajdonságot állítsuk a RoutePathType enumeráció Points elemére. mivel ez alapértelmezés szerint None. A konfigurációs objektumok létrehozása után már előállíthatjuk azt a kérést. vagyis azokat a pontokat.Driving }. Options = options. // végpont new Waypoint{Location = PetrolStations[0]. amely a majd átadott pontok között autóval a lehető leggyorsabban bejárható úgy. A kérésre adott válasz az egyéb fontos információkon felül tartalmazni fogja az érintett pontok listáját is. amit a szolgáltatás már fel tud dolgozni: var request = new RouteRequest { Credentials = cred. a WayPoint példányait jelenti. A XAML-ben keressük ki újra a térkép leírását.

Locations = lc.CalculateRouteCompleted += (s. hogy hogyan jelenik meg mindez az emulátoron (412 ábra)! 96 . és nézzük meg. A pontok halmaza sajnos más típusban érkezik. var lc = new LocationCollection().4. Haladó alkalmazásfejlesztés Windows Phone-on <TextBlock Name="tbDistance" /> <maps:MapPolyline Name="lRoute" Stroke="#FF2C76B7" Opacity="0. Ennek következménye.Summary. Fordítsuk le és futtassuk a projektet. A szolgáltatás meghívása WP7 esetében a WCF automatikusan aszinkron műveleteket generál a szolgáltatással való kommunikációra. valamint a kalkulált útvonal részleteit. amíg a kérésünkre előállított válasz megérkezik.Points) { lc. }. állítsuk a térkép nézetét a visszakapott BoundingRectangle-re! Nincs más hátra.Summary.Text = e. mint amit a megjelenítő elem vár.BoundingRectangle).Add(item).Result. azaz a készülék végig válaszra kész marad. // pozícionáljuk a térképet az útvonalra! myMap.Result.ToString().Result. Miután ezeket a műveleteket elvégeztük. ami annak a téglalapnak az északkeleti és délnyugati koordinátáját tartalmazza. A Summary tulajdonságon keresztül elérhetjük a szakaszok együttes hosszát. de ezt egy konverziós ciklussal orvosolhatjuk.Result. Ennek e paramétere egy CalculateRouteCompletedEventArgs típusú objektum. foreach (var item in e. Ennek szellemében írjuk meg a lekérdezést: proxy.Result. amely magába foglalja a teljes útvonalat.SetView(e. Ehhez csupán a vezérlő Locations tulajdonságát kell beállítani egy ObservableCollection<Waypoint> példányra.CalculateRouteAsync(request). az lRoute nevű MapPolyline objektum pedig felrajzolja azt. sikeres volt-e).RoutePath. ami tartalmazza a művelet végrehajtását leíró adatokat(pl. indítsuk el az aszinkron kérést! // kérés indítása proxy. valamint egy BoundingRectangle nevű elemet.85" StrokeThickness="6" /> A tbDistance fogja megjeleníteni az útvonal hosszát. ehelyett az eredmény elkészültét jelző események argumentumaiként juthatunk hozzá az igényelt adatokhoz. aminek elemeit használva rajzolja majd ki az út szakaszait.Result. Ezen kívül minden adat kötése egyértelmű. e) => { tbDistance. Ennek nagy előnye. hogy azonnali visszatérési értékkel nem rendelkeznek a függvények. A CalculateRouteCompleted eseménykezelője az egyszerűség kedvéért lehet helyben definiált anonim metódus is. hogy a felhasználói felület nem áll le arra az időre.Distance. } lRoute. az ennek megtételéhez szükséges időt.

ami egy linkhez hasonlóan jelenik meg. de felüldefiniálhatjuk a kinézetét. Az oldalak közti navigáció megvalósítására két lehetőségünk van:         HyperlinkButton – egyszerűen használható vezérlő. amely elemeket jelenít meg.xaml fájllal. egy önálló entitás. A NavigationService fontosabb metódusai.Navigáció 4-12 ábra: Az útvonaltervezést is tartalmazó kész alkalmazás Az ábrán látható. mint egy weblap. Navigáció A tartalom rendszerezésének egyik magától értetődő eszköze önálló oldalak létrehozása. eseményeket kínál számunkra. A PhoneApplicationPage elképzelhető úgy is. Ebben a részben ezeket a lehetőségeket fogjuk áttekinteni. de egészen másról van szó. amin keresztül könnyen kézben tarthatjuk a navigációs folyamatokat. Az egyszerű oldalváltáson túl függvényeket. itt is gyakran szükséges valamilyen kommunikációt biztosítani a lapok között. Ha csak a Solution Explorerben nézünk rá a fájlrendszerre. Az oldalak különálló egységeket alkotnak. mint a Back gomb lenyomásakor. 97 . CurrentSource – Az éppen mutatott oldal címe. ugyanúgy. azonban ahogyan weblapok esetében is. Navigated – A navigáció végét jelző esemény. akkor ezek hasonlónak tűnhetnek. Oldalak Minden Windows Phone 7 projekt a létrehozásakor két XAML állománnyal rendelkezik: egy MainPage nevű oldallal és egy alkalmazásszintű erőforrásokat és eseményeket tartalmazó App. ugyanis a MainPage szülő osztálya a PhoneApplicationPage. a bal felső sarokban pedig megjelenik a szakaszok együttes hossza. NavigationService – ez egy osztály. Navigate(Uri) – Átnavigál az Uri által meghatározott címre. míg az App az Application-ből származik. tulajdonságai és eseményei: GoBack() – Visszanavigál az előző oldalra. és rendelkezik a más oldalak eléréséhez szükséges eszközökkel. hogy a teljes útvonal kékkel kiemelve látszik. Navigating – A navigáció indítványozásakor következik be.

amelyen keresztül elérhetjük a többi lapot. a NavigationContext-ből és az előbb említett NavigationService-ből.Navigate(new Uri("/MainPage. } A Navigate függvény egy URI-t vár. Haladó alkalmazásfejlesztés Windows Phone-on   Source – A jelenleg aktív vagy mindjárt aktívvá váló oldal címe. amivel ezt módosíthatjuk(RemoveBackEntry).12. Ehhez a projekt gyorsmenüjéből válasszuk az Add  New Item funkciót (4-13 ábra)! 4-13 ábra: Új elem hozzáadása a projekthez Az Add New Item ablakban válasszuk a Windows Phone Portrait Page sablont. amely alapértelmezés szerint abszolút. ami egy főmenüt fog tartalmazni. Az első segítségével férhetünk hozzá a QueryString-hez. valamint az ehhez kapcsolódó előrenavigálás.xaml". azon belül pedig keressük ki a WMAppManifest. Ezzel a paranccsal címezzük meg a fejezet első részében létrehozott MainPage. de ez a WP7 esetében mindig false értékű lesz.Row="1" Margin="12.0"> <StackPanel> <Button Name="btnMap" Content="Térkép" Click="btnMap_Click" /> </StackPanel> </Grid> Menjünk át a kódot tartalmazó forráskód állományhoz (legegyszerűbb az F7 lenyomásával a XAML fájlhoz tartozó forráskódra ugrani). Itt a gomb Click eseménykezelőjében használjuk fel a már említett NavigationService-t az oldalváltásra: private void btnMap_Click(object sender. ami csakúgy. A NavigationService a felsorolt lehetőségein túl elérhetővé teszi a korábbi oldalak listáját (BackStack) és egy eljárást is. CanGoBack – Tudunk visszafelé navigálni? Azaz van-e bejegyzés az oldalak közti lépkedést rögzítő veremben? A NavigationService rendelkezik egy CanGoForward tulajdonsággal is. mint például a lap orientációja. onnan pedig sehova nem tudunk navigálni! A megoldáshoz nyissuk ki a Properties mappát. azon belül pedig helyezzünk el egy gombot: <Grid x:Name="ContentPanel" Grid. nekünk viszont most egyszerűbb lesz. A PhoneApplicationPage navigációs eszköztára két fontosabb részből áll.xml-t (4-14 ábra)! 98 .0. Ezek kipróbálására egészítsük ki az előző alkalmazást egy új oldallal. Ezen az új oldalon adjunk a ContentPanel nevű Gridhez egy StackPanelt. ha ezt relatívra cseréljük.4. UriKind.Relative)). mint weblapok esetében. az URL-ben átadható paraméterek kulcs-érték szótárát jelenti.xaml-t! Az oldalak közti váltás már működne. az oldal neve pedig legyen MainMenuPage! A többi sablon is ehhez hasonló szerkezetű. azaz a GoForward(Uri) függvény kivételt dob. azonban egy probléma még van: a MainPage nyílik meg először. csupán néhány alapbeállításban térnek el egymástól. RoutedEventArgs e) { NavigationService.

Ekkor hasonlóan.xaml"/> Most már tesztelhetjük programunkat! A kezdőképernyő a „Térkép” gombot fogja mutatni. Adatátvitel az oldalak között Egyszerű. hogy melyik elemet választotta a felhasználó.Show(myParam). } Navigációs metódusok A PhoneApplicationPage ősosztálya. hogy független oldalak között váltogatunk. mint weblapok esetében. Ugyanez már kevés lehet. RoutedEventArgs e) { NavigationService. akkor érdemes az erre vonatkozó elemet eltávolítani (bár ennek elmulasztásával sem vesztünk semmit). if (NavigationContext. Mivel ezek virtuális eljárások. ahonnan pedig a hardveres Back gombbal térhetünk vissza. UriKind. mert itt tudjuk átírni alkalmazásunk metaadatait (például a kiadó nevét. amire kattintva átjutunk a korábban létrehozott útvonaltervezőnkre. Ha például nem használunk Push Notificationt. leírását.QueryString. Ennek legegyszerűbb megoldása a QueryStringek használata. animálás) elvégezzünk. beállítani a kezdőoldalt.Navigate(new Uri("/MainPage.xml a projekt Properties mappájában Azért is érdemes megismerkednünk ezzel az állománnyal.xaml?myParam=test". } A paraméter kiolvasása a másik oldalon a NavigationContext segítségével egyszerűen megoldható: string myParam. adatkezelést nélkülöző programoknál elég lehet az. a saját oldalainkon felül tudjuk definiálni őket az override kulcsszó használatával: 99 . hogy a navigációval kapcsolatos feladatokat (például argumentumok kiolvasása. csak az URL-t kell kiegészítenünk az átadandó kulcs-érték párokkal: private void btnMap_Click(object sender.Relative)). out myParam)) { MessageBox.Navigáció 4-14 ábra: A WMAppManifest. Ezenfelül a Capabilities szekcióban találhatjuk az igényelt képességek listáját. így adva lehetőséget arra.TryGetValue("myParam". a Splash képet és az ikonokat. amelyek közvetlenül az oldal létrejötte után vagy a deaktiválódása előtt futnak le. a Page a NavigationService osztályon túl tartalmaz virtuális metódusokat. ehhez írjuk át a Tasks-on belül a DefaultTask-ot: <Tasks> <DefaultTask </Tasks> Name ="_default" NavigationPage="MainMenuPage. címét. ha például egy lista valamely elemének részleteit szeretnénk egy külön lapon megmutatni. Most elegendő a kezdőoldalt kicserélnünk. az operációs rendszer verzióját). Ugyanis valahogyan meg kell mondanunk a részleteket tartalmazó oldalnak.

// saját kód string myParam.QueryString. } icNavigationList. azaz a BackStack nem ad magáról értesítést a megjelenítő vezérlőnek arról.ItemsSource = NavigationService.Navigation. A DisplayMemberPath tulajdonság beállításával jelezzük. és töltsük ki a gomb eseménykezelőjét is! protected override void OnNavigatedTo(System. úgyhogy új objektumra kell állítanunk az ItemsSource-ot! */ icNavigationList.Windows. RoutedEventArgs e) { NavigationService.Navigation.Row="1" Margin="12.OnNavigatedTo(e). BackStack Az alkalmazásunkon belüli lapváltásokat egy verem tárolja. ami erre az oldalra mutat. hogy az beállítsa a XAML-ben definiált vezérlők hiányzó értékeit. Mi viszont az egyszerűség kedvéért nem használtunk adatkötést.0. /* nem használtunk adatkötést. } Ha felveszünk valahova egy linket. out myParam)) { tbMyParam. // saját kód } Ehhez hasonlóan hozzáférhetünk az oldal elhagyását megelőző OnNavigatingFrom és OnNavigatedFrom függvényekhez is.NavigationEventArgs e) { base.ItemsSource = NavigationService. Hozzunk létre egy új oldalt Navigation névvel. és visszanavigál erre az oldalra. Ehhez a veremhez mi is hozzáférhetünk.NavigationEventArgs e) { base. A RemoveBackEntry függvény törli a navigációs verem felső elemét. már megfigyelhetjük a NavigationService működését. hogy a későbbiekben bekötött elemek Source tulajdonságát akarjuk kiírni! Vegyünk fel még egy gombot is.0"> <StackPanel> <TextBlock Name="tbMyParam" Text="Nem érkezett paraméter"/> <Button Name="btnDelete" Content="Törlés" Click="btnDelete_Click" /> <ItemsControl Name="icNavigationList" DisplayMemberPath="Source"/> </StackPanel> </Grid> Az icNavigationList fogja megjeleníteni a látogatott oldalak vermét.RemoveBackEntry().Text = myParam. és ezzel módosíthatjuk a navigációs szolgáltatás működését! A kódfájlban írjuk felül az OnNavigatedTo eljárást.BackStack.BackStack.OnNavigatedTo(e).12.Windows. Haladó alkalmazásfejlesztés Windows Phone-on protected override void OnNavigatedTo(System. amivel a verem legutóbbi elemét el tudjuk távolítani.4. if (NavigationContext. Az OnNavigatedTo működése magától értetődő. } private void btnDelete_Click(object sender. a gomb eseménykezelője viszont egy kis magyarázatot érdemel.ToList(). Ilyenkor nem elegendő az ItemsSource-ot újra a BackStack- 100 . hogy frissült. amit készítsünk fel egy kapott paraméter és a korábbi címek kiírására a ContentPanel kiegészítésével! <Grid x:Name="ContentPanel" Grid. amiről a hardveres Back gomb leveszi a legfelső elemet. sőt a visszalépést is egyszerű függvényhívással megvalósíthatjuk.TryGetValue("myParam".

openxmlformats. valamint felkínál egy gombot.com/winfx/2006/xaml" xmlns:d="http://schemas. A Navigation vezérlő egy Hyperlink.microsoft. azaz az alkalmazáson belül is tudunk még visszafelé navigálni. hogy ezzel a törléssel a hardveres Back gomb működését is befolyásoljuk.Navigáció re állítani.org/markup-compatibility/2006" mc:Ignorable="d" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" d:DesignHeight="480" d:DesignWidth="480" Height="100" Width="450"> <Grid x:Name="LayoutRoot" HorizontalAlignment="Center"> <StackPanel> <HyperlinkButton Content="Navigation" NavigateUri="/Navigation. ami a hardveres vissza gombbal megegyező funkcionalitású. 4-15 ábra: Az elkészítendő navigációs vezérlő Az ehhez tartozó XAML kód: <UserControl x:Class="_04_Advanced_Development.microsoft.xaml-re navigál − akár paraméter átadásával −. A dolog varázsa az. Több lap esetében pedig érdemes lehet a minden oldalon megvalósítandó funkciókat a folyamatos másolgatás helyett egy UserControl-ba szervezni.com/expression/blend/2008" xmlns:mc="http://schemas. Komplexebb navigáció megvalósításához olyan felhasználói vezérlőt kell készítenünk. mert a UserControl osztály nem tartalmaz NavigationService-t.xaml" /> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <Button Name="btnBack" Content="Vissza" Click="btnBack_Click" /> <TextBox Name="tbNameParam" Width="200"/> <Button Name="btnNavigationPage" Content="Adatok" Click="btnNavigationPage_Click" /> </StackPanel> </StackPanel> </Grid> </UserControl> 101 . amely használja a NavigationService-t. ami a paraméter nélküli oldalváltást teszi lehetővé.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas. hogy a középső TextBox értékét átadja a megcímzett oldalnak. akkor az előtte lévőre fog a gomb visszavezetni. hiszen a referencia ekkor nem változik. azzal a kiegészítéssel. Így ha törüljük a legfelső elemet. Ez azért is érdekes téma. Az alkalmazás kiegészítése navigációs vezérlőkkel Az előző példa kevés oldal esetén még nem igazán látványos. amikor a BackStack nem üres. A kész vezérlő megjelenítése a 4-15 ábrán látható. A Vissza gomb pedig csupán akkor aktív.NavigationBar" xmlns="http://schemas. például a BackStack-ből előálló listára kell állítanunk az icNavigationList-et. hiszen ugyanezen verem alapján dolgozik az is. Ehelyett egy új példányra. úgyhogy a vezérlő sem frissül.microsoft. és nevezzük el vezérlőnket NavigationBar-nak! Ezt a vezérlőt úgy alakítjuk ki. Ennek megvalósításához az Add New Item menüben válasszuk a Windows Phone User Control sablont. Az Adatok gomb ugyanezt valósítja meg. hogy bárhonnan a Navigation.

Format("{0}?myParam={1}". } private void btnBack_Click(object sender. this.RootVisual as PhoneApplicationFrame). RoutedEventArgs e) { Frame.Text)) { Frame. bárhol az oldalon: 102 .CanGoBack. Haladó alkalmazásfejlesztés Windows Phone-on A felhasználói vezérlőkben a navigáció kulcsa az.xaml".Text). }. navigációs függvények. ami a beleágyazott oldalak cserélgetését segíti. hogy referenciát szerzünk egy olyan objektumra. ami rendelkezik az ehhez szükséges képességekkel.4. } Frame. események) biztosításával.Navigate(new Uri(target. UriKind. először vegyük fel a projekt névterét például local névvel: xmlns:local="clr-namespace:_04_Advanced_Development" Majd helyezzük el az egyéb tartalmak között. már csak fel kell használni azt! Ehhez a XAML fájlokat kell csak módosítanunk. Ezek tudatában fejezzük be a forrásfájl kiegészítését! public NavigationBar() { InitializeComponent(). target.Current. és valósítsuk meg a Frame tulajdonságot.GoBack(). } private void btnNavigationPage_Click(object sender. A WP7-es programokban szerencsére mindig található ilyen. public Frame Frame { get { if (_frame == null) { _frame = (App.Loaded += (s. nagyjából ugyanazokat a funkciókat érhetjük így is el. mintha az egy NavigationService példány lenne.Relative)).Navigate(new Uri(string. tbNameParam. } A vezérlő ezzel elkészült. többek között a navigációhoz szükséges feltételek (Source tulajdonság. Menjünk most a NavigationBar kódfájljába. } return _frame. hiszen az App osztály tartalmaz egy publikus PhoneApplicationFrame típusú. RootFrame nevű mezőt. e) => { btnBack. amely egy hivatkozás a RootFrame-re! private Frame _frame.IsEnabled = Frame. } } A Frame a navigációs feladatok során úgy kezelhető.Relative)). RoutedEventArgs e) { string target = "/Navigation. Ez egy fix keret.IsNullOrEmpty(tbNameParam. if (!string. UriKind.

hogy bejárjuk az összes oldalt. nem véletlen. hogy a beépített alkalmazások többsége is ezek felhasználásával készült el. és megnyomjuk a vissza gombokat! Ha minden jól működik.Pivot és Panorama <local:NavigationBar VerticalAlignment="Bottom" /> Próbáljuk ki alkotásunkat úgy. pontosabban a TemplatedItemsControlból származik (4-17 ábra). 4-17 ábra: A Pivot és Panorama kapcsolata az osztályhierarchia alapján Példák a vezérlők alkalmazására az Office programból: 103 . hogyan tudjuk alkalmazásunkat oldalakkal strukturálni. törlünk párat. majd a végén meglátogatjuk a navigációt összegző lapot. Szorosabban kapcsolódó adatok megjelenítésére vagy egyszerűen látványosabb UI létrehozására is két remek vezérlő áll rendelkezésünkre. A Pivot és a Panorama két nagyon hasonló. A WP7 programok kinézetének meghatározó formálói. akkor sikerült elsajátítani az oldalak közti navigáció trükkjeit (4-16 ábra)! 4-16 ábra: A BackStack tartalma és az átadott paraméter is látszik a Navigation oldalon Pivot és Panorama Az előző részben láttuk. amelyeket ebben a részben ismerhetünk meg. Mindkettő az ItemsControlból. horizontálisan elnyúló vezérlő.

alkalmazássablont is találhatunk). Pl. Adatok rendszerezésére. mint a kijelző. Hozzunk létre ezekből egy-egy példányt. jobbra a leveleket csoportosító Pivot látható Különbségek Pivot Lapokra osztott rendszerezés az egyes lapok közti átmenet nélkül. hogy Panorama vezérlő esetén kerülni kell az ApplicationBar használatát. ezért ennek területét teljesen kihasználhatjuk. folyamatos oldal érzetét kelti. Fontos megjegyezni. Alkalmazás kezdőoldala. Érdemes nem telezsúfolni a lapokat. mindenképp használjunk Pivotot! Emellett a Panorama és a Pivot egymásba ágyazva nem használható! A vezérlők népszerűségét jelzi az is. kategóriák kezelésére. egy címmel és két előre létrehozott elemmel. azaz egy PanoramaPage és egy PivotPage nevű oldalt! Az elemeket persze bármilyen oldalon létrehozhatjuk a vezérlő szokásos hozzáadásával is. ha erre szükségünk van. Haladó alkalmazásfejlesztés Windows Phone-on 4-18 ábra: Balra az Office alkalmazás Panorama vezérlője. nem kell ragaszkodnunk a sablon használatához.4. mivel a következő lap jobbról belóg az aktívba. így ezen is lapozhatunk. RSS olvasóban kategóriák szétválasztásakor használjuk. de ha átírjuk őket. akkor bármilyen komplex lapot használhatnak. Panorama Egy horizontálisan elnyúló. Egyszerre csak egy lap látszik. A sablonból generált PanoramaPage tartalmaz egy Panorama vezérlőt. funkciók bemutatása esetén hasznos. <Grid x:Name="LayoutRoot"> <controls:Panorama Title="my application"> <!--Panorama item one--> <controls:PanoramaItem Header="item1"> <Grid/> 104 . A háttérkép szélesebb. Pl. Figyelemkeltő kezdőoldalak. hogy külön oldalsablont építettek be mindkettő számára (sőt. Csak az aktív lap és a mellette lévők kerülnek leképzésre a megjelenítéshez. Az összes elem egyszerre kerül leképzésre a megjelenítéshez. A háttérkép horizontálisan fix (a tabokra definiálhatunk természetesen külön hátteret). Ezek az elemek jelenleg csak üres Grideket jelenítenek meg. esetleg hierarchikus elrendezésre érdemes használni.

az elérhető a Visual Studio Add Reference dialógusából (4-20 ábra).Silverlight Toolkit for Windows Phone7 </controls:PanoramaItem> <!--Panorama item two--> <controls:PanoramaItem Header="item2"> <Grid/> </controls:PanoramaItem> </controls:Panorama> </Grid> A dolog látványossá tételéhez csupán egy széles háttérkép hiányzik. így ennek kipróbálására most nem térünk ki. Ilyeneket könnyen találunk az interneten. de számos ismétlődő feladat még így is ránk hárul.codeplex. Ezek elvégzését könnyíti meg a Silverlight Toolkit. Miután telepítettük a csomagot.jpg" /> </controls:Panorama. 105 . Silverlight Toolkit for Windows Phone7 Az eddig bemutatott vezérlőkkel már egy gazdag eszközkészletből válogathatunk. ami új vezérlők felkínálásán túl a Metro stílus kialakításában is hasznos társunk lehet.Background> <ImageBrush ImageSource="Images/bgPanorama. Telepítés A készlet használatához töltsük le a telepítőt a projekt hivatalos weblapjáról: http://silverlight. beágyazásuk pedig a Background tulajdonság hozzáadásával történik (4-19 ábra): <controls:Panorama.Background> 4-19 ábra: Panorama egy háttérkép megadása után A táblázatban kiemelt különbségeken túl a Pivot használata teljesen megegyezik a Panorama vezérlőjével.com.

assembly=Microsoft.1\Toolkit\Aug11 \Bin\Microsoft. akkor keressük ki a Microsoftos SDK-k közül! Nálam ez a szerelvény itt található: C:\Program Files\Microsoft SDKs\Windows Phone\v7.Phone. 4-21 ábra: A HubTile állapotai Ezt a vezérlőt az alábbi módon illeszthetjük be a felhasználói felületbe:: <toolkit:HubTile Name="hirekTile" Tap="hirekTile_Tap" Title="Hírek" Source="Images/news. a már ismert módon adjuk hozzá a névteret a leíráshoz: xmlns:toolkit="clrnamespace:Microsoft.Phone.Controls.4. amelyek az egyszerű navigáción túl információt.Toolkit" Fontosabb vezérlők HubTile – A főoldal lapkáihoz hasonló dinamikus vezérlő. üzeneteket is szolgáltatnak a felhasználó számára (4-21 ábra). hogy az elemeket a XAML-ben is elérjük.png" Background="#E51400" GroupTag="TileGroup" Margin="6" Notification="1 új hír" DisplayNotification="True" Message="Microsoft Minősített Szerviz Partner project"> MultiselectList – Az Office alkalmazás levéllistájához hasonlóan lehetővé teszi.Controls.Phone. 106 . hogy a felsorolt elemek közül többet is kiválasszunk (4-22 ábra). nagyszerűen használható menük kialakítására.Controls.dll Ahhoz. Haladó alkalmazásfejlesztés Windows Phone-on 4-20 ábra: A Toolkit szerelvénye a telepítés után elérhető Ha mégsem találjuk itt.Toolkit.

Items> <TextBlock Text="Alelem 1" /> <TextBlock Text="Alelem 2" /> </toolkit:ExpanderView. elem" /> </toolkit:MultiselectList> ExpanderView – Szintén a leveleknél (pontosabban a hosszabb levélváltásoknál) megszokott lista. elem" /> <toolkit:MultiselectItem Content="2.Expander> <Rectangle Height="80" Width="400" Fill="Blue" /> </toolkit:ExpanderView.Silverlight Toolkit for Windows Phone7 4-22 ábra: A levelek kiválasztásakor is egy ugyanilyen funkcionalitású vezérlővel találkozunk Használata: <toolkit:MultiselectList> <toolkit:MultiselectItem Content="1.Items> </toolkit:ExpanderView> 107 . 4-23 ábra: Hasonló vezérlő a levélváltások részletezésénél Ezt a vezérlőt az alábbi módon használhatjuk: <toolkit:ExpanderView> <toolkit:ExpanderView. és a részletei is láthatóvá válnak (4-23 ábra). elem" /> <toolkit:MultiselectItem Content="3. amelynek egy elemét kiválasztva az lenyílik.Expander> <toolkit:ExpanderView.

ha horizontálisan görgethető elemeket használunk a lapon. például galériákat megjeleníteni (4-24 ábra). az egyik szövegesen kiírja a jelenleg beállított időpontot. A StackPanellel szemben. Két nézettel rendelkezik. ami lezárja az aktív lapot. az időpontot beállító elrendezést láthatjuk (4-25 ábra). hogy például egy ScrollBar értékét kívánjuk módosítani. akkor a kitöltést a következő sorban (oszlopban) folytatja.4. Ezzel egyszerűen tudunk ismeretlen elemszámú listákat. Ez hasznos lehet. ha eléri a sor (vagy oszlop) végét. 4-25 ábra: A TimePicker két nézete 108 . hiszen ilyenkor nem egyértelmű. azaz nem tudunk róla a telefon kezeléséhez használt gesztusok segítségével a környező lapokra navigálni. Haladó alkalmazásfejlesztés Windows Phone-on LockablePivot – Kiegészíti a Pivotot egy zárolási lehetőséggel. 4-24 ábra: WrapPanel horizontális elrendezéssel Használata: <toolkit:WrapPanel> <toolkit:HubTile Background="Green" Title="Zöld" /> <toolkit:HubTile Background="Red" Title="Piros " /> <toolkit:HubTile Background="Blue" Title="Kék" /> </toolkit:WrapPanel> TimePicker – Időpontok megadására használható vezérlő. az Alarm alkalmazásból ismerhetjük. PageTransitions – Az oldalak közti átmenetet kísérő animációk használatát megkönnyítő osztály. A StackPanelhez hasonlóan egymás mellé vagy alá helyezi az elemeket az Orientation tulajdonságától függően. Segít a megszokott Metro stílusú átmeneteket egységes módon használni. erre kattintva pedig a másik. WrapPanel – A Panel osztályból származó konténertípus. vagy egyszerűen csak lapoznánk.

0.ContextMenu> <toolkit:ContextMenu> <toolkit:MenuItem Header="Menü 1" Click="MenuItem_Click" /> </toolkit:ContextMenu> </toolkit:ContextMenuService.0" Style="{StaticResource PhoneTextTitle1Style}"/> 109 . <Grid x:Name="LayoutRoot"> <Grid. A menü megjelenésén túl a hivatkozó vezérlő ki is emelkedik a többi közül. a menü előállításában pedig a ContextMenu vezérlő segít minket.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid. a háttérben pedig látható a kiemelő effekt Használata: <toolkit:HubTile Tap="hirekTile_Tap" Title="Minden" Source="Images/all.0. Ez a menü mindig egy másik vezérlőhöz kapcsolódik.png" Margin="6" Background="#FF008000" GroupTag="TileGroup" Notification="Noti" Message="Microsoft Minősített Szerviz Partner project"> <toolkit:ContextMenuService. akkor az elemre vonatkozó menü ugrik fel. informatív és esztétikus menüt tartalmaz. a ContextMenuService-t kell felvennünk a funkcióval kiegészítendő kontrollba. A WP7 platformon ezt a viselkedést egy elem hosszan lenyomva tartásával érhetjük el. ami a toolkit előnyeit felhasználva egy áttekinthető. hiszen tájékoztatja a felhasználót a fontos funkciókról.Silverlight Toolkit for Windows Phone7 Használata: <toolkit:TimePicker Name="tpAlarm"/> ContextMenu – A PC-ken megszokhattuk.Row="0" Margin="12.17. így az animálással sem kell külön foglalkoznunk (4-26 ábra). üzeneteket jeleníthet meg és látványos. animált felületet is biztosít.28"> <TextBlock x:Name="PageTitle" Text="OEM Portal" Margin="9.Background> <ImageBrush ImageSource="Images/tileBg. így gyakorlatilag egy szolgáltatást. 4-26 ábra: ContextMenu 1 elemmel.png" /> </Grid.Background> <Grid. hogy ha egy elemre kattintunk az egér jobb gombjával. pontosabban ezt kivéve minden más kissé távolabbra kerül.RowDefinitions> <!--TitlePanel contains the name of the application and page title--> <StackPanel x:Name="TitlePanel" Grid. Egy ehhez hasonló lap remek belépési pont lehet bármely alkalmazás számára.ContextMenu> </toolkit:HubTile> Példaprogram Hozzunk létre egy olyan oldalt.-7.

png" Background="#E51400" GroupTag="TileGroup" Margin="6" Notification="1 új hír" DisplayNotification="True" Message="Microsoft Minősített Szerviz Partner project"> </toolkit:HubTile> <toolkit:HubTile Tap="hirekTile_Tap" Title="Letöltés" Source="Images/downloads.png" Background="#297FD5" Margin="6" GroupTag="TileGroup" Notification="2 új hír" DisplayNotification="True" Message="Microsoft Minősített Szerviz Partner project"> </toolkit:HubTile> <toolkit:HubTile Tap="hirekTile_Tap" Title="Esemény" Source="Images/calendar.Row="1" Margin="12.place additional content here--> <toolkit:WrapPanel x:Name="ContentPanel" Grid.png" Margin="6" Background="#A500FF" GroupTag="TileGroup" Notification="Noti" Message="Microsoft Minősített Szerviz Partner project"> </toolkit:HubTile> </toolkit:WrapPanel> </Grid> A fenti kód pedig (természetesen a képek Images mappába másolása után) a 4-27 ábrán látható megjelenést eredményezi.ContextMenu> </toolkit:HubTile> <toolkit:HubTile Name="hirekTile" Tap="hirekTile_Tap" Title="Hírek" Source="Images/news.png" Margin="6" Background="#FF00FF" GroupTag="TileGroup" Notification="Noti" Message="Microsoft Minősített Szerviz Partner project"> </toolkit:HubTile> <toolkit:HubTile Tap="hirekTile_Tap" Title="Akció" Source="Images/akcio.png" Margin="6" Background="#FF008000" GroupTag="TileGroup" Notification="Noti" Message="Microsoft Minősített Szerviz Partner project"> <toolkit:ContextMenuService. Haladó alkalmazásfejlesztés Windows Phone-on </StackPanel> <!--ContentPanel . 110 .0.png" Margin="6" Background="#FFF79608" GroupTag="TileGroup" Notification="Noti" Message="Microsoft Minősített Szerviz Partner project"> </toolkit:HubTile> <toolkit:HubTile Tap="hirekTile_Tap" Title="Info" Source="Images/info.0"> <toolkit:HubTile Tap="hirekTile_Tap" Title="Minden" Source="Images/all.ContextMenu> <toolkit:ContextMenu> <toolkit:MenuItem Header="Menü 1" Click="MenuItem_Click" /> </toolkit:ContextMenu> </toolkit:ContextMenuService.12.4.

Ezekkel a módszerekkel nemcsak hogy rendkívül egyszerűen valósíthatunk meg komplex alkalmazásokat.Összefoglalás 4-27 ábra: HubTile-ok WrapPanelbe csomagolva Összefoglalás A fejezet elején részletesen megismerkedhettünk a Bing Maps szolgáltatás felhasználási lehetőségeivel. azokon belül pedig a Panorama és Pivot vezérlőket. Ezt követően átnéztük a tartalmak rendszerezésére szolgáló műveleteket: az oldalak kezelését. Végül a Silverlight Toolkit előnyeit ismerhettük meg. 111 . de könnyedén varázsolhatjuk a Metro stílushoz és a Mango felhasználói felület koncepciójához illeszkedő megjelenésűnek azokat. ezek között a kiemelt pozíciók jelölésével. az egyszerű címkereséssel és az útvonaltervezéssel.

.

A felhasználót megtévesztjük a gyors CPU-nak köszönhetően és elhitetjük vele. hogy valóban egyszerre futtat számos programot. Asztali operációs rendszerek esetében már nem igazán találkozhatunk olyannal. mint a multitasking-rendszer ütemező komponenséről. Az alkalmazás életciklusa Az előző fejezetek átolvasása után egyre boldogabban tarthatjuk kezünkben Windows Phone telefonunkat. Minden új technológia rendelkezik saját karakterisztikával. és mégis rendkívül ismerős azoknak. de akár az operációs rendszer súgójának olvasása közben is belefuthatunk. hanem onnan folytathassa. A Windows Phone 7. azonban a Windows Phone 7 első verziójában ezt még nem találjuk – legalábbis a fejlesztők által használható módon nem.NET világában. hogyan tudjuk elmenteni a felhasználó által kialakított állapotot és azt a következő indításkor helyreállítani.5 (a továbbiakban csak a kódnevén említve Mango) újdonságai között nagyon fontos újra megismerkedni egy régi ismerőssel. ahol abbahagyta. amely lehetővé teszi. De miért is ebben a fejezetben tárgyaljuk a fent említett. Egyetemi óra keretein belül. milyen feladatokat kell ellátnunk az alkalmazás indulásakor és kiléptetésekor. de valójában nem másról van szó. mely egyedibbé. Megnézzük. amely ezt a rendszert ne tartalmazná. Mielőtt továbbhaladunk a funkcionalitás megismerésében.5 esetében is teljes mértékben igaz. amelyek elérhetőek saját alkalmazásunkból és a telefon beépített eszközeiből is. hanem a központi feldolgozóegység (CPU) kapacitását kihasználva ezek a programok egymás mellett dolgozhassanak. hogy igazodtunk az eredeti feltevéshez. akik jártak már a . amellyel apró darabokra szétbontva a csomagokat a háttérben végezhetünk szerver-kliens kommunikációt. mi minden történik a háttérben az alkalmazás indulásától a back vagy a Start gomb lenyomásáig. Számos olyan megoldás van a kíváncsi szemek elől elrejtve. azaz a belső ütemező rendszer. Lehetőségünk van riasztások és naptárbejegyzések készítésére és felügyeletére is. Az alapötlet szerint a multitasking azért felelős. megfelelően teret engedve egymásnak. azonban közelről tekintve ez nem igaz. Ez Windows Phone 7. egymástól teljes mértékben különböző dolgokat? A közös dolog bennük: ezek mind a háttérben képesek dolgozni! Multitasking A fenti kifejezéssel valószínűleg már mindenki találkozott valahol. Háttérben futó adatszinkronizációt is megvalósíthatunk alkalmazásunkban. amely nem más. valahol az operációs rendszer lelkén belül.5. ezzel biztosítva. most már mi magunk is láthattuk. A teljes fejezet célja – jól áttekinthető formában – megismerkedni az alkalmazások működésének keretével. mint a multitasking. az internetet böngészve. hogy egyszerre több alkalmazás osztozhasson a telefon biztosította erőforrásokon. A következőkben választ fogunk rá kapni. elterjedt mobilplatform esetében. Ezek után tovább folytatjuk az ismereteink bővítését olyan újdonságok áttekintésével. így ezeket egymás után nagyon gyorsan végrehajtva valóban a párhuzamosság érzetét kapjuk. amely teljesítményben és funkcionalitásban rendkívül sokat hozzátesz a rendszer működéséhez. hogy miért is volt ez így. hogy az operációs rendszer egyszerre ne csak egy alkalmazást tudjon futtatni. átnézni. kicsit vissza kell vennünk a lendületből és tartani egy apróbb kitérőt. A való világra levetítve a dolgot makroszkopikusan nézve még mondhatjuk. amely a végrehajtandó feladatokat a legoptimálisabb módon juttatja el a központi egységhez. hogy ezekre az eszközökre fejleszteni majdnem minden apró mozzanatát tekintve más. az addig megszokottól különbözővé teszi. mint a zenelejátszóval való integráció vagy a hardveres hangerő-szabályozó gombok kezelése. 113 . mint a többi. hogy a felhasználónak a munkáját ne kelljen elölről kezdenie.

A legegyszerűbb megoldás úgy néz ki. Itt minden folyamat kap egy prioritási értéket. A feladatunk az. ezért az operatív memóriánkat is a lehető legjobban be kell osztanunk.5. azonban véleményem szerint nagyon érdekes téma. hogy egyszerre. a GPU (grafikus számítási egység) és egyéb vezérlők szerepeinek felvállalása minimális energiaellátás és hűtés hiánya mellett! Amikor telefonunkon egy játékkal játszunk. majd ha C végzett. akkor megint A folyamat kerül előre a sorban. elemi szintű folyamatokról beszélünk). Elsőre ez a különbség nem tűnik olyan nagynak! Az én laptopomban négy processzormag van 2. asztali operációs rendszerek esetében ma már fel sem merül. mindegyik kap lehetőséget felszólalni. hogy egyszerre csak egy programot szolgál ki.2 GHz-es teljesítménnyel. amiket a számítógépünk − azonban a laptop és a telefon között is van néhány hatalmas különbség. Nem beszélve arról. ha pedig túl hosszú egy intervallum. de a kettő a valóságban összehasonlíthatatlan. és az addigi nézetek új irányba tolódtak el. mi ezzel a probléma. Ahhoz. és a számítási sorok végén az eredményeket nagy szélességű buszokra továbbítják. egymás mellett futnak az alkalmazásai. a processzor szemszögéből nézzük a problémát. Miért? A számítógépem processzora rengeteg segédprocesszort. és annak kell biztosítania a másodpercenkénti 30 képkockát (telefonokon ez a szabványos képkockaszám másodpercenként) ahhoz. és a legmagasabb prioritású megkezdheti a futását. és nagy előnye. ezzel gazdálkodhat egy menetben. Okos telefonok. hogy egy játék élvezhető legyen. Ebből látszik. és lassan elképzelni sem tudjuk ezek nélkül az életünket (főleg amióta a szó minden értelmében közösségi lények vagyunk). A fenti algoritmust round-robin ütemezési algoritmusnak hívják. És az utolsó mondatból következik még egy probléma! Ha van egy nagyobb prioritású folyamatunk. Jön először A folyamat. miszerint semelyik folyamatot nem éheztetjük ki. ezt úgy hívjuk. szintén csillogó szemekkel kell. Ez matematikailag pont a fele lenne. Azonban. így 50 ms üresen marad. nézzünk egy példát! A folyamatnak összesen 350 ms időre lesz szüksége ahhoz. Ezek a segédprocesszorok villámsebességgel végeznek el számos összetett aritmetikai műveletet. és ezeket úgy kellene ütemeznünk a processzor felé. egyik folyamatot sem éheztetjük ki. Az alkalmazás életciklusa A feladatütemezés elméletben Ez a rész talán nem illeszkedik szorosan a könyv témájához. Ez esetben négyszer fog magának lefoglalni egy 100 ms hosszú intervallumot. Egyetlen apró chip feladata a CPU. dolgozik 100 milliszekundumig. utána jön C. hogy tekintsen a számítógépes algoritmusokra és különböző matematikai problémákra. hogy SoC (System on a Chip). míg a telefonomban két processzormag 1. hogy észrevegyük. Ahogy azt már említettem. táblagépek.4 GHz-es órajelen üzemeltetve. akkor a túl sok váltás lassuláshoz fog vezetni. hogy elvégezzen minden számítást. utána őt követi B. és nagyon sokat segít a Mangóban lévő megoldás megértésében – persze ahhoz. hogy ugyanazokat a feladatokat lássák el. bevezetjük itt is az időszeleteket. hogy az egymás mellett futó alkalmazások állapotait meg kell tartani. hogy a hatalmas számítási kapacitás mellett egy operációs rendszer megengedje magának azt a luxust. Azt várjuk el ezektől a kütyüktől. annak a számítási feladatai mind ugyanahhoz a chiphez futnak be. Ha túl rövid egy időszelet. hogy van X darab folyamatunk (itt ne Windows vagy egyéb operációs rendszer folyamatra gondoljunk. Azonban az utóbbi évek során az informatika átesett egy újabb – és egyben sokadik – metamorfózisán. hogy mindegyik folyamat dolgozhasson valamennyit. hogy az elején megelőzzünk súlyos problémákat . beágyazott rendszerek jelennek meg sorra és mindegyik valamelyik népszerű operációs rendszer mobilizált változatát használja fedélzeti szoftverként. hogy könnyen implementálható. valamint ehhez tartozó magas áteresztőképességű vezetőrendszert tartalmaz. Azonban vannak hátrányai. akkor ő ki lesz éheztetve. de az utolsó iterációban 50 ms alatt befejezi a feladatát és terminál. hogy 50 ms processzoridő el lett pazarolva. Gyorsan hozzászoktunk. megfelelő energiaellátás és hűtés mellett. Egységesen mindegyik kap például 100 ms processzoridőt. hogy azt mondjuk. csak jobban bele kell gondolni. és így a felhasználó azt az érzetet kapja. A legmagasabb 114 . közvetlenül elérhető és másodlagos tárat. akkor alacsonyabb időigényű folyamatok el fogják pazarolni a nagyobbak elől a számítási időt.mint például a végtelen ideig tartó futás . azonban csak bizonyos ideig. Ezzel szemben a telefonom a számítógépem drabális hardvereit egyetlen chipbe tömöríti.illetve optimalizáljunk is. Ezeken a problémákon hivatott segíteni a prioritásos ütemezés algoritmusa. hogy ezt a kedves Olvasó is át tudja érezni. ezek alapján csökkenő sorrendbe állítjuk őket. és ez alaposan ellentmond az eredeti feltevésünknek.

Multitasking prioritású futhat bizonyos ideig, azonban ha lejárt az idő, akkor a következő legmagasabb prioritású kap processzoridőt. A végtelen futás elkerülésének érdekében pedig minden iteráció végén csökkentjük a prioritási értéket, így az eddig legmagasabb prioritású „kevésbé lesz fontos” a következő körben. A mai modern operációs rendszerek is ilyen alapelvekre épülnek, és azt gondolom, a fenti példák és számolások után senki számára sem kétséges, hogy egy mobiltelefon esetében ezeknek az optimális implementálása komoly kihívást jelent. A helyzet messze nem olyan „egyszerű”, mint az operációs rendszerek nagy testvérei esetében: meg kell találni az arany középutat az energiaigény, hardver kihasználása és teljesítménye között.

A multitasking megvalósítása WP 7.5 platformon
Az eredeti Windows Phone 7 operációs rendszer nem tartalmazta a multitasking lehetőségét (ellenben több szálú alkalmazásokat írhattunk), ez a Mango frissítéssel jött. Azonban gondoljunk csak bele jobban, mit is jelent egy mobiltelefon esetében az, hogy több programot futtat! Nincs tálca, ahol egy szempillantás alatt válthatunk az alkalmazások között, nincsenek ablakok, ahol egymás takarásában futnak a programok külön rajzterületeken. Akkor mit nyerhetünk több program futtatásával? A választ két részben kapjuk meg. Először is nézzük az eredeti Windows Phone 7 operációs rendszert! Ha bezártunk egy alkalmazást, vagy az alkalmazás valamilyen okból passzív státuszba került (alkalmazásfelületek között navigálunk pl. egy fénykép készítésekor, vagy túl sokáig nem használtuk a telefont, és ő elment pihenni, stb.), akkor valahova el kellett menteni az aktuális állapotot, majd amikor visszatért a felhasználó az alkalmazáshoz, akkor vissza kellett tölteni az előzőleg elmentett adatokat. A válasz másik része pedig még sokkal szembetűnőbb! Böngészünk, és közben szeretnénk zenét hallgatni. A telefonnal érkezett, Microsoft által készített alkalmazások esetében ez eddig is működött! Mi is azt szeretnénk, hogy a saját alkalmazásunkban lejátszott zene akkor is tovább folytatódjon, ha éppen nem a saját alkalmazásunk aktív vagy a telefon aludni tért. Igen, erre mostantól fogva lehetőségünk van! Nem kell egyszerre látnunk az alkalmazásokat egy kis képernyőn, nem kell ablakban futniuk, ettől még ott lehetnek a háttérben, és ugyanúgy szükségük lehet a processzorra. A Microsoft az eredeti Windows Phone 7 operációs rendszerben nem akarta a telefonok korlátozott hardver erőforrása, energiaigénye és az alkalmazás életciklus-modellje miatt bevezetni a multitaskingot. Ezt azonban előbbutóbb kénytelen volt implementálni, hiszen olyan képességről beszélünk, amelyet nem lehet kikerülni. Az 5-1 ábrán látható, hogyan is épül fel egy alkalmazás életciklusa. Az egész egyetlen nagy állapotgéppel írható le, amelynek középpontjában az az állapot áll, amikor az alkalmazás fut. Azonban mi van olyankor, ha nem fut éppen? Több minden is történhet. Megmaradt az előbbiek során ismertetett állapotmentés mechanizmus is, de ez tovább bővült azzal, hogy a Windows Phone ütemező rendszere eldöntheti, mit tesz az alkalmazásunkkal, és az például egy navigációs művelet során ott maradhat a memóriában. Az állapotok mentésének a későbbiekben több módját is megnézzük, és láthatjuk majd, hogyan válthatunk gyorsan az alkalmazások között − a multitaskingnak köszönhetően.

115

5. Az alkalmazás életciklusa

5-1. ábra: A Windows Phone 7.5 alkalmazások állapotai Nézzük meg, hogy az egyes állapotok és események mit jelölnek! A későbbiek során még számos alkalommal hasznosnak bizonyulhat ez a tudás.  Launching esemény: új alkalmazáspéldányt indítottunk, azaz kiválasztjuk a Start felületen vagy az alkalmazáslistából az alkalmazás lapkáját, esetleg egy értesítéshez tartozó üzenet. Ha az alkalmazás logikája nem igényel mást, akkor itt ne folytassunk munkafolyamatot, ez valóban egy teljesen új példány legyen – persze ez alól vannak kivételek. Ez a kódból kezelhető állapotok közé tartozik. Továbbá fontos, hogy itt erőforrásigényes műveletet ne végezzünk, az alkalmazást engedjük betöltődni minél gyorsabban, nagyobb adategységek betöltését mögöttes szálon hajtsuk végre! Vannak olyan alkalmazások, ahol a státusz nem fontos (például egy közösségi oldal kliense, ahova az új híreket az alkalmazás következő indításakor újra le fogjuk tölteni). Azonban gondoljunk például egy képszerkesztő programra, ahonnan véletlen a vissza gombhoz érve kiléptünk. Amikor visszatérünk az alkalmazásba, szeretnénk az előző munkafolyamatot folytatni, így vigyáznunk kell arra, hogy az állapotot folyamatosan mentsük az adatvesztés elkerülése végett. Továbbá vigyázzunk, hogy nagy adatmennyiségeket ne töltsünk be és mentsünk ki egyszerre, ezt a feladatot végezzük el egy mögöttes szálon! Running: az alkalmazás egészen addig „futtatás alatt” állapotban fog maradni, amíg valamilyen felhasználói interakció hatására nem navigálunk valamerre, vagy éppen a felhasználó interakció hiányában a telefon nem tér aludni. OnNavigatedFrom esemény: akkor játszódik le, ha a felhasználó elnavigál az adott alkalmazásfelületről, vagy az alkalmazás deaktivált állapotba került. Itt el kell mentenünk az

116

Állapotok kezelése aktuális oldal állapotát, és ha a felhasználó visszatér ide, akkor helyre kell állítanunk. Érdemes még figyelni arra is, hogy ha visszafelé szeretnének navigálni az adott oldalról, akkor nem kell állapotot mentenünk, mivel a következő alkalommal, mikor ide visszatér a felhasználó, újra létrejön a felület. A megvalósítás módja természetesen nagyban függ az alkalmazás logikájától.  Deactivated esemény: ez az állapot akkor jelentkezik, ha a felhasználó átvált egy másik alkalmazásra, vagy megnyomja a Start gombot, illetve ha hosszú ideig nem volt felhasználói interakció, és a telefon zárolódik. Fontos megemlíteni, hogy ez az állapot következik be akkor is, ha valamilyen Chooser segítségével az alkalmazás az operációs rendszer beépített eszközeit szeretné használni, például a kamerát, kép kiválasztását, e-mail üzenet írását, és így tovább. Ennek az eseménynek a hatására mindenképpen el kell mentenünk az alkalmazás állapotát! Ennek módját a későbbiek során részletesen megnézzük. Dormant: miután a Deactivated állapot bekövetkezett, az alkalmazás folyamata és a hozzá tartozó szálak leállításra kerülnek, a rendszer még megpróbálja az alkalmazáshoz tartozó adatokat a memóriában tartani, hogy így azok később gyorsan visszanyerhetők legyenek. A folyamat teljesen automatikus, azonban legyünk vele óvatosak, mivel ha az alkalmazásunk után egy erőforrásigényesebb alkalmazást indít a felhasználó, akkor a mi alkalmazásunk valóban lezárásra kerül! Az esemény hatására le kell mentenünk az állapotát, az eddig elfoglalt memóriaterület pedig felszabadításra kerül. Tombstoned: a Windows Phone 7 rendelkezik egy Dictionary<T > típusú gyűjteménnyel, amelyen keresztül objektumokat menthetünk el. Ennek működését még részletezni fogjuk, azonban a mechanizmus ebben az állapotban nyeri el igazán az értelmét. Az alkalmazás leállításra kerül, az adatokat nem őrzi meg automatikusan a rendszer, de a fent említett gyűjteményt elmenti, így onnan vissza tudjuk majd az állapotot tölteni. Vigyázzunk vele, mert ha a telefont pl. újraindítják, akkor a gyűjtemény elveszik, így ebben az esetben más utat kell választanunk! Activated esemény: ha Domant vagy Tombstoned állapotból tér vissza az alkalmazásunk, akkor az Activated esemény fog lejátszódni. Itt tudjuk leellenőrizni, hogy hova volt az állapot elmentve, és ettől függően tudjuk visszaállítani. OnNavigatedTo esemény: akkor következik be, amikor a felhasználó egy új alkalmazásfelületre navigál, vagy amikor az adott lap az alkalmazás indulása után először kerül betöltésre. Itt szükséges leellenőrizni azt, hogy egy új példányra van-e szükségünk, vagy egy lementett állapotot szeretnénk helyreállítani! Closing esemény: az alkalmazás lezárása előtti utolsónak lezajló esemény. Nagyon fontos vigyázni arra, hogy itt maximum 10 másodpercig tartózkodhat az alkalmazás, ha ezt túllépi, a folyamatban lévő műveletek befejezése nélkül fog leállni. Itt tehát nem célszerű erőforrásigényes műveleteket használnunk!

Állapotok kezelése
Az előző részekben alaposan végignéztük, hogy mi minden történik a háttérben, amelyből mi semmit sem látunk. Megnéztük, milyen állapotok között ingázik egy alkalmazás az életciklusa során, és milyen teendőink vannak az egyes esetekben. Egy dolgot azonban még nem láttunk: Hogyan kell ezeket gyakorlatban megvalósítani?

Életciklus-események kezelése
Az 5-1. abrán láthattuk, mely eseményekkel kell foglalkoznunk, és az ábrát követő leírásban szerepelt szövegesen is, hogy az egyes eseményeknél mi a tennivalónk. Az áttekinthetőség kedvéért az alábbi táblázatban összefoglalom az eseményeket és a hozzájuk tartozó műveleteket:

117

5. Az alkalmazás életciklusa

Esemény Launching Activated Deactivated Closing OnNavigatedFrom OnNavigatedTo

Végrehajtandó művelet Minimális kód, semmi erőforrásigényes műveletet ne végezzünk! Állítsuk helyre az állapotot, ha lehet FAS (Fast Application Switching) segítségével! Mentsük el az állapotot! Ha lezáródott az alkalmazás, akkor biztosítsuk a perzisztens tárolást! Utólagos műveleteket végezzünk, vigyázzunk a 10 másodperces időhatárra! Ha nem visszafelé navigálunk, akkor mentsük el az adott felhasználó felülethez tartozó állapotot! Amennyiben nem egy új példányra van szükségünk, a tárból állítsuk helyre az alkalmazás állapotát!

Tanács: Egy Windows Phone alkalmazás ne tartalmazzon opciót a kilépésre, ezt a feladatot hagyjuk meg a telefon vissza gombjának! Próbáljuk ki mindezt a gyakorlatban! Indítsuk el a Visual Studio 2010-et, és hozzunk létre egy új projektet a File  New  Project parancs segítségével! A megjelenő dialóguson a C# nyelvű Silverlight for Windows Phone szekcióból válasszuk ki az egyszerű Windows Phone Application sablont, és az alkalmazásnak adjuk az AppLifecycle nevet (5-2 ábra)! A fejezet során végig ezt a projektet fogjuk használni.

5-2. ábra: A fejezethez szükséges projekt létrehozása Ha megnyitjuk az App.xaml.cs fájlt, akkor láthatjuk, hogy a fenti táblázatból négy különböző eseményvezérlő már előre el lett készítve. Pillanatnyilag még nem tudjuk őket semmilyen hasznos dologra felhasználni, azonban azért, hogy lássuk azok végrehajtási sorrendjét, helyezzünk el minden eseményvezérlőhöz egy töréspontot, ahogyan az 5-3. ábrán is látható! A megjelenő felületen válasszuk a

118

Állapotok kezelése Windows Phone 7.1 beállítást és hagyjuk jóvá! Ha ezzel megvagyunk, akkor hajtsuk végre a következő lépéseket, és figyeljük meg, hogy az egyes esetekben hol áll meg a kód végrehajtása!     Az F5 segítségével Debug üzemmódban futtassuk az alkalmazást! Ennek hatására elindul az emulátor. A kód végrehajtása megáll az Application_Launcing eseménykezelőnél. Ez a működés annak tudható be, hogy az alkalmazásnak ez volt az első elindítása. Ezután az emulátoron nyomjuk le a Start gombot! Ennek hatására úgy tűnik, mintha az alkalmazásunk kilépett volna. A Visual Studio most az Application_Deactivated eseménykezelőn elhelyezett töréspont hatására megáll. Az alkalmazás állapota megváltozott, és ha valamilyen logika már megvalósításra került volna, akkor itt kellene a állapotot mentenünk. Két eseményünkkel még nem találkoztunk, ezért F5 segítségével újra indítsuk el az alkalmazást! Az újra meg fog állni a Launching eseménynél. Léptessük tovább! Most az emulátoron nyomjuk le a Back (vissza) gombot, és figyeljük meg, hogy mi történik! Megállt a végrehajtás az Application_Closing eseményvezérlőnél. Ez azt jelenti, hogy innentől fogva 10 másodpercünk van az alkalmazás állapotának elmentésére, utána végérvényesen kilépünk!

  

Az Application_Activated eseményvezérlő egyszer sem került meghívásra. Ezt az okozta, hogy az alkalmazást egyszer sem futtattuk le az emulátoron található példány újrafuttatásával. Ezt hiába is próbáltuk volna meg, a Visual Studio hibakereső elengedi az alkalmazáspéldányunkat, miután megnyomtuk a Back vagy Start gombok valamelyikét.

5-3. ábra: töréspontok elhelyezése az App.xaml.cs fájlban Egyelőre nem sok minden történt, mindössze láttuk, hogy melyik esemény mikor játszódik le. A következő részben alkalmazásunkat úgy alakítjuk át, hogy az elmentse a legutóbbi állapotot és a következő indításkor visszaolvassa azt.

Az alkalmazás állapotának mentése és helyreállítása
Ha az alkalmazásunk adatorientált, és a felhasználó által tett módosításokat el kell tárolnia, akkor a memóriában található objektumokat perzisztens tárolóba kell elmentenünk. Erre többféle lehetőségünk van (sőt, van ahol egy lehetőségen belül is több irányba ágazik el az út). Először is válasszuk szét a műveletet az alapján, hogy az alkalmazás véglegesen leállt-e, vagy csak szüneteltetésre került valamilyen formában! Tudjuk, hogy a szüneteltetésnek két módja is van. Ha Dormant állapotba került a telefon, azaz

119

5. Az alkalmazás életciklusa minden hozzá tartozó adat a memóriában maradt, akkor rendkívül gyorsan folytatható a munkafolyamat, manuálisan semmit sem kell helyreállítanunk. Ekkor kizárólag azt kell megvizsgálnunk, hogy használható-e a Fast Application Switching mechanizmus. Ezt az Application_Activated eseményvezérlőn belül tesszük meg:
private void Application_Activated(object sender, ActivatedEventArgs e) { if ( e.IsApplicationInstancePreserved ) { // dormant állapotban voltunk, nem kell semmit sem tennünk manuálisan } else { // sajnos nem dormant volt, vissza kell hoznunk az adatokat } }

Ha nem Dormant állapotban volt az alkalmazásunk, akkor nekünk kell gondoskodnunk az adatok mentéséről. Erre egyik lehetőségünk a Tombstoning állapotban használható PhoneApplicationService, amely tartalmaz egy Dictionary<T> típusú generikus gyűjteményt, és az ebben eltárolt objektumokat a telefon automatikusan elmenti, amikor a Deactivated esemény lejátszódik. Ennek nagy előnye, hogy szintén gyorsan visszanyerhetjük az adatokat, hátránya viszont, hogy ez nem teljesen perzisztens megoldás. Ha a telefont újraindítjuk, vagy egy frissítés miatt az alkalmazásunk véglegesen leáll, akkor az adatai elvesznek. Erre jelenthet megoldást az adatok szerializálása az Isolated Storage-ba. Miután közvetlen fájlrendszer hozzáférésünk nincs, de mégis a telefon tárkapacitását szeretnénk használni adatok mentésére, így ő az egyik megoldás. Számos szerializációs módszert használhatunk (bináris, JSON, XML, DataContract, stb.), azonban ezek közül egyik sem tud sebességben versenyezni az előző megoldásokkal. Másik lehetőség lenne a Mangóban megjelent SQL CE adatbázismotor használata − ezt részletesebben az adatkezeléssel foglalkozó fejezet tárgyalja. Alakítsuk át az alkalmazásunkat úgy, hogy az kilistázza a telefon színtémáit, és ha a felhasználó kiválaszt egyet, akkor azt láthatóvá teszi! Sajnos, ténylegesen a telefon témáját nem tudjuk kódból változtatni (legalábbis nem legálisan), talán majd egy következő Windows Phone verzióban. Hozzunk létre egy új osztályt, amely a színek nevét és hexadecimális kódját tárolja! Ahhoz, hogy az osztályból létrehozott példányokat menteni tudjuk (Isolated Storage vagy a telefon beépített PhoneApplicationService megoldása segítségével), annak sorosíthatónak kell lennie, mégpedig a DataContractSerializer segítségével. Az ehhez szükséges objektumok Windows Phone esetében is implementálásra kerültek, semmi mást nem kell tennünk, mint felvenni a System.Runtime.Serialization assembly-t a könyvtár referenciák közé!
[DataContract] public class PhoneTheme { [DataMember] public string Name { get; set; } [DataMember] public string HexValue { get; set; } }

120

Állapotok kezelése Szükségünk lesz egy egyszerű felhasználói felületre is, amely mindösszesen egy listát fog tartalmazni a ListBox vezérlővel megvalósítva. Miután saját entitásokkal dolgozunk, a vezérlő alapesetben nem lenne alkalmas azok megjelenítésére, így egy sablon segítségével átalakítjuk. Ennek hatására a háttere a tárolt szín lesz, és minden listaelem közepén szövegesen is megjelenik majd az entitás neve:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <ListBox x:Name="accentList"> <ListBox.Resources> <DataTemplate x:Key="AccentItemTemplate"> <Grid Width="400" Height="100" Margin="28,0,0,20" Background="{Binding HexValue}"> <Border BorderBrush="White" BorderThickness="2"/> <TextBlock HorizontalAlignment="Center" Text="{Binding Name}" VerticalAlignment="Center" FontSize="24" /> </Grid> </DataTemplate> </ListBox.Resources> <ListBox.ItemTemplate> <StaticResource ResourceKey="AccentItemTemplate"/> </ListBox.ItemTemplate> </ListBox> </Grid>

Most már van olyan entitás osztályunk, amely képes az elemeket tárolni, és van hozzá egy felhasználói felületünk, amely megjeleníti azokat. Hozzuk létre a tényleges listánkat is! Egyszerű esettel van dolgunk, elegendő lesz egy List<T> generikus listapéldány, amelyet helyben inicializálunk is az új elemek megadásával. Nyissuk meg a MainPage.xaml.cs fájlt, és hozzuk létre a következő adattagot:
private { new new new new new new new new new new }; List<PhoneTheme> themes = new List<PhoneTheme> PhoneTheme PhoneTheme PhoneTheme PhoneTheme PhoneTheme PhoneTheme PhoneTheme PhoneTheme PhoneTheme PhoneTheme { { { { { { { { { { Name Name Name Name Name Name Name Name Name Name = = = = = = = = = = "Blue", HexValue = "#FF1BA1E2" }, "Brown", HexValue = "#FFA05000" }, "Green", HexValue = "#FF339933" }, "Lime", HexValue = "#FFA2C139" }, "Magenta", HexValue = "#FFD80073" }, "Mango", HexValue = "#FFF09609" }, "Pink", HexValue = "#FFE671B8" }, "Purple", HexValue = "#FFA200FF" }, "Red", HexValue = "#FFE51400" }, "Teal", HexValue = "#FF00ABA9" },

Mielőtt elsiklanánk felette, szükségünk lesz egy metódusra, amely a szövegesen megadott színkódokat úgy alakítja át, hogy a Silverlight azt megjeleníthesse. De mit is tud a Silverlight megjeleníteni? Hiszen XAML kódban is névvel vagy hexadecimális kóddal adjuk meg a színeket, itt miért nem jó ez? A XAML-ben megadott kódot az objektum képes interpretálni, és a szükséges változtatásokat elvégezni automatikusan, azonban erre nincs lehetőségünk mögöttes kódból. Itt a Brush alaposztály valamelyik leszármazottját kell segítségül hívnunk, amely a mi esetünkben a SolidColorBrush lesz, ez egyszínű kitöltést tesz lehetővé. Ennek az objektumnak a konstruktora egy Color típusú objektumpéldányt vár, így a szövegesen megadott színkódunkat ilyen típusra kell átalakítanunk. Ennek az elvégzése rendkívül egyszerű:
private SolidColorBrush GetColorFromHex( string color ) { return new SolidColorBrush( Color.FromArgb( Convert.ToByte( color.Substring( 1, 2 ), 16 ), Convert.ToByte( color.Substring( 3, 2 ), 16 ),

121

5. Az alkalmazás életciklusa

Convert.ToByte( color.Substring( 5, 2 ), 16 ), Convert.ToByte( color.Substring( 7, 2 ), 16 ) ) ); }

Kattintsunk tervezői nézetben kettőt a telefon felületén, és a Visual Studio létrehozza a Loaded eseménykezelőt. Ebben első dolgunk az, hogy az előbb létrehozott listát átadjuk a felületen elhelyezett ListBox vezérlőnek. Ezt könnyedén megtehetjük, mivel a ListBox ItemsSource tulajdonságának a feltöltése után a Silverlight adatkötő motor automatikusan kivezeti a listaelemeket a felületre, ahol a vezérlő a nemrég létrehozott sablon segítségével meg is jeleníti azokat. Itt viszont lesz még egy feladatunk! Ha el volt mentve az állapot, akkor azt itt helyre kell állítanunk! Először nézzük ezt meg a telefon beépített eszközével megvalósítva, amelyet a PhoneApplicationService osztályon keresztül érhetünk el! Ennek az osztálynak van egy State nevezetű gyűjteménye, amelyen megvizsgáljuk, hogy tartalmazza-e a „Theme” nevű kulcsot. Ha igen, akkor nem először használjuk az alkalmazást, és korábban mentettünk már állapotot. Nincs is más dolgunk, mint kiolvasni a kulcshoz tartozó értéket és a felületen átállítani az adott színre a hátteret:
void MainPage_Loaded(object sender, RoutedEventArgs e) { accentList.ItemsSource = themes; if ( PhoneApplicationService.Current.State.ContainsKey( "Theme" ) ) LayoutRoot.Background = GetColorFromHex( ((PhoneTheme)PhoneApplicationService.Current.State[ "Theme" ]).HexValue ); }

Valahol az előbb betöltött objektumot el is kellett mentenünk, erre a legmegfelelőbb hely a listában kiválasztott elem változtatását jelző esemény. Ha a tervezői nézetben duplán kattintunk a ListBox vezérlőre, akkor a Visual Studio létrehozza a SelectionChanged eseménykezelőt, ezen belül dolgozunk tovább. Le kell kérdeznünk az aktuálisan kiválasztott elemet. Mivel az adatkötő motor felhasználásával a tényleges objektumpéldányokat adtuk át a ListBox-nak, így lekérdezhetjük magát az elemet, de ugyanúgy megfelelne az index is, mivel a forráslistát az osztály továbbra is tárolja:
private void accentList_SelectionChanged(object sender, SelectionChangedEventArgs e) { PhoneTheme theme = accentList.SelectedItem as PhoneTheme; LayoutRoot.Background = GetColorFromHex( theme.HexValue ); PhoneApplicationService.Current.State[ "Theme" ] = theme; }

Mielőtt futtatnánk az alkalmazást, tennünk kell a beállítások között is egy változtatást. A Mangóban a multitasking bevezetésével az emulátor is megváltozott. Ez alapértelmezésben nem engedélyezi a Tombstoning állapot tesztelését. Ahhoz, hogy ezt engedélyezzük, jobb egérgombbal kattintsunk a projekt nevére, és válasszuk a Properties opciót! Ezen belül válasszuk a Debug fület, és az egyetlen itt található „Tombstone upon deactivation while debugging” opciót jelöljük be! Ezek után futtathatjuk az alkalmazást.

122

Állapotok kezelése

5-4. ábra: Alvó állapot engedélyezése Visual Studióban A tesztelést a következő lépésekben végezzük el:       Indítsuk el Debug módban az emulátort és benne az alkalmazást! Válasszunk ki egy színt a listából, majd a Start gomb segítségével lépjünk ki! Itt be tudjuk tölteni az Internet Explorert vagy egy másik, az emulátorra telepített alkalmazást. Lépjünk ki a vissza gombbal, és térjünk vissza a saját alkalmazásunkhoz! Az állapota megfelelően helyre lesz állítva. (Ha nem a Resuming állapot következik be, akkor zárjuk be az emulátort, és fordítsuk újra a projektet, majd futtassuk újra!

5-5. ábra: Az alkalmazás futásának pillanatfelvételei A fenti módszer nem menti el az adatokat végérvényesen. Ha valóban perzisztálni szeretnénk azokat, akkor az Isolated Storage-ba kell mentenünk. Mivel általánosítható megoldást szeretnék mutatni és nem csak az alkalmazásra specifikusat, így az adatsorosítást választottam. Az entitásosztályt fel kell készíteni DataContractSerializerrel való együttműködésre, most ezt ki is próbáljuk. Szükségünk van egy alkalmazásszintű statikus példányra a PhoneTheme osztályból, a memóriában ide fogjuk menteni a felületen végzett változtatásokat, és ide fogjuk majd visszatölteni azokat. Ezenkívül két metódusra is szükségünk van még, az egyik feladata az adatok mentése, a másiké pedig azok visszatöltése.

123

5. Az alkalmazás életciklusa

public static PhoneTheme Theme { get; set; } private void SaveData() { using ( IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication() ) { using ( IsolatedStorageFileStream stream = file.CreateFile( "theme.xml" ) ) { // új DataContractSerializer példány, a megfelelő típussal ellátva DataContractSerializer serializer = new DataContractSerializer( Theme.GetType() ); // az objektum sorosítása a megnyitott adatfolyamra serializer.WriteObject( stream, Theme ); } } } private void LoadData() { using ( IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication() ) { // vizsgáljuk meg létezik-e már a fájl if ( !file.FileExists( "theme.xml" ) ) Theme = new PhoneTheme { Name = "Blue", HexValue = "#FF1BA1E2" }; else using ( IsolatedStorageFileStream stream = file.OpenFile( "theme.xml", FileMode.Open, FileAccess.Read ) ) { // létezett a fájl, így megfelelő típussal visszaolvassuk az adatokat. DataContractSerializer serializer = new DataContractSerializer( typeof( PhoneTheme ) ); Theme = (PhoneTheme)serializer.ReadObject( stream ); } } }

A beolvasás esetére megvizsgáltuk, hogy létezik-e már a fájl, így a LoadData() metódus is nyugodtan használható. Nincs is más dolgunk, mint az alkalmazás indításakor és leállításakor meghívni az oda tartozó metódusokat (nem szükséges megkülönböztetni, hogy milyen típusú indításról és leállításról van szó).
private void Application_Launching(object sender, LaunchingEventArgs e) { LoadData(); } private void Application_Activated(object sender, ActivatedEventArgs e) { if ( e.IsApplicationInstancePreserved ) { } else { LoadData(); } } private void Application_Deactivated(object sender, DeactivatedEventArgs e) { SaveData(); }

124

Folyamatok a háttérben

private void Application_Closing(object sender, ClosingEventArgs e) { SaveData(); }

A felhasználó felület mögöttes kódja az alábbiak szerint módosul, felhasználva az alkalmazásszinten elhelyezett statikus objektumpéldányt:
void MainPage_Loaded(object sender, RoutedEventArgs e) { accentList.ItemsSource = themes; LayoutRoot.Background = GetColorFromHex( App.Theme.HexValue ); } private void accentList_SelectionChanged(object sender, SelectionChangedEventArgs e) { PhoneTheme theme = accentList.SelectedItem as PhoneTheme; LayoutRoot.Background = GetColorFromHex( theme.HexValue ); App.Theme = theme; }

Folyamatok a háttérben
A fejezet elején említettem, hogy a Windows Phone 7 nem engedte az alkalmazásoknak, hogy amikor nem ők voltak előtérben, a háttérben műveleteket végezzenek. Részletesen leírtam, hogyan működik a multitasking, és ennek hiányában miért nem tehette az operációs rendszer ezeket a funkciókat elérhetővé.

Elméleti áttekintés
Alapesetben egy alkalmazásra úgy tekintünk, hogy annak az előtérben kell futnia. Azonban vannak olyan esetek, amikor szeretnénk, hogy olyankor is történjen valami, amikor a felhasználó éppen más alkalmazást futtat, vagy egyáltalán nem is használja a telefonját. Tipikus eseteket is felsorolhatunk:  Van egy zenelejátszó alkalmazásunk. A felhasználó valószínűleg nem fogja folyamatosan a kezében a telefonját, és nem használja aktívan, lehet, hogy közben egy könyvet olvas, vagy éppen a munkáját végzi. Ilyenkor a telefon alvó állapotba helyezné a lejátszónkat, és a zene lejátszása megszakadna. Szeretnénk, ha a zene lejátszása folytatódna a háttérben. Főzéshez készítünk egy időmérő alkalmazást, amelynek az a feladata, hogy bizonyos idő letelte után riasszon bennünket, így biztosan nem felejtjük ott tovább az ételt, és az nem fog odaégni. Főzés közben biztosan nem használjuk a telefonunkat, így ebben az esetben is kellemetlen lenne, ha alvó állapotba kerülne az alkalmazás. Megjegyzésként megemlíteném, akár azt is megoldhatjuk, hogy a telefon ne tudjon aludni, amíg manuálisan ki nem lépünk az alkalmazásból. Ezzel azonban az akkumulátort nagyon hamar lemeríthetjük, így használata nem javasolt. Időjárás-figyelő alkalmazást készítünk, amelynek extra funkciója, hogy vihar közeledése esetén időben riaszt bennünket. A funkció riasztáshoz kapcsolódó részére pontosan azok az elvek érvényesek, amit az előző listapontban említettem, viszont itt még valamivel számolnunk kell. Az időjárás-adatokat nem elegendő akkor lekérnünk egy webes szolgáltatástól, amikor a felhasználó az alkalmazásunkat használja, mert így nem biztos, hogy mindig a legfrissebb információkkal fogunk rendelkezni! Szinkronizálnunk kell a háttérben, ez pedig időről időre adatok letöltését jelenti – a felhasználó beavatkozása nélkül is.

A fenti példákat szándékosan választottam, még találkozni fogunk velük az alfejezetek során, ahol részletesen bemutatom ezeket az eseteket.

125

vagy a telefon zárolást feloldó képernyőjén található zenelejátszás kezelőfelületet is. vagy ha a felhasználó akarja.0. ResourceIntensiveTask: nagyobb számítási feladatok ellátására szolgál (pl.xaml-nek! A felületet az alábbi kódok szerint alakítsuk ki.0. A zene lejátszásáért felelős ágens mélyen az operációs rendszerben található Zune komponensbe van integrálva. akkor a háttérben élő folyamatok futtatási joga megvonható az alkalmazástól. Természetesen akkor is kikapcsolásra fognak kerülni. mint bármelyik zenénk a médiagyűjteményben. adatok tömörítése/kitömörítése). és így olyan forrásadattal dolgozhatunk.28"> <TextBlock x:Name="ApplicationTitle" Text="BACKGROUND AUDIO PLAYER" Style="{StaticResource PhoneTextNormalStyle}"/> <TextBlock x:Name="PageTitle" Text="play a song" Margin="9.Row="1" Margin="12. hogy a telefon számára fogyasztható audio formátumokkal kódolt zenei állományokra hivatkozzunk. és nevezzük el a fájlt AudioPlayerPage. Ha túl alacsony a telefon akkumulátorának a töltöttségi szintje.Row="0" Margin="12. és valamilyen gyorsan végrehajtható feladatot lát el. percben) meghívódik. így ugyanabban a bánásmódban részesül. amely a zenei információt képes dekódolni. a valós feladatok során ezek több speciális változatát vehetjük használatba. Amikor alkalmazásunk zenét játszik le. Itt vigyáznunk kell arra. Előre pontosan meghatározott feladatkör szerint dolgozhat alkalmazásunk a háttérben. Az AudioStreamingAgent esetében mi írhatjuk meg azt a komponenst. amely az a WPAppManifest. Ezeket az ágenseket Task típusok gyűjtik magukba. amilyennel csak szeretnénk. az csak egy lejátszás. A következő mintaalkalmazásban az AudioPlayerAgent-et használjuk fel.0. így hasznos.és egy hátratekerés gombot tartalmaz: <StackPanel x:Name="TitlePanel" Grid.xml fájlon keresztül kapcsolódik az alkalmazáshoz. ha most az elején elő is készítünk néhány MP3 zeneszámot a kedvenceink közül! Adjunk hozzá meglévő alkalmazásunkhoz egy új lapot! A projekt gyorsmenüjéből válasszuk ki az Add  New Item  Windows Phone Portrait Page parancsot. Sajnálatosan Windows Phone-ra eddig egyáltalán nem volt lehetőségünk saját lejátszók készítésére. egy előre.0" Style="{StaticResource PhoneTextTitle1Style}"/> </StackPanel> <Grid x:Name="ContentPanel" Grid. amikor az alkalmazásunk előtérben fut. így használhatjuk a hangerővezérlés hardveres gombjait. melyek helyben tároltak vagy akár egy távoli címen elérhetőek is lehetnek. A Mango megjelenésével nemcsak egy ilyen ágenst. hanem rögtön kettőt is kapunk. Álljon itt egy példa ennek az állománynak a szerkezetére: <ExtendedTask Name="BackgroundTask"> <BackgroundServiceAgent Specifier="ScheduledTaskAgent" Name="LocationTaskAgent" Source="LocationTaskAgent" Type="LocationTaskAgent.12.0"> 126 . A Windows Phone Mango megjelenésével szerencsére ez gyökeresen megváltozott! A multitasking bevezetésével a Microsoft létrehozta a háttérben futó folyamatokat. Az AudioPlayerAgent egy listát vár zenéinkből. és ez csak gyűjtőnév.5. és akkor is csak rövid ideig. Az ágensek létrehozása során többször találkozunk olyan esettel. de még a beépített Zune lejátszóval sem tudtuk integrálni alkalmazásainkat.dll állományban) helyezkedik el az ágens feladatát leíró kód. Az alkalmazás életciklusa A Windows Phone Mango egy energiatakarékos módját választotta a háttérműveletek kezelésének. Ezeknek a folyamatoknak a neve Background Agents.17. az adott audió bekerül a Zune Media Queue-ba. így „aktív” állapotban más módot kell találnunk az egyébként háttérben futó feladatok ellátására. amikor külön projektben (és ezért külön .és videólejátszó szoftver létezik.ScheduledAgent" /> </ExtendedTask> Zenelejátszás integrálása saját alkalmazásokba Az összes népszerű mobil operációs rendszerre számos zene. legfeljebb 10 percig futhat.-7. melyek közül kettőt rögtön érdemes megemlíteni:   PeriodicTask: periodikusan (például minden 30.

ehhez hasonló eredményt kell kapnunk.xaml. amiket szeretnénk majd lejátszani! Jelöljük ki a zenefájlokat. és ne felejtsük azt az App osztály konstruktorából meghívni! Természetesen a zeneszámokat tartalmazó fájlok listáját mindenkinek a saját fájljaira kell szabnia. hogy az AudioPlayerAgent csak Isolated Storage-ban és távoli elérési úton elhelyezett audio fájlokat tud lejátszani. Fontos megemlíteni.18.40.0" VerticalAlignment="Top"> <Button Content="prev" x:Name="prevButton" Height="140" Width="140" Click="prevButton_Click"/> <Button Content="play" x:Name="playButton" Height="140" Width="140" Click="playButton_Click"/> <Button Content="next" x:Name="nextButton" Height="140" Width="140" Click="nextButton_Click"/> </StackPanel> <TextBlock x:Name="txtCurrentTrack" Height="75" HorizontalAlignment="Left" Margin="12.0" VerticalAlignment="Top" Width="438" TextWrapping="Wrap" /> </Grid> Hozzunk létre egy új mappát és másoljuk bele az MP3 fájlokat. így Zune-on keresztül a telefonra másolt zenéket ne is próbáljuk meg elérni! Az App. ábrán látható.cs fájlban helyezzük el az alábbi metódust.0. a Zune gyűjteményünkhöz nincs hozzáférése. 127 . 5-6. jobb kattintással rajtuk a Properties parancsot választva állítsuk be a Copy To Output Directory tulajdonságot a Copy if newer opcióra! Az én projekt struktúrám az 5-6. ábra: A projekt struktúrája Következő tennivalónk a zenefájlok átmásolása az Isolated Storage-ba.193.Folyamatok a háttérben <StackPanel Orientation="Horizontal" Width="420" Margin="18.

byteCount).Windows. hogy a projekten belül található Properties mappában az ott lévő WPAppManifest. Ennek az osztálynak a műveleteit tudjuk arra felhasználni. using (IsolatedStorageFileStream file = storage. esetleg lekérdezzük a zenelejátszó státuszát. ha futtatjuk. int byteCount.Relative)). A következőkben a feladatunk az. Mivel a zene lejátszása az alkalmazásból való kilépéskor is folytatódik. akkor nem a megfelelő felület jelenik meg.mp3". private void CopyToIsolatedStorage() { using (IsolatedStorageFile storage = IsolatedStorageFile. 128 .xaml"/> Ezek után. hogy melyik lap (Page objektum) legyen az alkalmazás indításakor az alapértelmezett.Stream. hogy ezeket a műveleteket fel is használjuk.CreateFile(_fileName)) { int chunkSize = 4096.GetUserStoreForApplication()) { string[] files = new string[] { "1-01 Mr. "1-03 Dark Side. } } } } } } Van már tehát lejátszható zeneszámunk. hogy a zeneszámok között váltogassunk. Ezt úgy tudjuk megtenni. hogy az alkalmazás újbóli előtérbe kerülése esetén a gombok megfelelő állapotban jelenjenek meg a felületen. using System. Még felhasználói felület is van hozzá.Resources.Read(bytes. if (!storage. byte[] bytes = new byte[chunkSize]. Know It All.xml fájlban átírjuk a szükséges hivatkozást a következőre: <Tasks> <DefaultTask </Tasks> Name ="_default" NavigationPage="MusicPlayerPage.Write(bytes. azonban még nem működik az alkalmazásunk. chunkSize)) > 0) { file.5. foreach (var _fileName in files) { string _filePath = "Audio/" + _fileName. ha futtatjuk emulátorban a projektet.mp3" }. "1-02 What Doesn't Kill You (Stronger). 0. így vigyáznunk kell arra is.FileExists(_filePath)) { StreamResourceInfo resource = Application. Azonban még mindig nem működik! Van három gombunk. megállítsuk vagy elindítsuk az aktuális zeneszámot. akkor már a megfelelő felületet fogjuk látni.mp3".IO. így azt példányosítás nélkül a megfelelő névtér feloldása után használhatjuk is. UriKind. ennek függvényében változtatjuk a lejátszás/szüneteltetés gomb tartalmát. 0. több dolog is hiányzik ehhez! Először is.IsolatedStorage. Figyelnünk kell a zenelejátszás státuszára is. while ((byteCount = resource.GetResourceStream( new Uri(_filePath. Az alkalmazás életciklusa using System. illetve az aktuális zeneszámról megjelenített információt. az ezekhez tartozó funkcionalitást meg kell írnunk! A BackgroundAudioPlayer egy singleton osztály. Ehhez be kell állítani.

Content = "play". } // ezt a konstruktorban helyezzük el! BackgroundAudioPlayer. RoutedEventArgs e) { BackgroundAudioPlayer. case PlayState.Instance.PlayerState) { playButton. } } protected override void OnNavigatedTo(NavigationEventArgs e) { if (PlayState.Instance.Artist.Windows. } else { playButton.Content = "play".Track.Instance.Artist.PlayerState) { BackgroundAudioPlayer.Title + " by " + BackgroundAudioPlayer.Track.Instance.Text = BackgroundAudioPlayer. using Microsoft.Title + " by " + BackgroundAudioPlayer.Folyamatok a háttérben using System.Playing: playButton. } else { BackgroundAudioPlayer.Play().BackgroundAudio. break.Content = "pause".Pause(). RoutedEventArgs e) { BackgroundAudioPlayer.Playing == BackgroundAudioPlayer. RoutedEventArgs e) { if (PlayState. } } 129 .Instance.Content = "pause".Instance. void Instance_PlayStateChanged(object sender.Track. } } private void nextButton_Click(object sender.Text = BackgroundAudioPlayer.Playing == BackgroundAudioPlayer. EventArgs e) { switch (BackgroundAudioPlayer.Instance. break.PlayerState) { case PlayState.Text = "".Instance.Track) { txtCurrentTrack. txtCurrentTrack. txtCurrentTrack. } private void playButton_Click(object sender.Instance.Instance. } if (null != BackgroundAudioPlayer.SkipNext().Phone.Instance.Navigation. private void prevButton_Click(object sender.Instance.Instance.Paused: case PlayState.Track.SkipPrevious().Stopped: playButton.PlayStateChanged += new EventHandler(Instance_PlayStateChanged).

"Windows Phone Radio Podcast".com/wpradio/WPRadio_29. "Stronger". "Episode 29". "Windows Phone Radio". hogy a zenék lejátszása még mindig nem működik. és a nulladik sorszámúra kell ugranunk.mp3". akkor túl vagyunk az utolsó zeneszámon. azt tapasztaljuk. mint maga a zenét lejátszó ágens. } private void PlayPreviousTrack(BackgroundAudioPlayer player) { if (--currentTrackNumber < 0) { currentTrackNumber = _playList. new AudioTrack(new Uri("http://traffic. hiszen egy nagyon fontos komponens még hiányzik! Ez nem más. } PlayTrack(player). Mielőtt továbbhaladnánk. Az AudioTrack konstruktora egymás után a következő paramétereket fogadja: zenefájl. UriKind. 0 után a lista utolsó elemére ugrunk.1. null).Relative). amelyben dolgozni fogunk. private void PlayNextTrack(BackgroundAudioPlayer player) { if (++currentTrackNumber >= _playList.mp3". 130 .Relative). UriKind. null). Know It All".mp3". "Kelly Clarkson".5. amely a zenefájlokra hivatkozik. "Stronger". majd projekt típusaként a Windows Phone Audio Playback Agent-et válasszuk! Adjuk neki az AudioPlayer nevet! A Visual Studio létrehozza a projektet és abban egy AudioPlayer.Relative). Ezek után nincs semmi más dolgunk. ebben a listában AudioTrack típusú objektumpéldányokat sorolunk fel. null) }. "Dark Side". null). new AudioTrack(new Uri("1-03 Dark Side.Count) { currentTrackNumber = 0. Know It All. UriKind.mp3".Count . Szükségünk lesz még egy számlálóra is. "Stronger". Ez nem is csoda. és a Solution Explorerben adjuk hozzá egy új projektet jelenlegi megoldásunkhoz! Válasszuk ki a projekt gyorsmenüjéből az Add  New Project parancsot. hogy éppen melyik zeneszámot játsszuk le! Ha annak értéke egyenlő a lista méretével. lemez címe.libsyn. dal címe. "Kelly Clarkson". private static List<AudioTrack> _playList = new List<AudioTrack> { new AudioTrack(new Uri("1-01 Mr. előadó. mint a szükséges helyeken meghívni a lejátszásért felelős függvényt. UriKind. "Kelly Clarkson". akkor pedig a logikát megfordítva. adjuk hozzá az új projekt referenciáját a Windows Phone projektünkhöz! Szükségünk lesz egy listára. Pótoljuk a hiányosságot.cs fájlt. amely azt tárolja. illetve váltani listában a felhasználó igénye szerint: static int currentTrackNumber = 0. lemez képe. "Mr. Az alkalmazás életciklusa Ha fordítjuk és futtatjuk a projektet. new AudioTrack(new Uri("1-02 What Doesn't Kill You (Stronger). Ha visszafelé lépkedünk a zeneszámok között.Absolute). "Stronger".

object param) { switch (action) { case UserAction. } Teszteljük alkalmazásunkat emulátorban. } private void PlayTrack(BackgroundAudioPlayer player) { player. PlayState playState) { switch (playState) { case PlayState. vagy akár éles eszközön.TrackEnded: PlayNextTrack(player).Track = _playList[currentTrackNumber].Play: PlayTrack(player).Pause: player. hogyha rendelkezésünkre áll! Az 5-7. case UserAction. ábra az alkalmazást mutatja be futás közben. break.Pause(). case UserAction.TrackReady: player. case UserAction. UserAction action.Play(). break. AudioTrack track. break. } NotifyComplete().SkipPrevious: PlayPreviousTrack(player). AudioTrack track. } NotifyComplete(). } protected override void OnPlayStateChanged(BackgroundAudioPlayer player. break. break.SkipNext: PlayNextTrack(player). break. } protected override void OnUserAction(BackgroundAudioPlayer player. case PlayState. 131 .Folyamatok a háttérben } PlayTrack(player).

} A fenti példában látható. hogy saját riasztásokat és emlékeztetőket készítsünk. a figyelmeztetések akkor is működni fognak! Ezeket a ScheduledActionService objektum felügyeli. figyelmeztetnek bennünket.None. definiálni kell a megjelenítendő tartalmát. melyen keresztül egy új emlékeztetőt be tudunk ütemezni. hogy az adott MP3 az alkalmazás mellé legyen 132 . Az alkalmazás életciklusa 5-7.Now.Ceiling( beginTime.Ceiling(beginTime.Add( alarm ).AddMinutes(Math.Content = "Time is up!\n" + Name + " is/are done now!". és meg kell adni a riasztás időpontját.RecurrenceType = RecurrenceInterval. Három különböző időzítőt tudunk beállítani. alarm. az nyugodtan deaktivált állapotba kerülhet. alarm. Saját hangokat is rendelhetünk hozzá.AddMinutes(Math.AddSeconds( 10 ). hogy a riasztásnak egy nevet kell adnunk. UriKind.ExpirationTime = DateTime. illetve ha a felhasználó változtatást végzett a háttérben. hogy újra emlékeztessen-e. A neve Cook Timer és megtalálható a Windows Phone Marketben. azonban ekkor figyeljünk arra. alarm. amely főzés közben segít nekem.Sound = new Uri( "Sounds/House Fire Alarm. és amikor elkészült az adott étel. illetve azt. Új időzítés hozzáadásra a következő kódrészlet mutat példát: private void MakeAlarm() { alarm = new Alarm( Name ). ScheduledActionService.Relative ). Természetesen ehhez nem kell folyamatosan használnunk az alkalmazást.mp3". alarm. alarm. melyek egymástól független mérik az idő előrehaladását. akkor ki tudjuk azt keresni és törölni tudjuk a sorból.BeginTime = DateTime.Now. esetleg le szeretné állítani a riasztást.5.Value )). Példáként egy saját alkalmazásomat mutatom be.Value )) . ábra: Az Audio Player alkalmazás futás közben Figyelmeztetések és riasztások kezelése A Windows Phone Mango lehetővé teszi.

ábra az alkalmazást mutatja be működés közben. A Windows Phone Mango bevezette a Background File Transfer objektumokat. Sajnos az FTP protokoll használata jelenleg nem támogatott. mert ahhoz itt sincs hozzáférésünk! Ha időközben szeretnénk leállítani a riasztást és törölni a sorból. stb) Fájl letöltése WIFI hálózaton (akkumulátorról) Maximális méret 5 MB 20 MB 100 MB 133 . melyek HTTP és HTTPS protokollokon képesek adatokat forgalmazni. Mielőtt részletesen megnéznénk. amelyekkel számolnunk kell! Méretkorlátok: Adatforgalmazás típusa Fájl feltöltése Fájl letöltése mobil csatornán (3G. hogyan is történik letöltés. nézzük meg azokat a korlátozásokat.IsScheduled == false ) ScheduledActionService.Title ). } Az 5-8. 5-8. if ( reminder != null && reminder. akkor arra a következő kódrészlet mutat példát: void CleanupOldReminder( AlarmItem item ) { var reminder = ScheduledActionService.Find( item.Folyamatok a háttérben csomagolva.Name ). ábra: a Cook Timer alkalmazás működés közben Adatok letöltése a háttérben Elképzelhető. ne Zune média könyvtárból akarjuk elérni.Remove( reminder. HSDPA. esetleg nagyobb állományok letöltése vált szükségessé. hogy az alkalmazásunk időről időre adatokat szeretne szinkronizálni valamilyen szerver oldali komponenssel.

0 fejlesztőknek című könyv PDF változatát tölti le a háttérben: // Silverlight 4. amely leírja magát a kérést egyetlen távoli állományra mutatva.AllowCellularAndBattery. A következő kódrészlet a Silverlight 4. //megadjuk.RelativeOrAbsolute ).TransferPreferences = TransferPreferences. hanghívás megzavarhatja-e a letöltést (ha nem 3G hálózaton vagyunk. Azt is megadhatjuk. UriKind. Az alkalmazás életciklusa Egyéb korlátozások: Korlátozás típusa Az adatforgalmazó sorban lévő elemek száma Maximális érték 5 (a teljesített letöltéseket manuálisan kell törölnünk kódból) Egyidejű adatforgalmazás adott telefonról (több 2 alkalmazás által) Maximálisan beütemezhető (várakozási sorba kerülnek) HTTP fejlécek száma kérésenként HTTP fejlécek maximális mérete letöltések 500 15 16 KB külön-külön Fontos azt is tudni. így egy olyan helyi elérési útra is szükségünk lesz. amely egyesével végrehajtja az átadott letöltés-kéréseket. akkor a kivételkezelést figyelembe véve megkezdhetjük a letöltést a BackgroundTransferService objektum segítségével. Ilyen beállítás például az. A másik a BackroundTransferService. UriKind. ez egy olyan sorként képzelhető el.Add(request). hogy a letöltések szüneteltetésre kerülnek. Ha a beállításokkal végeztünk.Substring(transferFileName. Uri transferUri = new Uri( Uri.LastIndexOf( "/" ) + 1 ). A BackgroundTransferRequest objektumnak meg kell adnunk. ahova ezeket a Windows Phone bemásolhatja. Két objektumtípus segít bennünket ezeknek a feladatoknak a megvalósításában. request. hogy hova töltse le a fájlt string downloadFile = transferFileName.gl/9dkcY". } catch(Exception ex) { // ha valami probléma volt } 134 .DownloadLocation = downloadUri. Az egyik a BackgroundTransferRequest. és a HTTP protokoll melyik igéjét szeretnénk hozzá használni. BackgroundTransferRequest request = new BackgroundTransferRequest( transferUri ). akkor ez előfordulhat). esetleg Wifin keresztül kívánjuk ezt lehetővé tenni. Uri downloadUri = new Uri( "shared/transfers/" + downloadFile. hogy milyen beállítások mellett szeretnénk az adatforgalmazást engedélyezni.Method = "GET". hanem mondjuk GPRS vagy EDGE módban működünk. try { // a háttérben beütemezzük a letöltést BackgroundTransferService. ha 3G hálózat esetében 50 Kbps és WIFI esetében 100 Kbps alá csökken a hálózat áteresztő képessége. esetleg várjunk töltő csatlakoztatására. request.0 fejlesztőknek könyv pdf-ben string transferFileName = "http://goo.5.RelativeOrAbsolute ). Miután fájlrendszerbe fognak letöltődni a fájlok. request. és így tovább. hogy csak a celluláris hálózaton.EscapeUriString( transferFileName ). hogy honnan kell a letöltést végeznie.

Az új multitasking környezet számos új dolgot tesz lehetővé a fejlesztőknek. hogy az első Windows Phone 7 verzióhoz képest – amely alig egy évvel ezelőtt jelent meg – mennyit fejlődött az operációs rendszer Mango kódnevű legújabb kiadása. Láthattuk. minden feladatnak speciálisan a hozzá illeszkedő feladat kategóriába kell kerülnie. és arról gondoskodnak. amelyre eddig csak nagyon nehézkesen vagy esetleg egyáltalán nem találhattunk megoldást. hogy semmilyen esetben se veszhessenek el a felhasználó munkafolyamataihoz tartozó adatok. 135 .Összefoglalás Összefoglalás A fejezetben láthattuk. Az elméleti bevezetést követően gyakorlatban is láthattuk azokat a lépéseket. hogy nem végezhetünk akármit szabadon a háttérben. melyek az alkalmazást segítik beilleszkedni a Windows Phone életciklus modelljébe. ahol a megfelelő objektumok végrehajtják az általunk megvalósított feladatok logikáját.

.

6-1 ábra: Események és állapotváltozások taszk indításakor A taszkok két fő csoportra bonthatók: a valamilyen adatot visszatérési értékként szolgáltató Chooserekre és az egyszerű programindítást elvégző Launcherekre. e-mail vagy SMS küldése. Ennek következménye az. tehát ezt a funkciót egy Chooser valósítja meg. a futtatott feladat pedig aktívvá válik. deaktiválódik. a rendszer sebezhetetlensége volt. sőt annak létezéséről ne is tudhassanak. Ez a saját tér tartalmazza az alkalmazás izolált tárhelyét (Isolated Storage) és a program kontextusát. fényképek készítése. hogy ezekhez fejlesztőként mi is hozzáférhessünk. A taszkok a Microsoft. Egy taszk indításakor alkalmazásunk a háttérbe kerül. valamint a teljes háttértárra vonatkozó fájlrendszer fogalma sem értelmezhető az alkalmazások szemszögéből. de ennek köszönhető az is. ha nem kapnánk vissza az elkészült képet. 137 . oly módon. A taszkok a platform főbb funkcióihoz hozzáférést biztosító programok. de bármely alkalmazás által elérhetőek az SDK-n keresztül. indításuk a példányosítást és helyes paraméterezést követő Show() függvényhívással történik. hogy az összes alkalmazás úgynevezett sandbox-ban.Phone. hogy a programok nem egy felhasználó kontextusában futnak. amelyekre számos programnak szüksége lehet. az érintett állapotokat és az ezek közti eseményeket a 6-1 ábra mutatja. Ilyen feladat egy telefonhívás indítása. a CLR réteg alatt futó biztonsági mechanizmusokkal rendelkezik. vagyis a többi programtól elzárt „homokozóban” fut. Más szavakkal: kontextusváltás történik.6. Ezeket a funkciókat a platform részeként szállított alkalmazások valósítják meg. bevezették az úgynevezett taszkok (Task) rendszerét. Emiatt a platform natív. a lényeg csupán a feladat elvégzése. A folyamat lefutását. hogy ahhoz külső alkalmazások ne tudjanak hozzáférni.Tasks névtérben találhatóak. Ezzel szemben egy fénykép készítése során értelmetlen lenne. Azért. Egy telefonhívás indítása például egy Launcher. fejezet taglalja. Az alkalmazások tehát egymás elől rejtve futnak és léteznek. amelynek működését bővebben az 5. hiszen nem várunk semmi adatot. Alapvető telefonos funkciók használata A Windows Phone 7 platform megalkotása során az egyik legfontosabb szempont a biztonság. amelyek ugyan szintén sandboxban futnak. de ide tartozik a médiatár és a kapcsolattár elérése is. viszont előfordulnak olyan általános feladatok.

Amennyiben viszont nincsenek egyedi igényeink a funkcióval kapcsolatban. amely feladatát egy-egy beépített vezérlő is képes ellátni. Ez a felhasználó számára sokkal egységesebb rendszerképet és könnyebb kezelhetőséget garantál. Erre elegáns módszer a 4. amit legegyszerűbben a Windows Phone Pivot Application projektsablon kiválasztásával (6-2 ábra) helyezhetünk el alkalmazásunkban.6. akkor nemcsak egyszerűbb a taszk használata. de a platform többi részével konzisztens megoldást is biztosít. fejezetben bemutatott Pivot vezérlő. Ehhez hozzunk létre egy új projektet 06 – Integrating with the Phone névvel! Mivel a Chooserek és Launcherek két jól szeparálható részre osztják a feladatot. érdemes ezek mentén külön lapokra bontani a megjelenítési felületet is. Alapvető telefonos funkciók használata A Mango verzióban elérhető Launcherek az alábbiak: Launcher neve EmailComposeTask MediaPlayerLauncher PhoneCallTask SmsComposeTask WebBrowserTask SearchTask MarketplaceDetailTask MarketplaceHubTask MarketplaceReviewTask MarketplaceSearchTask Megvalósított funkció E-mail üzenet írása és küldése Megadott média (video / audio) lejátszása Telefonhívás indítása SMS írása Böngésző indítása Webes keresés Alkalmazás részleteinek mutatása a Marketplace kliensben Marketplace kliens indítása Vélemény írása alkalmazásunkról a Marketplace-re Keresés indítása a Marketplace kliensben A Chooserek listája: Choose neve SavePhoneNumberTask SaveContactTask SaveEmailAddressTask EmailAddressChooserTask AddressChooserTask CameraCaptureTask PhoneNumberChooserTask PhotoChooserTask SaveRingtoneTask GameInviteTask Megvalósított funkció Telefonszám mentése a kapcsolatok tárába Új partner felvétele a kapcsolatlistára E-mail cím mentése a kapcsolatok tárába E-mail cím kiválasztása kapcsolatlistánkról Cím kiválasztása kapcsolatlistánkról Kép készítése alkalmazásunk számára Telefonszám kiválasztása kapcsolatlistánkról Fénykép kiválasztása a fényképtárból Csengőhang mentése Több résztvevős játékokban a partnerek meghívását teszi lehetővé Több olyan taszk is létezik. 138 . A példaalkalmazás létrehozása A fejezet első részében a felsorolt taszkokkal fogunk részletesen megismerkedni.

1-es verziót. hogyan tudjuk az MVVM modellnek megfelelően szervezni kódunkat. hogy ezt a forrást a tervező eszközök meg is jelenítsék.A példaalkalmazás létrehozása 6-2 ábra: Windows Phone Pivot Application sablon kiválasztása a projekt létrehozásakor A következő dialógusban mindenképpen válasszuk a Windows Phone OS 7. logika. ami XAML formátumban rögzít néhány tesztbejegyzést a tervezésidejű megjelenítéshez (a Blend és a Visual Studio design felülete is ezt használja). 6-3 ábra: A sablon által generált projekt Ez a megközelítés a lehető legjobban elválasztja a különböző felelősségeket (adatszolgáltatás. megjelenítési felületek által elvárt formában tárolják az egyéb adatforrásból származó információt. Ahhoz. megjelenítés). csak az alábbi attribútumokat kell hozzáadni a PhoneApplicationPage deklarációjához (természetesen a sablon alapján ezt a VS már megtette helyettünk): 139 . mivel a taszkok egy része csupán a Mango frissítéssel vált elérhetővé! A sablonból generált projekt felépítését (6-3 ábra) érdemes tüzetesebben átvizsgálni. Ilyen adatforrás például a SampleData MainViewModelSampleData. amelyek az egyes oldalak.xaml állománya. és kihasználja a Silverlight által biztosított adatkötési mechanizmust. A ViewModels mappa fogja össze azokat az osztályokat. mivel példát mutat arra.

Phone.Controls.0.Controls névtérre. //..0" Style="{StaticResource PhoneTextSubtleStyle}"/> </StackPanel> </DataTemplate> </ListBox. public static MainViewModel ViewModel { get { // ViewModel létrehozásának elhalasztása addig.assembly=Microsoft. az oldal központi eleme ez a vezérlő.. xmlns:controls="clr-namespace:Microsoft.-12. Mivel a Pivot sablont választottuk.0" ItemsSource="{Binding Items}"> <ListBox. Alapvető telefonos funkciók használata xmlns:d="http://schemas.cs állítja elő. Használatához hivatkoznunk kell a Microsoft.0.0. A Model osztály példányát az App.0.microsoft.Controls" . és publikálja egy statikus mező formájában: private static MainViewModel viewModel = null.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" d:DataContext="{d:DesignData SampleData/MainViewModelSampleData. <Grid x:Name="LayoutRoot" Background="Transparent"> <!--Pivot Control--> <controls:Pivot Title="MY APPLICATION"> <!--Pivot item one--> <controls:PivotItem Header="first"> <!--Double line list with text wrapping--> <ListBox x:Name="FirstListBox" Margin="0.6..ItemTemplate> <DataTemplate> <StackPanel Margin="0.Phone.xaml}" Futtatáskor azonban nem ezeket az adatokat fogjuk látni. ugyanis a MainViewModel osztály rendelkezik egy LoadData metódussal.xaml és a hozzá tartozó kódfájl felelős..-12. és azokon egyegy ListBoxot helyezett el.xaml.12.-6. sőt felvett két lapot a Pivotba.17"> 140 .0. } } A megjelenítésért a MainPage.com/expression/blend/2008" xmlns:mc="http://schemas.17" Width="432" Height="78"> <TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/> <TextBlock Text="{Binding LineTwo}" TextWrapping="Wrap" Margin="12. amíg szükségünk nem lesz rá if (viewModel == null) viewModel = new MainViewModel(). ami a valós adatok előállításáért felelős. A listák adatkötés használatával tárják elénk a ViewModelekben definiált publikus tulajdonságokat.Phone.ItemTemplate> <DataTemplate> <StackPanel Margin="0.openxmlformats. de ezt a Visual Studio már megtette helyettünk.ItemTemplate> </ListBox> </controls:PivotItem> <!--Pivot item two--> <controls:PivotItem Header="second"> <!--Triple line list no text wrapping--> <ListBox x:Name="SecondListBox" Margin="0. return viewModel.0" ItemsSource="{Binding Items}"> <ListBox.0.

ItemTemplate> </ListBox> </controls:PivotItem> </controls:Pivot> </Grid> A megjelenítés és az adatok megismerése után már csak a két oldal közötti kapocs kialakítása maradt hátra. } // Adatok betöltése.0.ViewModel.Loaded += new RoutedEventHandler(MainPage_Loaded). RoutedEventArgs e) { if (!App. ezek pozicionálását pedig bízzuk egy StackPanelre! A StackPanelt viszont mindenképpen egy ScrollVieweren belül definiáljuk. hiszen ezzel biztosítható az. Alakítsuk át a projektet a taszkok teszteléséhez szükséges formába! A Pivot két lapot tartalmazzon. Az oldal kontextusát a MainPage konstruktora állítja a megfelelő ViewModelre: // Constructor public MainPage() { InitializeComponent(). egyet a launcherek és egyet a chooserek számára. viszont ha komolyan érdeklődünk a téma iránt.0. // Adatkötés DataContext = App. amennyiben a tartalom túlnyúlik a rendelkezésre álló helyen! <controls:Pivot Title="Integrating with the Phone"> <controls:PivotItem Header="launchers"> <ScrollViewer> <StackPanel> <Button Content="PhoneCallTask" Name="btnPhoneCallTask" Click="btnPhoneCallTask_Click"/> <Button Content="SmsComposeTask" Name="btnSmsComposeTask" Click="btnSmsComposeTask_Click"/> <Button Content="WebBrowserTask" Name="btnWebBrowserTask" Click="btnWebBrowserTask_Click" /> <Button Content="EmailComposeTask" Name="btnEmailLauncher" Click="btnEmailLauncher_Click" /> <Button Content="MediaPlayerLauncher" Name="btnMediaLauncher" Click="btnMediaLauncher_Click" /> <Button Content="SearchTask" Name="btnSearchTask" 141 .ViewModel. private void MainPage_Loaded(object sender. akkor a Silverlight 4: A technológia.0" Style="{StaticResource PhoneTextExtraLargeStyle}"/> <TextBlock Text="{Binding LineThree}" TextWrapping="NoWrap" Margin="12. Minden taszk indítására vegyünk fel külön gombot.0. fejezete tökéletes kiindulópontot jelent a tanuláshoz.A példaalkalmazás létrehozása <TextBlock Text="{Binding LineOne}" TextWrapping="NoWrap" Margin="12. és ami mögötte van című könyv 10.IsDataLoaded) { App. amint elkészült az oldal. hogy a panel görgethetővé válik.ViewModel.LoadData().-6. this.0" Style="{StaticResource PhoneTextSubtleStyle}"/> </StackPanel> </DataTemplate> </ListBox. } } A generált projekt megvizsgálásával egy kis betekintést nyerhettünk az MVVM architekturális minta használatába.

majd a hívást összegző üzenetet láthatjuk (6-4 ábra). a kihangosítási.6. de vizuális elemeket ez sajnos nem tartalmazhat. ami először lehetőséget ad a felhasználónak a hívás elindítására vagy elutasítására.DisplayName = "WP7 support". 142 . hiszen működésük teljesen azonos. fejezet részletesen taglalja. // a tagolás nem kötelező. Emellett egy nevet is megjeleníthetünk. mivel ezeket a 12. phoneCallTask. csupán az érintett tulajdonság különbözik. Launcherek PhoneCallTask Telefonhívás indításakor kötelező megadni a hívandó telefonszámot. RoutedEventArgs e) { PhoneCallTask phoneCallTask = new PhoneCallTask().PhoneNumber = "00361/123-4567". } A Show() metódus elindítja a taszkot. némítási lehetőségekkel. de ennek hiánya sem okoz problémát: private void btnPhoneCallTask_Click(object sender. A chooserek lapja tartalmazzon egy Image vezérlőt is. hiszen a visszatérési értékek tartalmazhatnak szöveget és képet is! A szöveges válaszok megjelenítésére tökéletes egy felugró ablak (MessageBox). A hívás lebonyolítása a megszokott felületen történik. // ezt nem kötelező megadni phoneCallTask. de így is megadhatjuk a számot phoneCallTask.Show(). Ezenfelül fölösleges különbséget tenni a telefonszámot vagy e-mail címet szolgáltató és módosító feladatok között. Alapvető telefonos funkciók használata Click="btnSearchTask_Click"/> </StackPanel> </ScrollViewer> </controls:PivotItem> <controls:PivotItem Header="choosers"> <ScrollViewer> <StackPanel> <Button Content="SavePhoneNumberTask" Name="btnSavePhone" Click="btnSavePhone_Click" /> <Button Content="PhoneNumberChooserTask" Name="btnPhoneNumberChooserTask" Click="btnPhoneNumberChooserTask_Click" /> <Button Content="CameraCaptureTask" Name="btnCameraCaptureTask" Click="btnCameraCaptureTask_Click" /> <Button Content="PhotoChooserTask" Name="btnPhotoChooserTask" Click="btnPhotoChooserTask_Click" /> <Image Name="imgResult" Width="400" Height="400" /> </StackPanel> </ScrollViewer> </controls:PivotItem> </controls:Pivot> A launcherek és chooserek listájáról hiányoznak a Marketplace-szel kapcsolatos taszkok.

Az ApplicationBaron található gombokkal médiaelem csatolására és üzenet diktálására is lehetőségünk van. amit az üzenetváltásban jelez számunkra a rendszer(6-5 ábra).Body = "szöveg".Show(). Természetesen a küldés az emulátoron meg fog hiúsulni. smsComposeTask. de mindkét érték elhagyható: private void btnSmsComposeTask_Click(object sender.Launcherek 6-4 ábra: Telefonhívás lebonyolítása alkalmazásunkból SmsComposeTask Sms küldésekor lehetőségünk van megadni a címzettek listáját és az üzenet szövegét is. 987-6543". smsComposeTask. RoutedEventArgs e) { SmsComposeTask smsComposeTask = new SmsComposeTask(). 6-5 ábra: Sms küldése SmsComposeTask használatával 143 . ahogyan az üzenet szövegét is átírhatjuk. A címzetteket a + gombra kattintva kiegészíthetjük.To = "123-4567. } A feladat indításakor a megadott értékek megjelennek az sms-ek küldését végző alkalmazásban. smsComposeTask.

// másolat küldése emailTask. } Az üzenet minden adata a kódból is beállítható. // több címzett megadása emailTask. Alapvető telefonos funkciók használata EmailComposeTask Levelek küldéséhez szükségünk van egy levelező szerverre is. hogy ezek nélkül. Két megoldás létezik arra.To ="alpha@test. hogy melyik fiókot szeretné használni a feladathoz. mint például saját elemek felvétele az ApplicationBarba.6. A levelek küldése előtt a taszk megkérdezi a felhasználót. a levélküldés sajnos nem lesz tesztelhető. WebBrowserTask Gyakori igény alkalmazásokban teljes weboldalak megjelenítése.Subject = "tárgy". Erre tökéletes megoldás a WebBrowser vezérlő.Body = "üzenet szövege". az alsó URL sávot. viszont ez önmagában csak egy megjelenítő és értelmező felület. ami alkalmas ennek a szolgáltatásnak a kipróbálására. emailTask. hogy létezik más megoldás is. hogy telefonkészülékre telepítjük az alkalmazásunkat. hogy keresünk egy a Microsoft által nem támogatott emulátort. akkor érdemes lehet a böngésző programot elindító WebBrowserTaskot használnunk: private void btnWebBrowserTask_Click(object sender.URL = "xy. hogy ilyen fiókokat állítsunk be. már ne használjuk! //webBrowserTask.com".Cc = "charlie@test.com". hiszen a telefon konfigurálása során valószínűleg minden felhasználó beállít egy felhasználói fiókot.com. hogy ezt a funkciót kipróbáljuk. Az egyik az. // rejtett másolat emailTask.Bcc = "delta@test. RoutedEventArgs e) { EmailComposeTask emailTask = new EmailComposeTask(). ugyanis az a megbízhatóbb. (Ezeket az emulátorokat többnyire ingyenesen tölthetjük le. bravo@test. // task indítása emailTask. // elavult.Show().com". RoutedEventArgs e) { WebBrowserTask webBrowserTask = new WebBrowserTask(). a kedvencek és előzmények rendszerezését és még számos funkciót elveszítünk a használatával. de lehetőség van arra is.) 6-6 ábra: A levélküldés sajnos nem elérhető az emulátorról private void btnEmailLauncher_Click(object sender. a másik pedig az. ezt követően jelenik csak meg a szerkesztő felület. csak készülékre telepítve (6-6 ábra).com". 144 . pusztán a Show() függvényhívással egy üres e-mail alkalmazást nyissunk. a beépített Internet Explorer 9 előnyeit. emailTask. amelyet a szolgáltatások igénybevétele során használ. Mi a készüléken való kipróbálást ajánljuk. de bizonyos esetekben jó tudni arról. Ha nincsenek olyan egyedi igényeink. Mivel az emulátoron jelenleg nincs mód arra. Szerencsére ez nem jelent külön feladatot.

A taszk használatakor a példányosítást követően meg kell adnunk a lejátszandó video vagy audio elem címét.Show(). private void btnMediaLauncher_Click(object sender. ami lehet lokális vagy távoli. } 145 .Controls = MediaPlaybackControls. ezt pedig a MediaPlayerLauncher Location tulajdonságán keresztül tehetjük meg.hu/wp7". akkor meg kell adnunk. ami teljes testreszabhatóságot biztosít számunkra. így a generált oldal teljesen megegyezik a számítógépeken megszokottal. Ennek megfelelően ki kell választanunk.hu/wp7 oldal.Show().Location = MediaLocationType.devportal. Választásunkat követően az oldal betöltődik az Internet Explorer 9 mobilos változatába. ami a 6-7 ábrán látható.All. mpl.wmv". A példában egy internetes videót választottam. mpl. //mpl. így most abszolút címzést alkalmazunk.net/o9/mix/09/wmv/key01.Absolute). hogy az alkalmazással telepített vagy az Isolated Storage-be mentett médiát címzünk meg.hu/wp7 oldal egy WebBrowserTaskban megjelenítve MediaPlayerLauncher A platform két rendkívül egyszerűen használható lehetőséget biztosít médiaelemek lejátszására. mpl. 6-7 ábra: A https://devportal. UriKind. A böngésző a Mango frissítésnek hála teljes HTML 5 támogatással rendelkezik.msecnd.Media = new Uri(@"http://mschannel9. } A böngésző első indításakor engedélyt kér a böngészés adatainak felhasználására a Bing kereső továbbfejlesztésének érdekében. UriKind. Ha a telefonon található tartalmat szeretnénk lejátszani.Launcherek webBrowserTask. internetről származó is. hogy relatív vagy abszolút címzésről van szó.Data. webBrowserTask.vo. Jó példa erre az Orchard keretrendszerben elkészített HTML 5-öt használó https://devportal. RoutedEventArgs e) { MediaPlayerLauncher mpl = new MediaPlayerLauncher(). Az egyik a Toolboxban megtalálható MediaElement vezérlő.Uri = new Uri("http://www. a másik pedig a pár kódsorral paraméterezhető MediaPlayerLauncher taszk (6-8 ábra).Absolute).

akár képek között. aminek lapjait a 6-9 ábra mutatja. A 6-8 ábrán az összes elem együttes használata látható. 6-8 ábra: MediaPlayerLauncher taszk egy videó lejátszása közben. searchTask. de ha engedélyeztük a Location Servicest. None. A találatok egy Pivot vezérlőn jelennek meg. A Mango újdonsága az ún. Skip. RoutedEventArgs e) { SearchTask searchTask = new SearchTask().Show(). és a többi találat előtt ajánlja az illeszkedő alkalmazásokat. Stop) egy értékét veheti fel. private void btnSearchTask_Click(object sender. Segítségével a megadott kulcsszó alapján kereshetünk a weben. aminek hála a keresés a Marketplace alkalmazásait is megvizsgálja. searchTask. a beviteli mező jobb szélén található mikrofon gombra kattintva akár diktálva is.SearchQuery = "pizza". A keresőszót a taszkon belül módosíthatjuk. Ez a mező a MediaPlaybackControl enumeráció (All. Rewind. } 6-9 ábra: A SearchTask találatainak listája 146 . FastForward.6. hogy milyen előre definiált vezérlők jelenjenek meg a médialejátszóban. Alapvető telefonos funkciók használata A Controls tulajdonságon keresztül kiválaszthatjuk. App Connect. Pause. akkor a pozíciónk körüli kiemelt helyek között is. minden beépített vezérlővel SearchTask Kereső funkciót megvalósító taszk.

rövid kódról van szó. SavePhoneNumberTask Az első megvizsgált chooser esetében nem valamilyen szolgáltatott adatra. amit nekünk kell a felhasználó felé továbbítanunk egy üzenetdoboz megjelenítésével: private void btnSavePhone_Click(object sender. hogy amíg nem zártuk be a MessageBoxot az OK gombbal. break.Cancel: MessageBox. a képeket pedig a gombok alatt található Image vezérlőben. addig a rendszer úgy érzékeli. akkor a rendszer – az alkalmazás eseményeinek 10 másodperces időkorlátja miatt – leállítja programunk futását. hibája pedig adatvesztéshez vezethet. spn.Show("Mentés megszakítva!"). case TaskResult. esetleges meghiúsulásukról kell értesítenünk a felhasználót. így a kommunikáció egy eseménykezelő (Completed) implementálásával történik. hanem a művelet eredményességére vagyunk kíváncsiak. amit egészen biztos. amelyekkel a műveletek kimenetéről. hogy nem fogunk máshol használni. fejezet foglalkozik részletesen. amely akkor fut le. break. mivel egy fellépő hibáról azonnal értesül a felhasználó.Show("A telefonszám mentése nem sikerült!"). hogy ha túl sokáig hagyjuk fent a párbeszédablakot. result) => { switch (result.Completed += (s. Egy valós alkalmazás során ez a megközelítés nem lenne működőképes.PhoneNumber = "0000/1234567". hogy az állapotváltás eseménykezelője fut. amikor a taszk futása már befejeződött. RoutedEventArgs e) { SavePhoneNumberTask spn = new SavePhoneNumberTask(). Emiatt az ilyen taszkok visszatérési értékkel rendelkeznek.None: MessageBox. Ennek megfelelően a taszk felparaméterezése után definiálnunk kell egy eseménykezelő függvényt. ami tartalmazhat egy kivételt (Exception). valamint azok is. meghiúsult). Ez azt jelenti. és újra a mi alkalmazásunk kerül előtérbe. A példa során ebben a metódusban egy párbeszédablakban fogjuk megjeleníteni a szöveges visszatérési értékeket. érdemes lambda kifejezéssel megadott anonim metódust alkalmazni. mégis képes „megfogni” programunk aktiválódását. mivel a MessageBox megjelenítése. } A Completed eseménykezelőjét megadhatjuk külön eljárásként is. Egy telefonhívás indítása launcher. amelyek adatot szolgáltatnak alkalmazásunk számára.Chooserek Chooserek A chooserek közé tartoznak azok a taszkok. A SavePhoneNumberTask a Contacts alkalmazást indítja el. spn. azaz a Completed eseménykezelő közvetlenül az Application_Activated után fut le. illetve a futás kimenetelét (sikeres.Show(). amelyben lehetőséget biztosít arra. } }. A taszkok természetesen külön szálon futnak. 147 . break. de mivel egyszerű. A visszatérési érték TaskResult mezője a TaskResult felsorolás egyik lehetséges értékével jelzi a futás kimenetelét. képet).TaskResult) { case TaskResult. hogy valamely ismerősünk adatait egy új telefonszámmal egészítsük ki. valamint bármilyen a taszk jellegéből adódó adatot (pl. de egy telefonszám mentését indítványozó SavePhoneNumberTask kimenete közvetlenül nem érzékelhető. Az állapotátmenetek működésével az 5. spn.OK: MessageBox. Ennek az a következménye. case TaskResult.Show("Telefonszám elmentve!").

Show(string. } }. phoneNumberChooser.Format("Név: {0}\nTelefonszám:{1}". 6-10 ábra: Egy telefonszám mentésének lépései és a visszatérési érték megjelenítése PhoneNumberChooserTask A PhoneNumberChooserTask szintén a Contacts alkalmazást nyitja meg. number)).6. ami megvizsgálja és az általunk definiált eljárás alapján jelzi a visszatérési értéket. A folyamat a 6-10 ábrán tekinthető meg. amelyek a tesztelések megkönnyítésére kerültek be az emulátorba. A módosítások mentése után a kapcsolat adatait részletező oldalra kerülünk. Ekkor fut le az általunk definiált eseménykezelő. A Completed eseménykezelő második paramétere egy PhoneNumberResult példány. result) => { if (result.OK) { string name = result. viszont ez a taszk már adatot is szolgáltat a hívó alkalmazás számára.Completed += (s. akkor a telefonszám mentésére lehetőséget biztosító oldal következik.Show(). MessageBox.DisplayName. phoneNumberChooser. string number = result.PhoneNumber. Ha itt kiválasztunk egy partnert. RoutedEventArgs e) { PhoneNumberChooserTask phoneNumberChooser = new PhoneNumberChooserTask(). name. amin keresztül elérhetjük a kiválasztott partner nevét és telefonszámát (611 ábra): private void btnPhoneNumberChooserTask_Click(object sender. Alapvető telefonos funkciók használata A Contacts alkalmazás indulásakor néhány előre definiált partner közül választhatunk.TaskResult == TaskResult. ahonnan a Back gomb megnyomásával térhetünk vissza a taszkot indító alkalmazásba. } 6-11 ábra: A kiválasztott partner neve és telefonszáma 148 .Error == null && result.

amit ha engedélyezünk.Chooserek CameraCaptureTask A kamera használatának legegyszerűbb módja egy CameraCaptureTask indítása. } }. A feladat egy Streammel tér vissza. ha a dimenziók rögzítése mellett döntünk.Show(). private void btnCameraCaptureTask_Click(object sender.Media. Meghatározhatjuk az általunk elvárt kép dimenzióit is a PixelHeight és PixelWitdh tulajdonságok értékének beállításával. } Az emulátor szerencsére egy kamera működését is szimulálni tudja.BitmapImage BitmapImage bmp = new BitmapImage(). A Mango frissítéssel megjelent a PhotoCamera osztály is az eszközkészletben. így a kapott képet meg tudjuk jeleníteni (6-12 ábra). erről a fejezet következő részében lesz szó.Imaging. cameraTask.ChosenPhoto). amit nem lehet közvetlenül képforrásként használni. Ha ezeket üresen hagyjuk. akkor a teljes kiválasztott képet visszakapjuk. Az osztály rendelkezik egy ShowCamera tulajdonsággal. bmp. imgResult.TaskResult == TaskResult. ezért be kell vezetnünk egy BitmapImage változót is. Ez a SetSource metódusával már fel tudja dolgozni a streamet. 6-12 ábra: Kép készítése CameraCaptureTask használatával PhotoChooserTask A PhotoChooserTask egy kép kiválasztását teszi lehetővé a telefon médiatárából. 149 .SetSource(result. akkor lehetőségünk lesz a képen kijelölni a kívánt területet. ha nem is naplementés tájképekkel. RoutedEventArgs e) { CameraCaptureTask cameraTask = new CameraCaptureTask(). cameraTask.Windows.Source = bmp.Completed += (s. akkor kikerül a különböző képtárak listája alá egy CameraCaptureTaskot indító gomb is.OK) { // System. abban az esetben viszont. result) => { if (result. de a célra tökéletesen megfelelő mozgó fekete kockával szembesülhetünk a taszk indításakor.

photoChooserTask.TaskResult == TaskResult. Alapvető telefonos funkciók használata private void btnPhotoChooserTask_Click(object sender.Source = bmp. photoChooserTask.PixelHeight = 50. Ezek bemutatására vegyünk fel egy új lapot a korábban használt pivotra datasharing névvel! Az új lapon definiáljunk egy-egy gombot. 6-13 ábra: Meghatározott méretű kép kiválasztása és megjelenítése Adatok megosztása alkalmazások között A taszkok rendszere mellett a Mango frissítéssel bekerült egy új lehetőség az alkalmazások közti adatmegosztásra.Show(result. result) => { if (result. Az új fejlesztői készletben megjelent ugyanis a PhoneDataSharingContext osztály. ami egy kijelölt tárterületen képes lekérdezéseket futtatni. imgResult. photoChooserTask. BitmapImage bmp = new BitmapImage(). } }.6. a Contacts és az Appointments osztály érhető el.ChosenPhoto). és csupán az ezen belül található képrészt adja majd vissza alkalmazásunk számára (6-13 ábra).PixelWidth = 200. bmp. RoutedEventArgs e) { PhotoChooserTask photoChooserTask = new PhotoChooserTask().Completed += (s. valamint egy új képet a két feladathoz: <controls:PivotItem Header="datasharing"> <ScrollViewer> <StackPanel> <Button Content="Contacts" Name="btnContacts" Click="btnContacts_Click" /> <Button Content="Appointments" Name="btnAppointments" Click="btnAppointments_Click" /> <Image Name="imgDataSharing" Width="400" Height="400" /> 150 .OriginalFileName). } A példakódban egy 50 pixel magas és 200 pixel széles képet szeretnénk beolvasni. // lehetőséget adhatunk a kamera taszk indítására is egy gomb engedélyezésével photoChooserTask. a találatokat pedig generikus listán szolgáltatja a hívó alkalmazásnak.Show().ShowCamera = true. // dimenziók beállítása photoChooserTask.OriginalFileName != null) { MessageBox.SetSource(result. így a taszk lehetőséget kínál egy ekkora terület kijelölésére. Jelenleg két implementációja.OK && result.

A partnerlista egyik nagyszerű tulajdonsága az. e-mail címet. MiddleName. Megjelenített név E-mail címek listája Boolean érték. amíg a Back gombbal vissza nem navigálunk az alkalmazásunkba. A partnerhez rögzített jegyzeteink listája A partner telefonszámai. hogy aki a SIM kártyánkra mentett ismerősünk. Tehát annak ellenére. de szerepel például a facebookos vagy hotmailes ismerőseink listáján is. céges. hogy több információforrásunk is van. facebook. A Contacts nem túl meglepő módon a Contact osztály példányainak listáját szolgáltatja. de akár olyan ellentmondásos helyzetek is kialakulhatnak. Itt válasszunk egy profilképet. stb. FirstName. Live. telefonszám vagy minden mező alapján kereshetünk. Birthday. annak összes adatát egyetlen helyről. hogy a felhasználó képének lekérésére is van lehetőségünk. hogy a különböző helyekről származó adatokat összefésüli. Az emulátoron szereplő kapcsolatlista jó kiindulási alap a teszteléshez. mobil. e-mail cím. a találatoknak pedig minden információjához hozzáférhetünk. hanem metódus. hogy kitűztük-e a felhasználó hivatkozását a kezdőlapra. amiket le szeretnénk kérdezni! A módosításokhoz használhatjuk akár a SavePhoneNumberTaskot is. és egy közös tárban teszi hozzáférhetővé. hiszen a név nem egyedi azonosító egy személy esetében). transzparens módon érhetjük el. amelyeken partnerünk a felhasználó (pl. Ez azt jelenti. párkapcsolattal (ennek megítélése nyilván felhasználófüggő) rendelkezik. LastName). Segítségével név.) A partner párkapcsolatai Weblapok listája Ugyan nem tulajdonság. Típusosan elérhető a név összes része (Nickname. Ennek természetes velejárója az. mivel a telefonszám módosítását követően a Contacts alkalmazásban maradunk addig. megmutatja. ezek uniójaként egy felhasználót látunk a partnerlistánkon (némely esetben a felhasználók összekapcsolását nekünk kell elvégeznünk. Tartalmazzák a számot és a telefonszám típusát is (otthoni. stb. hogy egy felhasználó tartalmazhat több telefonszámot. Az ezen keresztül elérhető tulajdonságok az alábbi táblázatban találhatók: Tulajdonság Accounts Addresses Birthdays Children Companies CompleteName DisplayName EmailAddresses IsPinnedToStart Notes PhoneNumbers SignificantOthers Websites GetPicture() Leírás Azon források listája. és töltsük ki a JobTitle. de fontos megjegyezni. amikor egy partnerünk több szülinappal. de a biztonság kedvéért egészítsük ki például Chris Sells adatait azokkal az információkkal. SignificantOther és OfficeLocation tulajdonságokat! 151 .) Címek listája Partnerünk összes szülinapjának listája Ismerős gyermekei Munkahelyek listája A partner teljes neve.Adatok megosztása alkalmazások között </StackPanel> </ScrollViewer> </controls:PivotItem> Contacts A Contacts osztály a telefonon tárolt összes kapcsolatunkhoz hozzáférést biztosít alkalmazásunk számára.

Companies.First(). contacts. sajnos az emulátoron mindig egy üres listát fogunk visszakapni. imgDataSharing.First().JobTitle.FirstName.Format(formatStr. string company = contact. MessageBox.First(). string note = contact. stb. bmp.Source = bmp. title. result) => { var contact = result.SearchCompleted += (s.CompleteName. null).First(). name. de természetesen a keresés ettől függetlenül felhasználók listáját adja vissza.Companies.First(). RoutedEventArgs e) { Contacts contacts = new Contacts(). // megjelenítés string formatStr = "Name: {0}\nCompany: {1}\nTitle: {2}\n" + "Birthday: {3}\nSignificantOther: {4}\nNote: {5}". Facebook.SetSource(contact. ahol a tulajdonságok többsége szintén egy IEnumerable példány. viszont mivel ezek az adatok mindenképpen felhasználói fiókhoz kötődnek (Live. string title = contact. FilterKind. // felhasználó képének lekérése BitmapImage bmp = new BitmapImage(). }.Results.First(). A bejegyzést megtestesítő Appointment osztály főbb tulajdonságai a következő táblázatban láthatók: 152 .CompanyName.ToShortDateString(). note)). company.SearchAsync("c". Alapvető telefonos funkciók használata A módosításokat követően írjuk meg a Contacts gomb klikk eseménykezelőjét! private void btnContacts_Click(object sender. } A fenti kódban minden listának csak az első elemét kérdeztük le. // csak a nevek között keresünk contacts. A függvény futásának eredménye a 6-14 ábrán látható. significantOther.SignificantOthers. string birthday = contact.Show(string.GetPicture()). // egyéb adatok string name = contact.Notes.). Hotmail.6. string significantOther = contact.DisplayName. birthday.Birthdays. 6-14 ábra: Partner adatainak lekérdezése PhoneDataSharingContext használatával Appointments A naptárbejegyzések lekérdezése a kapcsolatok kezeléséhez hasonlít.

Kamera használata taszk nélkül

Tulajdonság
Account Attendees Details StartTime EndTime IsAllDayEvent IsPrivate Location Organizer Status Subject

Leírás A naptárbejegyzést tároló felhasználói fiók Résztvevő felhasználók (Attendee lista) A bejegyzés szöveges leírása Kezdés ideje Befejezés ideje Boolean, egész napos eseményről van-e szó? Mindenki által látható vagy privát esemény? A találkozó helye (szövegként) A szervező személy (Attendee példány) Részvételi állapotunk A bejegyzés tárgya röviden

Alkalmazása tehát nagyon hasonlít a partneradatok lekérdezéséhez. A SearchAsync() hívása új szálon elindítja a keresést, a visszatérési értéket pedig a SearchCompleted eseménykezelőben használhatjuk fel:
private void btnAppointments_Click(object sender, RoutedEventArgs e) { Appointments apps = new Appointments(); apps.SearchCompleted += (s, result) => { var events = result.Results; if (events != null && events.Count() > 0) { var myEvent = events.OrderBy(c => c.StartTime).First(); string formatStr = @"A következő esemény {0} napon kezdődik, tárgya: {1}, résztvevői pedig:\n{2}"; StringBuilder builder = new StringBuilder(); foreach (var item in myEvent.Attendees) { builder.AppendFormat("{0}\n", item.DisplayName); } MessageBox.Show(string.Format(formatStr, myEvent.StartTime.ToShortDateString(), myEvent.Subject, builder.ToString())); } }; apps.SearchAsync(DateTime.Now, DateTime.Now.AddMonths(6), null); }

Kamera használata taszk nélkül
A CameraCaptureTask használatán túl lehetőségünk van közvetlenebb módon is kommunikálnunk a készülék kameráival. Az operációs rendszer Mango verziója ugyanis elérhetővé teszi számunkra a fényképek készítését lehetővé tevő PhotoCamera és a videorögzítést megkönnyítő VideoCaptureDevice osztályokat. Ezek működése nagyrészt hasonlít egymáshoz, a különbség főként az adatok tárolásakor mutatkozik meg. Mindkét esetben az Isolated Storage-be vagy a Media Library-ba menthetünk, de videó rögzítésekor a folyamatos adatfolyam miatt a FileSink segédosztályt is használnunk kell. A következő példa során valós idejű képet fogunk mutatni a kamera képéről, és lehetőséget adunk fénykép készítésére akár a fő, hátlapon lévő kamerát, akár az előlapon lévőt használva.

153

6. Alapvető telefonos funkciók használata Mindenekelőtt a WMAppManifest.xml állományban jelezzük, hogy alkalmazásunk fogja használni a készülék kameráit. Ehhez egészítsük ki a Capabilities szekciót a két kamera azonosítójával (a hátlapon lévő kamera bejegyzése valószínűleg már a generált állományban is megtalálható):
<Capabilities> <Capability Name="ID_HW_FRONTCAMERA"/> <Capability Name="ID_CAP_ISV_CAMERA"/> ... </Capabilities>

Vegyünk fel egy Windows Phone Landscape Page -et projektünkbe Camera névvel (6-15 ábra)! Ez a sablon egy olyan oldalt generál, amely csak Landscape módban jelenik meg, de természetesen ez két tulajdonság módosításával felüldefiniálható.

6-15 ábra: Windows Phone Landscape Page sablon Mivel az oldalt a továbbiakban fektetett módban fogjuk használni, érdemes az emulátort is ehhez igazítani. Ehhez az emulátor jobb oldali menüjében találjuk a jobbra és balra forgató gombokat (6-16 ábra).

6-16 ábra: Emulátor forgatása Adjunk hozzá egy gombot az eddig szerkesztett MainPage oldalhoz, ami az új Camera.xaml oldalunkra fog navigálni!
<Button Content="Camera" Name="btnCamera" Click="btnCamera_Click" /> // kódfájl: private void btnCamera_Click(object sender, RoutedEventArgs e) { NavigationService.Navigate(new Uri("/Camera.xaml", UriKind.Relative)); }

Mielőtt nekiállnánk a kódfájlban létrehozni minden objektumot és a funkcionalitást implementálni, gondoljuk végig, hogy mire lesz szükségünk! Mivel két kamera képét egyszerre nem tudjuk kezelni, lehetővé kell tennünk a felhasználó számára, hogy váltani tudjon azok között. Erre tökéletesen megfelel egy Slider, ami két értéket vehet fel. Azért is szerencsés ez a választás, mert az operációs rendszer legtöbb beállításánál is így vannak megvalósítva a kapcsolók, és az sohasem baj, ha a platformmal konzisztensek maradunk. A kapcsoló állásától függ a kirajzolt kép és az adatmentés forrása. Egy gombbal pedig

154

Kamera használata taszk nélkül lehetőséget kell adnunk a fénykép készítésére is, viszont a feldolgozás idejére ezt inaktívvá is kell tennünk. Látszik, hogy itt az előző taszkindításoknál bonyolultabb dolgunk lesz, például adatkötéseket is meg kell valósítanunk. Ennek érdekében a feladatot a fejezet elején leírt modell szerint egészítsük ki, azaz hozzunk létre egy ViewModelt az oldal számára! A ViewModels mappához adjunk hozzá egy új osztályt CameraViewModel névvel, ez pedig valósítsa meg az INotifyPropertyChanged interfészt:
public class CameraViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (null != handler) { handler(this, new PropertyChangedEventArgs(propertyName)); } } }

Ez az osztály tároljon minden tulajdonságot és logikát, amit a Camera.xaml-nek a megjelenítés során alkalmaznia kell! Vegyük is fel ezeket az alábbiak szerint:
public PhotoCamera Camera { get; set; } private VideoBrush cameraBrush; /// <summary> /// Az élő képet megjelenítő VideoBrush /// </summary> public VideoBrush CameraBrush { get { return cameraBrush; } set { cameraBrush = value; NotifyPropertyChanged("CameraBrush"); } } private bool isCameraChooserEnabled; /// <summary> /// True, ha mindkét kamera elérhető, azaz a választó /// slide-nak aktívnak kell lennie /// </summary> public bool IsCameraChooserEnabled { get { return isCameraChooserEnabled; } set { isCameraChooserEnabled = value; Deployment.Current.Dispatcher.BeginInvoke(() => { NotifyPropertyChanged("IsCameraChooserEnabled"); }); } } private bool isFrontCamera; /// <summary> /// True, ha az előlapi kamera aktív, egyébként false /// </summary> public bool IsFrontCamera {

155

6. Alapvető telefonos funkciók használata

get { return isFrontCamera; } set { isCameraChooserEnabled = value; Deployment.Current.Dispatcher.BeginInvoke(() => { NotifyPropertyChanged("IsFrontCamera"); }); } } private bool isPhotoEnabled; /// <summary> /// True, ha készen állunk fénykép készítésére, /// azaz a fotó gomb aktív /// </summary> public bool IsPhotoEnabled { get { return isPhotoEnabled; } set { isPhotoEnabled = value; Deployment.Current.Dispatcher.BeginInvoke(() => { NotifyPropertyChanged("IsPhotoEnabled"); }); } } /// <summary> /// Fénykép készítése /// </summary> public void TakePhoto() { // nem készíthetünk új képet, amíg ezt nem dolgoztuk fel IsPhotoEnabled = false; Camera.CaptureImage(); }

A kódban kiemelem azokat a tulajdonságokat, amelyeket kötnünk kell egy vezérlőhöz a megjelenítő oldalon. Ezeknél a set metódust úgy kell módosítani, hogy az értékadást követően egy NotifyPropertyChanged hívással jelezzék a mögöttes érték változását. Emiatt nem lehet a rövidített public string PropertyName { get; set; } formátumot használni, a teljes kifejtésre van szükség. Szerencsére ez a „prop” + TAB + TAB beírásával legenerálható, és így a gépelés nagy részét megúszhatjuk. Mivel a kamerával kapcsolatos feladatok nem az UI szálon futnak, szükségünk lesz a Dispatcher használatára, hogy a változásokat a felhasználói felületen is megjeleníthessük. Kezdjük el leprogramozni a vezérlő logikáját! A két kamerát egyszerre nem tudjuk kezelni, így valahol meg kell oldanunk a kiválasztott eszköz eseményeinek figyelését, míg a másik kamerát ki kell kapcsolnunk. Magától értetődő választás erre az IsFrontCamera tulajdonság set metódusa, mivel a kamera kiválasztásakor közvetlenül ez az eljárás fog futni. Itt szabaduljunk meg egy Dispose hívással a korábbi kamerától, majd példányosítsunk egy megfelelő típusú PhotoCamera-t (Primary, FrontFacing)! Definiáljuk az új objektum CaptureImageAvailable eseménykezelőjét, ami a kép elkészültekor fog lefutni. Emellett gondoskodjunk az IsCameraChooserEnabled tulajdonság kezeléséről is, mivel az objektum inicializálása viszonylag sok időt vesz igénybe, és ha még eközben kamerát váltunk, akkor a Dispose() hívás a félkész objektumon hibát fog eredményezni.
public bool IsFrontCamera { get { return isFrontCamera; } set

156

Kamera használata taszk nélkül

{ isFrontCamera = value; // előzőleg beállított kamera törlése, ha volt if (Camera != null) { Camera.Dispose(); } if (isFrontCamera) {// előlapi kamera Camera = new PhotoCamera(CameraType.FrontFacing); } else {// hátlapi kamera Camera = new PhotoCamera(CameraType.Primary); } // Init lezárása előtt ne lehessen kamerát váltani (Dispose) IsCameraChooserEnabled = false; Camera.Initialized += (s, e) => { if (PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing) && PhotoCamera.IsCameraTypeSupported(CameraType.Primary)) { // kameraváltás újbóli engedélyezése IsCameraChooserEnabled = true; } }; Camera.CaptureImageAvailable += (s, e) => { string name = DateTime.Now.ToShortTimeString() + ".jpg"; // TODO: mentés megírása // újra fotózhatunk IsPhotoEnabled = true; Deployment.Current.Dispatcher.BeginInvoke(() => { // visszajelzés küldése (UI szál) MessageBox.Show(name + " mentve!"); }); }; NotifyPropertyChanged("IsFrontCamera"); } }

A kép már elkészül, azt viszont még csak a telefon pozíciójából tudjuk kikövetkeztetni, hogy mit fotóztunk. Ennek kiküszöbölésére csak annyi a teendőnk, hogy a korábban deklarált ecsetet összekötjük a kamerával, még ugyanebben a set metódusban, például a NotifyPropertyChanged("IsFrontCamera"); hívása előtt:
// ... // VideoBrush beállítása a kiválasztott kamerára cameraBrush.SetSource(Camera); NotifyPropertyChanged("IsFrontCamera"); }

A tulajdonságok halmaza és a logika már kész, már csak inicializálni kell az értékeket. Vegyünk fel erre egy új függvényt, LoadData névvel:

157

6. Alapvető telefonos funkciók használata

public void LoadData() { CameraBrush = new VideoBrush(); IsPhotoEnabled = true; if (PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing) && PhotoCamera.IsCameraTypeSupported(CameraType.Primary)) { // mindkét kamera elérhető --> választhassunk IsCameraChooserEnabled = true; IsFrontCamera = true; } else { // csak az egyik kamera érhető el (vagy egyik sem) IsCameraChooserEnabled = false; if (PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing)) { IsFrontCamera = true; } else if (PhotoCamera.IsCameraTypeSupported(CameraType.Primary)) { IsFrontCamera = false; } else { MessageBox.Show("Nincs elérhető kamera!"); } } }

Ennek az eljárásnak az a feladata, hogy kiderítse, hozzáférünk-e egyáltalán a kamerákhoz, és ennek megfelelően inicializálja a tulajdonságokat. Nem lenne szép megoldás, ha ezt a ViewModelt egy Camera objektum példányosítaná, ehelyett vegyünk fel egy statikus tulajdonságot az App osztályban, amin keresztül a View eléri a hozzá tartozó ViewModelt:
private static CameraViewModel cameraVM; public static CameraViewModel CameraVM { get { if (cameraVM == null) { cameraVM = new CameraViewModel(); } return cameraVM; } }

A Camera.xaml kódfájljában pedig módosítsuk úgy a konstruktort, hogy az kérje el az App osztálytól a statikus ViewModelt, majd ezt állítsa be DataContextnek! Amint az oldal betöltődött, inicializáljuk az értékeket a LoadData meghívásával:
CameraViewModel ViewModel; public Camera() { InitializeComponent(); ViewModel = App.CameraVM; DataContext = ViewModel;

158

A Slider lesz az a vezérlő. így a vezérlő értékének módosításával a mögöttes tulajdonság értéke is változik! Egyetlen feladatunk maradt hátra. A fektetett megjelenítés miatt a bal oldalra kerülhet az élőképet mutató Canvas.ColumnDefinitions> <ColumnDefinition Width="600" /> <ColumnDefinition Width="*" /> </Grid.TakePhoto(). így az csak akkor lesz aktív. RoutedEventArgs e) { ViewModel.Kamera használata taszk nélkül this. e) => { ViewModel.ColumnDefinitions> <!--ContentPanel .LoadData(). akkor a projekt telepítése után a 6-17 ábrán látható elrendezést fogjuk látni. hogy a mozgóképet jelképező fekete téglalap melyik irányban mozog. amellyel a kamerák között válthatunk. itt csupán egy függvényhívásra van szükségünk: private void btnPhoto_Click(object sender. Mivel a ViewModel megvalósítja a műveletet. jobbra mellé pedig a vezérlő gombok: <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid. a hátlapon lévő fő kamera esetében pedig azzal megegyező. Az előlapon lévő kamera kiválasztása esetén ez a mozgás az óramutató járásával ellentétes lesz. A kiválasztott kamerát az alapján tudjuk azonosítani. már csupán a megjelenítő felületet kell létrehoznunk.Loaded += (s. a képkészítést indító gomb eseménykezelőjének megírása. 159 . amikor nincs folyamatban lévő képfeldolgozás.Column="1"> <Button Name="btnPhoto" Content="Kép" Click="btnPhoto_Click" IsEnabled="{Binding IsPhotoEnabled}"/> <Slider Value="{Binding IsFrontCamera. amennyiben az IsCameraChooserEnabled tulajdonság true értéket tartalmaz. a gombhoz pedig bekötjük az IsPhotoEnabled tulajdonságot. } Ha sehol nem hibáztunk. hogy az adatkötés kétirányú legyen. Fontos.place additional content here--> <Canvas Name="ContentCanvas" Width="600" Height="440" Background="{Binding CameraBrush}"> </Canvas> <StackPanel Grid. }. } Ezzel be is fejeztük a logika megírását és a ViewModel „behuzalozását”. Mode=TwoWay}" IsEnabled="{Binding IsCameraChooserEnabled}" Minimum="0" Maximum="1"/> </StackPanel> </Grid> A CameraBrush háttérnek való bekötésével festjük fel a pillanatnyi képet a Canvas felületére.

Kép készítésekor a gomb egy időre inaktívvá válik.Frameword dll! MediaLibrary library = new MediaLibrary(). A mentés helye a CaptureImageAvailable eseménykezelő. hogy a kapott képpel kezdjünk is valamit.6. Ehhez egy MediaLibrary példányra lesz szükségünk. ezért hivatkozzunk erre a dll-re projektünkben! A tárolás szintén a ViewModel dolga. amikor a kép már elkészült. ahol korábban már egy // TODO: mentés megírása sort hagytunk. de a felhasználó számára még nem küldtük el az értesítést erről! Így hibakezelésre is lehetőségünk van − de ettől most eltekintünk. amelyen keresztül hozzáférhetünk a telefonon tárolt zenékhez és képekhez. ezt cseréljük most ki az alábbiaknak megfelelően: 160 . A mentés akkor történjen. 6-18 ábra: Értesítés a feldolgozás befejeződéséről Már csak annyi maradt hátra. hogy a kamera váltása megtörtént.Framework szerelvény része. így a MediaLibrary típusú library objektumot a CameraViewModel osztályban deklaráljuk: // Microsoft.Xna.Xna. Az osztály a Microsoft. amiből tudhatjuk. Alapvető telefonos funkciók használata 6-17 ábra: A kamerák képét mutató alkalmazás felülete A slider értékének megváltoztatását követően a téglalap irányt vált. majd a feldolgozás végén egy üzenetablakban kapunk értesítést a feladat befejeződéséről (6-18 ábra). például tároljuk el a készülék médiatárában.

Now.és naptárbejegyzési adatok elérésére megoldást kínáló egyéb lehetőségeket is a PhoneDataSharingContext használatával.CaptureImageAvailable += (s.ToShortTimeString() + ".Show(name + " mentve!"). az előlapon lévő kamera képét ugyanis egy bal oldalra mutató sárga pötty.Current.BeginInvoke(() => { // visszajelzés küldése (UI szál) MessageBox. amelyek egyszerű hozzáférést biztosítanak a telefon valamely funkciójához. }.Összefoglalás Camera. hogy hogyan tudunk a taszkoknál közvetlenebb módon hozzáférni a kamerákhoz és azok képét a médiatárban rögzíteni. Az én emulátoromon például a 6-19 ábra művészeti remekművei készültek. e) => { string name = DateTime. Végigvettük az erre kínált taszkokat. megkülönböztetve a visszatérési értéket is szolgáltató choosereket és a csupán feladatindítást kínáló launchereket. Deployment.SavePictureToCameraRoll(name. A fejezet végén pedig egy példaalkalmazás írásán keresztül láthattuk.Dispatcher. // újra fotózhatunk IsPhotoEnabled = true. e.ImageStream). Ezt követően megnéztük a partner. }). // mentés a médiatárba library. 161 . míg a hátlapon lévőét egy felfelé mutató jelképezi. A funkció működését a fejezet korábbi részeiben bemutatott PhotoChooserTask segítségével ellenőrizhetjük. Összefoglalás A fejezet során rengeteg olyan lehetőséggel ismerkedtünk meg. 6-19 ábra: A kamerák által készített képek Az emulátor ezeknél a képeknél is különbséget tesz a két eszköz között.jpg".

.

Az esemény kiváltásának helyét a GetPosition metódussal kérdezhetjük le.7. és amelyet a felhasználó lassan már anélkül használ. amikor a felhasználó megérint egy vizuális elemet. hogy milyen bonyolultan szeretnénk hozzáférni. Minél mélyebb szinten programozunk. hogy Tap esetén nem lehet megkülönböztetni bal/jobb egérgombot és egyéb egérre jellemző tulajdonságokat. hogyan lehet felhasználni ezeket az eseményeket! 163 . amely egy UIElement típusú paramétert vár. lemehetünk egy szinttel mélyebbre a Manipulation eseményekhez. Tegyük hozzá: elég gyakran még ez az információ sem érdekes. annál pontosabb.5 operációs rendszert futtató telefonokba alapfelszereltségként beépített szenzorokat. amikor a felhasználó rövid időn belül kétszer megérinti egy vizuális elem felületét. Alapvető érintési események Ezeknek az eseménynek a kezelői egy GestureEventArgs típusú paraméterrel rendelkeznek. amikor a felhasználó megérinti egy elem felületét – tulajdonképpen ez a kattintás megfelelője az érintőképernyőn. Szintén a UIElementből származó vezérlőkön és vizuális elemeken értelmezett a DoubleTap esemény. figyelhetünk az egyszerű eseményekre. most azonban egy kicsit mélyebbre hatolunk. vagyis érzékelőket. de annál több munkánk is lesz vele. vagy a legmélyebb szintre. hogy ismerik a RoutedEventArgs leszármazottakra jellemző Handled. de ujját nem emeli fel. Akkor következik be. a Hold. illetve OriginalSource tulajdonságokat – tulajdonképpen csak annyi hasznos információval szolgál. azzal a különbséggel. hogy ott van a telefonban. mint a Tap (érintés) és társai. hanem kb. és ennek az érintés miatt értelme sincsen. ahol a nyers adatokkal dolgozhatunk. egy másodpercig rajta hagyja az elemen. A Silverlight for Windows Phone több szinten teszi elérhetővé a fejlesztő számára az érintőképernyő eseményeit. bonyolultabb algoritmusokat építhetünk az eseményekre. Ebben a fejezetben azt vizsgáljuk. További telefonos funkciók használata Eddig jobbára a telefon szoftveres képességeivel játszottunk. Ez akkor következik be. Ez az érintőképernyő − kétségkívül a legfontosabb szenzor. ehhez a vizuális elemhez képest adja vissza az érintés pozícióját. hogy egyáltalán észrevenné azt. néhány évvel ezelőtt még ritkán építették bele. amit a UIElement osztályon definiáltak. a Touch. hogyan tudjuk kihasználni a Windows Phone 7. Az érintőképernyő kezelése Elsőként azzal az érzékelővel foglalkozunk. DoubleTap Hold Lássuk. mely – azonfelül. Bár ma teljesen természetesnek számít. amely ma már elengedhetetlen része okostelefonjainknak. A harmadik érintési esemény. Attól függően. hogy lekérdezhető belőle az esemény bekövetkezésének helye.FrameReportedig. Ebbe a kategóriába három esemény tartozik: 7-1 táblázat: Érintési események Esemény Tap Leírás A Tap esemény akkor következik be.

hogy hogyan tudunk ilyen transzformációt létrehozni XAML-ben: <Rectangle x:Name="rect" Width="100" Height="100" Fill="{StaticResource PhoneAccentBrush}"> <Rectangle. </Rectangle> A mögöttes kódban pedig csak módosítanunk kell az előbb létrehozott transzformáció Angle tulajdonságát.0"> <Rectangle x:Name="rect" Width="100" Height="100" Fill="{StaticResource PhoneAccentBrush}" /> </Grid> A megoldandó feladat annyi..5.RenderTransform> <RotateTransform Angle="0"/> </Rectangle. </Rectangle> Ezután már csak fel kell iratkozni a Tap eseményre – ezt a szokásos módon tehetjük meg: <Rectangle x:Name="rect" Width="100" Height="100" Fill="{StaticResource PhoneAccentBrush}" Tap="rect_Tap" RenderTransformOrigin=".RenderTransform). További telefonos funkciók használata Készítsünk egy Windows Phone Application sablonra épülő alkalmazást.Row="1" Margin="12.7.5"> ..12. 164 . } Teszteljük le az alkalmazást! A négyzet nyomkodás hatására forog (7-1 ábra). hogy elhelyezzünk a négyzetben egy transzformációt...5"> . de alkalmazhatunk CompositeTransformot. TransformGroupot is. Ezt úgy tudjuk átállítani az elem középpontjára. A transzformációt a UIElement RenderTransform tulajdonságán keresztül tudjuk beállítani. hogy mennyivel kell elfordulnia az elemnek a RenderTransformOriginben megadott pont körül. vagy ha több különálló transzformációra lesz szükségünk. hogy az Angle-t lássuk: private void rect_Tap(object sender.. hogy az egyes tengelyeken hol helyezkedjen el a középpont.RenderTransform> </Rectangle> A forgatás alapesetben a vizuális elem befoglaló négyzetének bal felső sarka körül történik. amit állítgathatunk. és helyezzünk el benne −konkrétan a ContentPanel nevű Gridben − egy négyzetet! <Grid x:Name="ContentPanel" Grid. hogy tapintásra a négyzet forduljon el középpontja körül 10 fokkal jobbra! Ehhez arra lesz szükség.5.0. Természetesen a RenderTransform tulajdonság nem RotateTransform típusú – elvégre 5-6 másik transzformáció-típust is tudnia kell fogadni –. Forgatásra a RotateTransform a legmegfelelőbb. Itt 0 és 1 között relatívan adhatjuk meg. GestureEventArgs e) { ((RotateTransform)rect.Angle += 10. így át kell alakítanunk. Ez fokokban adja meg. Az alábbi kód szemlélteti. hogy átállítjuk a Rectangle RenderTransformOrigin tulajdonságát.. <Rectangle x:Name="rect" Width="100" Height="100" Fill="{StaticResource PhoneAccentBrush}" RenderTransformOrigin=".

. GestureEventArgs e) { rect. rect. tehát ha 1 mp-en belül felengedjük az ujjunkat. Oldjuk meg azt is.. (Emellett persze továbbra is működik a Tap. } Tesztelésnél látható.Az érintőképernyő kezelése 7-1 ábra: A Tap esemény hatása Ha egy transzformációt gyakran akarunk a mögöttes kódban használni. két gyors egymás utáni tapintás (DoubleTap) pedig alaphelyzetbe állítsa! Iratkozzunk fel a Hold eseményre! <Rectangle x:Name="rect" Width="100" Height="100" Fill="{StaticResource PhoneAccentBrush}" Tap="rect_Tap" Hold="rect_Hold" RenderTransformOrigin=". egyszerűbb.) 7-2 ábra – A Hold (és a Tap) esemény hatása 165 . Így megkímélhetjük magunkat a sok típuskonverziótól.Width += 20.5.5"> . </Rectangle> Az eseménykezelőben növeljük meg a négyzet méretét! private void rect_Hold(object sender. hogy a négyzet nyomva tartása (Hold) esetén a négyzet nagyobbra nőjön. akkor elfordul a négyzet. hogy a Hold esemény hatására a négyzet 20-20 képpontonként nő. ha adunk neki egy nevet az x:Name tulajdonságon keresztül.Height += 20..

Height = 100.Angle = 0.RenderTransform). ((RotateTransform)rect. A Windows Phone-nal felszerelt telefonokban alapkövetelmény a legalább négy érintési pontot kezelni képes kapacitív kijelző. amikor a felhasználó megérinti a kijelzőt. Ha ezt meghívjuk. Készítsük be a telefont.RenderTransform> <RotateTransform Angle="0"/> </Rectangle. hogy mely objektumhoz viszonyítva történik a manipuláció (ez maga a manipulált objektum). ami a manipulálás indításakor a ManipulationContainer bal felső sarkához viszonyított pozíciót adja meg – tehát hogy hol nyomták meg az elemet. hanem a ManipulationCompleted esemény fut majd le. hogy előre megfontolt szándékkal egyszerre több ujjával is megérintse a kijelzőt.RenderTransform> </Rectangle> Ezután a mögöttes kódban vissza kell állítani alaphelyzetbe az előzőleg megváltoztatott három tulajdonságot: private void rect_DoubleTap(object sender.7.5"> <Rectangle. nem a ManipulationDelta. Hasznos lehet még tudni. hogy szintén a ManipulationStartedEventArgs része a Complete metódus. Ehhez nem kell több ujját használnia – már egy érintéstől is kiváltásra kerül az esemény. így elviekben semmi nem gátolja a felhasználót abban. ha többérintéses eseményeket szeretnénk tesztelni – az emulátor nem támogatja a több érintést. További telefonos funkciók használata A DoubleTap megoldása is az előbb leírtakat követi. Az események második szintje a többpontos (multitouch) érintések kezelését is lehetővé tevő úgynevezett Manipulation események csoportja. GestureEventArgs e) { rect. rect. amit megnyomtak. Először is fel kell iratkozni az eseményre: <Rectangle x:Name="rect" Width="100" Height="100" Fill="{StaticResource PhoneAccentBrush}" Tap="rect_Tap" DoubleTap="rect_DoubleTap" Hold="rect_Hold" RenderTransformOrigin=". tehát ha a felhasználó továbbra is a kijelzőn tartja ujját.5. } Multitouch manipulációk Az előző események egyetlen ujj érintését jelzik vissza felénk. illetve a ManipulationOrigin tulajdonság. Itt is három eseményt találunk: 7-2 táblázat: Manipulation események Esemény ManipulationStarted Leírás A ManipulationStarted esemény akkor következik be.. Ennek ManipulationContainer tulajdonsága megadja. 166 . az operációs rendszer lezártnak tekinti a manipulációt.Width = 100. Ennek egyik paramétere egy ManipulationStartedEventArgs típusú objektum.

Row="1" Margin="12. hogy mennyit tolódott el az ujjak által kijelölt középpont. Ennek ManipulationDeltaEventArgs paramétere szintén tartalmaz egy ManipulationContainer és egy ManipulationOrigin tulajdonságot. hogy a manipuláció kezdete óta mekkora eltolás és átméretezés történt.12.0. Típusuk megegyezik: ManipulationDelta. A Windows Phone Application sablon alapján készített alkalmazás MainPage lapjának ContentPaneljébe ezúttal egy Bordert helyezzünk el.0"> <Border Name="brd" Width="100" Height="100" BorderBrush="BlanchedAlmond" Background="{StaticResource PhoneAccentBrush}" /> </Canvas> Az átméretezést egy ScaleTransform segítségével szeretnénk végrehajtani – egészítsük ki ezzel a Bordert! 167 . magát a ContentPanelt pedig módosítsuk Gridről Canvas típusúra! <Canvas x:Name="ContentPanel" Grid. Emellett pedig a felhasználó két ujjának közelítésével vagy távolításával képes lesz növelni és csökkenteni a négyzet méretét. hogy előbbi a manipuláció kezdete óta összegyűlt eltéréseket mutatja. hogy egy „Drag” műveletet hajtsunk végre. vagyis amíg legalább egy ujj érinti a kijelzőt. ManipulationCompleted A következőkben arra fogjuk felhasználni ezt a három eseményt. Ennek Scale tulajdonságából megkapjuk azt. hogy a több ujj arányában mennyit távolodott egymástól vagy közeledett egymáshoz. hogy a felhasználó ujjmozdulatok segítségével húzzon arrébb egy objektumot a felületen. a ManipulationDelta eseményt kaphatjuk el. Említésre méltó ezenfelül a ManipulationDeltaEventArgs Velocities tulajdonsága. míg utóbbi csak annak változását. Translation tulajdonságából pedig. amelyek a korábban ismertetettel egyező működésűek. vagyis lehetővé tegyük.Az érintőképernyő kezelése Esemény ManipulationDelta Leírás A manipuláció időtartama alatt. a ManipulationCompleted eseményt jelzi a rendszer. Amikor az utolsó ujj is elhagyja az érintőképernyőt. ManipulationDelta típusú tulajdonságon keresztül adja tudtunkra. Ezenkívül két talán legfontosabb tulajdonsága a CumulativeManipulation és a DeltaManipulation. A különbség a CumulativeManipulation és a DeltaManipulation között. amely a több ujj által kifejtett manipulációt összegzi. Ennek ManipulationCompletedEventArgs típusú paramétere egy TotalManipulation nevű. FinalVelocities tulajdonságával pedig azt mutatja. vagyis a legutóbbi ManipulationDelta esemény óta történt elmozdulást. illetve Complete metódust. hogy az utolsó ujj felemelésekor milyen sebességű volt az átméretezés és eltolás. melyből az ujjak egymástól való távolodásának (ExpansionVelocity) és az eltolásnak a (LinearVelocity) sebességét kaphatjuk meg.

Mivel arányokról van szó (az esemény argumentuma azt adja meg. nem közvetlenül a Borderen találjuk. hanem az előbb említett tulajdonságokat felszorozzuk a megfelelő skálázási komponenssel.5"> <Border. hogy ha mozgatja ujjait. Mivel ez a tulajdonság ún. hanem a GetValue és SetValue metódusok segítségével kérhetjük le. } A ManipulationDelta. Csak egy-egy sor nem túl bonyolult C#-kódra lesz szükségünk: private void brd_ManipulationStarted(object sender.Row="1" Margin="12. Induláskor láthatóvá tesszük a Border keretét.5. } Mivel minden egyes elmozduláskor szeretnénk az előző pozícióhoz képest elmozdítani a vizuális elemet.GetValue( Canvas. nem összeadunk. Itt a Borderbe ágyazott ScaleTransform objektum ScaleX és ScaleY tulajdonságát állítgatjuk.Y *st.GetValue( Canvas. } private void brd_ManipulationCompleted(object sender.ScaleX).SetValue(Canvas. amelyet nem az az objektum definiál. ManipulationCompletedEventArgs e) { brd. (double)brd.7. melyik objektum változik.TopProperty. ManipulationDeltaEventArgs e) { brd. ManipulationStartedEventArgs e) { brd.Translation.DeltaManipulation.RenderTransform> <ScaleTransform x:Name="st" /> </Border.Translation. a végén pedig ismét eltüntetjük.Top tulajdonságainak változtatásával állítjuk – vagyis a Bordert az őt tartalmazó Canvas bal felső sarkához képest mozgatjuk.LeftProperty.TopProperty) + e.LeftProperty) + e.Left és Canvas.0.. </Border> A manipuláció indulásakor és végén vizuális visszajelzést akarunk adni a felhasználónak arról. Ennek Translation tulajdonsága egy X és egy Y értékkel adja meg. attached property (csatolt tulajdonság.X * st. a DeltaManipulationt vesszük igénybe.DeltaManipulation. Az eltolást a brd nevű Borderünk Canvas. illetve állíthatjuk be: private void brd_ManipulationDelta(object sender..BorderThickness = new Thickness(0).RenderTransform> </Border> </Canvas> Iratkozzunk fel a három Manipulation eseményre a Borderen! <Border Name="brd" Width="100" Height="100" BorderBrush="BlanchedAlmond" Background="{StaticResource PhoneAccentBrush}" ManipulationStarted="brd_ManipulationStarted" ManipulationDelta="brd_ManipulationDelta" ManipulationCompleted="brd_ManipulationCompleted"> . Külön kell kezelnünk a 168 . hogy hány képponttal kell arrébb mozgatnunk a Bordert. További telefonos funkciók használata <Canvas x:Name="ContentPanel" Grid. Hasonló módon valósíthatjuk meg a többujjas átméretezést.ScaleY). vagyis az ujjak elmozdulását jelző esemény kezelőjének megírása ennél kicsit bonyolultabb. brd.BorderThickness = new Thickness(5). (double)brd.12. amelyen használjuk)..SetValue(Canvas. Első körben csak az elmozdítást (vagyis a „Drag” effekt megvalósítását) nézzük meg.0"> <Border Name="brd" Width="100" Height="100" BorderBrush="BlanchedAlmond" Background="{StaticResource PhoneAccentBrush}" RenderTransformOrigin=". hogy a korábbi hányszorosára nőtt a méret).

Scale. ManipulationDeltaEventArgs e) { brd.TopProperty. amikor az ujjak közötti távolság nem változna érzékelhető mértékben.DeltaManipulation.ScaleY *= e. hogy az elmozdítás történhet a Canvashoz képest akár negatív irányba is. 7-3 ábra: A négyzet.Az érintőképernyő kezelése nulla átméretezés esetét: ki kell szűrni. (double)brd. Amíg minden ujj el nem engedi a kijelzőt. a TouchFrameEventArgs osztály SuspendMousePromotionUntilTouchUp metódusának meghívásával érhetjük ezt el. Az események csak annyit közölnek velünk. kapunk róla egy FrameReported eseményt. A Touch.DeltaManipulation.Y.Scale. különben a négyzet eltűnne.Scale. amelyekkel követhetjük az ujjak pillanatnyi állapotát. A TouchFrameEventArgs két olyan metódust biztosít.LeftProperty) + e.LeftProperty. elmozdul. A GetPrimaryTouchPoint az elsődleges érintési pontot adja vissza – amelyik legkorábban megérintette a képernyőt. Azonban ekkor nem férünk hozzá a részletekhez. hogy pontosan mi is történik az érintőfelületen. Ennek eseményargumentuma TouchFrameEventArgs típusú. vagyis ki tudjuk rángatni a Bordert a Canvasról! Ha az átméretezés működését is tesztelni szeretnénk.DeltaManipulation. 169 . } Ennyi az egész.X * st.X != 0) st. hogy a több ujj elmozdulásából mit számoltak ki. amelyek leírják. melynek segítségével az események egymástól való időben egymástól való távolságát mérhetjük le. private void brd_ManipulationDelta(object sender. Ha ki akarjuk kapcsolni. Ekkor siet segítségünkre a Touch osztály. Mindkét metódus egy UIElement paramétert vár: ehhez az elemhez képest adja vissza a pontokat.X. Egyetlen tulajdonsága a TimeStamp nevű integer. Gyakran ez elég is.ScaleX *= e. magasabb szinten nem támogatott ujjmozdulat kezelése megvalósítható.ScaleX).DeltaManipulation. amikor pontosabb.Translation. A GetTouchPoints az összes aktuális érintési pontot visszaadja.Scale.SetValue(Canvas.DeltaManipulation. brd.DeltaManipulation. mindenképpen szükségünk lesz egy telefonra is (7-3 ábra). a Manipulation események segítségével jó néhány.ScaleY). –. a program tesztelhető! Figyeljük meg.Y *st. mélyebb szintű adatokra van szükségünk. if (e.SetValue(Canvas. hogy a magasabb szintű eseményeket is feldobja a rendszer. Bármilyen változás történik az érintőfelületen – egy ujj megérinti a képernyőt. eredeti pozíciójából elmozgatva A nyers érintési adatok kezelése Ahogy láthattuk. csak FrameReported eseményeket kapunk. ez a FrameReported.TopProperty) + e.GetValue( Canvas. (double)brd.Translation. akad azonban olyan szituáció. stb.Y != 0) st.GetValue( Canvas. if (e.FrameReported esemény A Touch osztály csupán egyetlen eseménnyel bír.

/// </summary> public static class IntColorConversion { static int colorscount = 0.Count(). egy nagyobbacska kört jelenítünk meg az ujja alatt.FrameReported += new TouchFrameEventHandler(Touch_FrameReported). Rajzoljunk egy 50*50 képpont méretű kört a lenyomás helyén! A színt egy kis segédosztállyal választjuk ki. TouchFrameEventArgs e) { var pts = e. hanem az érintést kiváltó ujjat.Linq. a Colors felsorolt típus tulajdonságainak megszámlálásával visszaadunk egy színt az integer értékből. Ezt például a MainPage konstruktorában tehetjük meg: public MainPage() { InitializeComponent(). amelyet kézzel írunk meg. Ennyi alapozás után már csak egy kis logika kell egy faék egyszerűségű. de több érintést kezelő rajzprogram létrehozásához. Ennek három értéke lehet: Down (érintés). az ahhoz az ujjhoz tartozó köröket eltüntetjük.GetTouchPoints(ContentPanel).12. hogy éppen milyen esemény történt az adott ponton. hogy hol történt az esemény. Ezzel tudjuk megkülönböztetni. Amikor a felhasználó megérinti a képernyőt. hogy mekkora a lenyomott felület. using System. amelyek újak. Minimális Reflectionnel. namespace LowLevelTouch { /// <summary> /// Integerek színné alakítása. kisebb köröket. static IntColorConversion() { colorscount = typeof(Colors). A TouchPoint típusú objektumok Action tulajdonsága megadja.xaml fájljában cseréljük le a ContentPanel típusát Canvasra! A XAML-ben ezzel el is végeztük minden dolgunkat: <Canvas x:Name="ContentPanel" Grid. } 170 . A Windows Phone Application sablonnal létrehozott alkalmazás MainPage. de minden ujjé mással.Windows. a Size pedig. További telefonos funkciók használata Az előbbi metódusok visszatérési típusa TouchPoint.0"></Canvas> A mögöttes kódban először is fel kell iratkoznunk a Touch osztály FrameReported eseményére. vagyis ahol éppen megérintették a képernyőt! Ezt az Action tulajdonság Down értéke jelzi. majd ahogy mozgatja az ujját a kijelzőn. Amikor egy ujját felengedi. } Ezután menjünk végig az érintési pontokon! Először azokat kezeljük. mindezt egy bővítő függvénnyel: using System. Move (elmozdulás) és Up (felengedés). A Position tulajdonság megadja. és kérjük le benne az érintési pontokat a ContentPanel (a Canvasunk) bal felső sarkához képest! void Touch_FrameReported(object sender. Touch.Media. illetve TouchPointCollection.GetProperties().0. hogy az egyes TouchPointok mely ujjhoz tartoznak. Emellett persze az egyazon ujjhoz tartozó körök mindig ugyanazzal a színnel jelennek meg. } Ezután hozzuk létre az eseménykezelő metódust.Row="1" Margin="12. A TouchDevice tulajdonság kicsit félrevezető nevű: nem az érintést kiváltó eszközt azonosítja (hiszen az mindig ugyanaz lenne).7.

Position.Position. Fill = new SolidColorBrush(p.ToColor()) }. null). A Move Action értékkel rendelkező elemek pozíciójára egy-egy kisebb kört rajzolunk: void Touch_FrameReported(object sender. el.Id. el.10).Position.Add(el). } } } 171 .Id.Children. Height = 20.X .TopProperty.GetTouchPoints(ContentPanel).Id-t.Children. p.10). } } } Ez után a kis kitérő után már meg tudjuk írni a kört létrehozó kódot.GetProperties()[id + 1 % colorscount] .Id. A már korábban a kijelzőn lévő ujjak további útjának kirajzolása hasonló elven történik.Down) { Ellipse el = new Ellipse { Width = 50.SetValue(Canvas.LeftProperty.Az érintőképernyő kezelése public static Color ToColor(this int id) { return (Color)typeof(Colors). el.Id.Add(el).Position. } else if (p.Move) { Ellipse el = new Ellipse { Width = 20. foreach (TouchPoint p in pts) { if (p. illetve ne felejtsük el megjeleníteni a kört azzal. ContentPanel. } } } A Tag tulajdonság igazi funkcióval nem rendelkezik – pont olyan helyzetekre készült.SetValue(Canvas. objektumot eltárolni. hogy hozzáadjuk a ContentPanel gyermekelemeihez! void Touch_FrameReported(object sender.Position. ContentPanel.Action == TouchAction.Y .Id.Action == TouchAction. el. Két apróságra ügyeljünk: tároljuk el az újonnan létrehozott kör Tag tulajdonságában a TouchDevice.25). hozzárendelni az elemhez.X .Add(el). p. Height = 50. Tag = p.TopProperty.TouchDevice. Fill = new SolidColorBrush(p.Down) { Ellipse el = new Ellipse { Width = 50.SetValue(Canvas.SetValue(Canvas.LeftProperty. el. el. Fill = new SolidColorBrush(p. a vizuális elemhez kapcsolódó adatot. Height = 50.X . Tag = p.SetValue(Canvas. ContentPanel. Tag = p.25).TouchDevice.TouchDevice.25).Id. foreach (TouchPoint p in pts) { if (p.TopProperty.ToColor()) }. p.Position.Children.25). p.Y .SetValue(Canvas. TouchFrameEventArgs e) { var pts = e. amikor szeretnénk valamilyen. p.TouchDevice.Action == TouchAction.TouchDevice.GetValue(null.ToColor()) }. TouchFrameEventArgs e) { var pts = e. p.LeftProperty.GetTouchPoints(ContentPanel).TouchDevice.Y .

végigszaladjunk a Canvasban lévő Ellipseeken.Children where item is Ellipse && (int)((Ellipse)item).Id-t.Position.TouchDevice.10).TouchDevice. p. } } } Az alkalmazás kész.Action == TouchAction.LeftProperty.SetValue(Canvas. és amelyiknek a Tag értéke megegyezik az aktuális Taggel.ToColor()) }.GetTouchPoints(ContentPanel).ToColor()) }. Tag = p. p.TouchDevice.Position.Children.25).X . Csupán annyi a dolgunk. ahol korábban megfordult.Action == TouchAction. foreach (TouchPoint p in pts) { if (p.Add(el).ToList(). el.Tag == p.7. TouchFrameEventArgs e) { var pts = e. ContentPanel. Tag = p. void Touch_FrameReported(object sender. ContentPanel. foreach (Ellipse el in q) ContentPanel. akkor persze mindenképpen telefonon kell tesztelnünk (7-4 ábra). } else if (p. el. hogy amikor egy Action az Up értéket vette fel.Position. el.Action == TouchAction.Id select item as Ellipse). hogy amikor egy ujjbegy elereszti a kijelzőt. Ezért tároltuk el az Ellipse-ek Tag tulajdonságában a TouchDevice. p. tesztelhető.10).TopProperty.Down) { Ellipse el = new Ellipse { Width = 50. Ha több színt is szeretnénk látni. el. Fill = new SolidColorBrush(p. 7-4 ábra – Nem Imagine Cup logó 172 . Height = 50. Height = 20.TopProperty.LeftProperty.Id.TouchDevice.TouchDevice.SetValue(Canvas.Y .Children.Id. } else if (p.Move) { Ellipse el = new Ellipse { Width = 20. törlünk minden pontot.Children. További telefonos funkciók használata Az utolsó lépés.Id. Fill = new SolidColorBrush(p.Position.X .Add(el).Up) { var q = (from item in ContentPanel. azt töröljük.SetValue(Canvas.Remove(el).25). p.Y .SetValue(Canvas.Id.

A GeoCoordinate egy példányából kinyerhetjük a helymeghatározás vízszintes és függőleges pontosságát (HorizontalAccuracy és VerticalAccuracy tulajdonságok). A GPS lassabban áll be. hogy igénybe veszi-e a GPS-t a telefon. mikor történt a mérés). hogy ha nagyon gyorsan rajzolunk. hiszen például a cellainformáció keresése csupán az amúgy is bekapcsolt állapotban lévő mobilrendszert veszi igénybe. de a GeoCoordinateWatcher konstruktorában be is állíthatjuk (két értéke: Default és High). de általában elég – cserébe pedig gyors. Az esemény csak akkor kerül kiváltásra. hogy nem méterre pontos. Hacsak nem kér a program nagy pontosságú helymeghatározást. ismert wifi-pontok alapján határozza meg a helyzetet.RowDefinitions> <Grid. méterben mért távolságra kerültünk az előző eseményben rögzített pozíciótól.0. bár tény. hiszen meg kell találnia 3-4 műholdat. mely lehetővé teszi a Föld körül keringő GPS műholdak által a telefon pontos helyének meghatározását. érdemes elgondolkodnunk rajta. A helymeghatározás azonban ennél jóval többet jelent. Ez. Ez adja meg. Ennek egyetlen tulajdonsága Position típusú. merre tart (Course) és milyen gyorsan halad ebbe az irányba (Speed). hogy mennyire pontos a helymeghatározás. és keveset fogyaszt. Amikor a Windows Phone-on egy alkalmazás igénybe veszi a helymeghatározást.aspx#BKMK_UserInput Az érintőképernyő felhasználási módjainak megismerése után hatoljunk be az eszközök belsejébe! Helymeghatározás A Windows Phone-telefonok alapfelszereltségének része egy Assisted GPS.RowDefinitions> <RowDefinition Height="80" /> <RowDefinition Height="80" /> <RowDefinition Height="80" /> <RowDefinition Height="80" /> </Grid.12. A helymeghatározás használata nagyon egyszerű. ha előzőleg meghívtuk a GeoCoordinateWatcher Start metódusát (és a Stopot még nem). A PositionChanged esemény második argumentuma GeoPositionChangedEventArgs<GeoCoordinate> típusú. Fontos tulajdonság még a DesiredAccuracy. amikor a MovementThreshold tulajdonságban beállított. valamint természetesen a hosszúsági és szélességi értékeket (Longitude és Latitude tulajdonságok). valamint egy Location tulajdonságot. A Microsoft ajánlása ezzel – és a telefon más teljesítményigényes alkalmazásainak helyes használatával – kapcsolatban az alábbi linken érhető el: http://msdn. Jó tudni: Ha a teljesítmény is szempont. a telefon csak a legvégső esetben nyúl a GPS-hez.0"> <Grid. Kicsit bonyolultabb algoritmusokkal (legutolsó érintési pontok eltárolása. ami megmondja. A GeoCoordinateWatcher osztályon keresztül nyerhetjük ki a szükséges információkat a telefonból.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> 173 . illetve több energiát fogyaszt.Row="1" Margin="12. hogy gyorsabban húztuk végig ujjunkat a kijelzőn.92). mely GeoCoordinate típusú. hogy a tengerszinthez képest milyen magasságban van a telefon (Altitude tulajdonság). mely esemény-réteget használjuk fel.com/enus/library/ff967560(v=VS. Line-ok használata) ez is kiküszöbölhető. a körök elszakadhatnak egymástól! Ez azt mutatja. az operációs rendszer először a cellainformációk és az esetleg elérhető.Helymeghatározás Vegyük észre. Ez a tulajdonság csak lekérdezhető.microsoft. vagyis. mely egy Timestampet tartalmaz (egy DateTimeOffset. Hozzunk létre egy alkalmazást a Windows Phone Application sablonnal! A MainPage ContentPanel Gridjét töltsük fel néhány elemmel az alábbi módon: <Grid x:Name="ContentPanel" Grid. A PositionChanged eseményt akkor dobja fel egy GeoCoordinateWatcher objektum. mint ahogy a 60Hz frissítésű panel követni tudta volna. Ezenfelül pedig információt szolgáltat arról is.

Row="3" /> <CheckBox Name="cbHighAccuracy" Content="Nagy pontosság" Grid. majd ezek után vegyük fel a System. hozzunk létre egy GeoCoordinateWatcher példányt.Row="3" Grid. szabadítsuk fel azt.Column="1" /> <Button Name="btnGetCoordinates" Content="Indítás" Click="btnGetCoordinates_Click" Grid.Row="2" Grid. és indítsuk el a figyelőt! Végül pedig állítsuk át a gomb szövegét! A null értéket tesztelő elágazás else ágában iratkozzunk le az eseményről. public MainPage() { InitializeComponent().Column="1" /> <TextBlock Name="tbkTimeStamp" Grid.Column="1" /> </Grid> Ahhoz. A MainPage-ben hozzunk létre egy GeoCoordinateWatcher referenciát! Ha a XAML-tervező nem hozta létre automatikusan.High : GeoPositionAccuracy. 174 .Row="1" /> <TextBlock Name="tbkVertAccu" Grid.Column="1" /> <TextBlock Name="tbkHorAccu" Grid.7.Location. } private void btnGetCoordinates_Click(object sender. hogy a felhasználó bekattintotta-e az erre vonatkozó jelölőnégyzetet! Írjunk fel egy metódust a PositionChanged eseményre. állítsuk le a figyelőt.Row="2" /> <TextBlock Name="tbkSpeed" Grid. } private void btnGetCoordinates_Click(object sender. a pontosságot attól függően állítsuk be.Device. ha még null értékű a gcw referenciánk. RoutedEventArgs e) { } } Ezután a gomb eseménykezelőjében.Default).Device. RoutedEventArgs e) { if (gcw == null) { gcw = new GeoCoordinateWatcher((bool)cbHighAccuracy.Device dll-re. További telefonos funkciók használata </Grid. public MainPage() { InitializeComponent().Location névteret! using System.ColumnDefinitions> <TextBlock Name="tbkLat" /> <TextBlock Name="tbkLong" Grid. hogy a Geolocation API-t felhasználhassuk. szükségünk lesz a System.IsChecked ? GeoPositionAccuracy. akkor írjuk meg az egyelőre üres Click-kezelő metódust is! public partial class MainPage : PhoneApplicationPage { GeoCoordinateWatcher gcw = null. és írjuk vissza a gomb feliratát! public partial class MainPage : PhoneApplicationPage { GeoCoordinateWatcher gcw = null.Row="1" Grid. ezt adjuk hozzá a projekt referenciáihoz.

Start(). amit az emulátornak végig kell járnia! 7-5 ábra – Az Additional Tools megnyitása Ha megvannak a pontok. megfelelően kezeljük: kiírjuk a kapott adatokat a képernyőre. 175 .Position. void gcw_PositionChanged(object sender.Location. tbkVertAccu.Timestamp.Position. de ha épp nincs kedvünk vagy lehetőségünk rá.Location. majd itt.Text = e.Position.Text = e.Text = e. GeoPositionChangedEventArgs<GeoCoordinate> e) { } } Már csak annyi dolgunk maradt.Location.Speed + " m/s". láthatjuk.ToLongTimeString(). Az elindított emulátor mellett látható dupla nyílra (7-5 ábra) kattintás hatására megjelenő ablakban válasszuk a Location fület.ToString(). } Az alkalmazást – ahogy minden érzékelőket használó alkalmazást – érdemes fizikai eszközön tesztelni. az emulátor is megfelelhet.DateTime.Longitude.Location.Location. ahogy változnak a koordináták a szimuláció közben (7-6 ábra).Latitude.Text = e.HorizontalAccuracy. btnGetCoordinates. kapcsoljuk ki a fent látható „Live” gombot.Helymeghatározás gcw. } } void gcw_PositionChanged(object sender. tbkHorAccu.PositionChanged -= gcw_PositionChanged. hogy amikor a gcw feldobja az eseményt.Dispose().Text = e.Position. gcw.ToString() + " m".Stop().PositionChanged += gcw_PositionChanged. GeoPositionChangedEventArgs<GeoCoordinate> e) { tbkLat.Content = "Leállítás".ToString() + " m". tbkTimeStamp. tbkSpeed. } else { gcw. tbkLong. btnGetCoordinates. és kattintsunk a lejátszásra! Ha az emulátorban elindítottuk a GeoCoordinateWatchert. gcw.Text = e.Position.Content = "Indítás".Position.VerticalAccuracy. a térképre kattintgatva jelöljük ki a pontokat.ToString(). gcw.

hogy milyen irányban hat gyorsulás a telefonra. közelségi szenzort. illetve a PhoneApplicationPage-ek OnNavigatedFrom eseménye. a vektor X. Egy kép „ugrál” a képernyőn. mint a helye. Ennek IsSupported nevű statikus tulajdonsága megmondja. és ezt kell eltalálni egy célkereszttel. ha megváltozott az eszköz helyzete – de itt is a Start és a Stop metódusok hívása között történik csak figyelés.7. hogy elérhető-e a gyorsulásmérő. További telefonos funkciók használata 7-6 ábra – A felvett útvonal lejátszása Ne felejtsük el leállítani az érzékelőket. A szokásos Windows Phone Application sablonra építve egy egyszerű ügyességi alkalmazást hozunk létre. Y és Z komponensei is változnak. A gyorsulásmérőt az Accelerometer osztályon keresztül érjük el. jelen könyvben azonban máshol mutatjuk be ezek használatát. Egy Accelerometer objektum létrehozása után a CurrentValueChanged eseményen keresztül kapunk értesítést arról. amin majd a célba talált lövéseket számláljuk! Ezenfelül pedig iratkozzunk fel a ContentPanel Tap eseményére: 176 . A gyorsulásmérő használata A gyorsulásmérő megadja. amikor nincs rájuk szükség! A tökéletes helyek erre az alkalmazás Deactivated és Closing eseményei. illetve egy TextBlockot. hanem a helyzetmeghatározó érzékelőkre is vonatkozik. Adjunk egy célt és egy célkeresztet ábrázoló képet a projekthez. Nem mindegyik érhető el ezek közül. amit elérünk! Telefonunk helyzetének meghatározása – vagyis. hogy éppen hogyan tartja és mozgatja a felhasználó – legalább olyan fontos információkkal szolgálhat. tehát alapesetben ez egy a Föld középpontja felé mutató vektor. Néha szokás a szenzorok közé sorolni a kamerát és a mikrofont. Helyzetmeghatározás Nem a GPS az egyetlen szenzor. amelyek jelenítsék meg a képeket. Ahogy forgatjuk a telefont. A CurrentValueChanged esemény második argumentuma SensorReadingEventArgs<AccelerometerReading> típusú. Ez nemcsak a helymeghatározó. amelyben az X. illetve egy Acceleration nevűt. majd a MainPage ContentPaneljét alakítsuk át Canvasszá! Helyezzünk el benne két Image vezérlőt. A Windows Phone 7-nel szerelt eszközöknek tartalmazniuk kell többek között egy gyorsulásmérőt (accelerometer). de ezenkívül még lehet bennük iránytű (magnetometer). melyet a gyorsulásmérő segítségével (vagyis a telefon forgatásával) mozgatunk. Y és Z komponenseket érjük el. illetve giroszkóp. Ennek SensorReading tulajdonságában egy Timestamp nevű tulajdonságot találunk (DateTimeOffset. hogy mennyi idő telt el az előző mérés óta). Ez a tulajdonság egyébként a többi érzékelőosztályon is megtalálható. érdemes ennek ellenőrzésével kezdeni a munkát.

Adjuk hozzá ezt a referenciákhoz. amivel számlálunk. GestureEventArgs e) { } } Az Accelerometer a Microsoft.. majd a usingok közé rakjuk be a hasonló nevű névteret!Ezenfelül még a Microsoft.CurrentValueChanged += new accel_CurrentValueChanged.0" Tap="ContentPanel_Tap"> <TextBlock Name="tbkHits" Text="0" /> <Image Name="target" Source="kenny.0. null. public partial class MainPage : PhoneApplicationPage { Timer timer = null..Framework nevű dll-t kell felvennünk a referenciák közé.Devices. int hits = 0. public MainPage() { InitializeComponent(). :(")..Sensors. 5000).MainPage" . accel. } private void ContentPanel_Tap(object sender.png" /> <Image Name="crosshair" Source="crosshair-red.Xna.IsSupported) { accel = new Accelerometer().IsVisible="True" Loaded="PhoneApplicationPage_Loaded"> Az eseménykezelőben inicializáljuk az objektumokat. } void accel_CurrentValueChanged(object sender. 5000. timer = new Timer(TimerEvent.12.png" /> </Canvas> A célpontot azonos időközönként szeretnénk véletlenszerűen elhelyezni. RoutedEventArgs e) { if (Accelerometer. Accelerometer accel = null.Start().Row="1" Margin="12. } else MessageBox. SensorReadingEventArgs<AccelerometerReading> e) { } 177 .Devices.Show("Nincs gyorsulásmérő. shell:SystemTray. és indítsuk el a gyorsulásmérőt! public partial class MainPage : PhoneApplicationPage { . accel.Helyzetmeghatározás <Canvas x:Name="ContentPanel" Grid. Random rand = new Random(). tehát egy Timerre és egy Randomra lesz szükségünk – valamint természetesen egy Accelerometerre és egy integerre. using Microsoft.. private void PhoneApplicationPage_Loaded(object sender. Iratkozzunk fel az oldal Loaded eseményére! <phone:PhoneApplicationPage x:Class="AccelerometerHandling.Sensors dll -ben található.

hogy ezzel nem csúszna-e ki a célkereszt a ContentPanel valamelyik szélén: void accel_CurrentValueChanged(object sender. newLeft). crosshair.LeftProperty.7.Acceleration. egy InvalidOperationException lesz a jutalmunk. rand. else if (newLeft > 450) newLeft = 450.GetValue(Canvas. ezt kell felszoroznunk a ContentPanel szélességével és magasságával. else if (newTop > 700) newTop = 700. Mivel az esemény nem a UI-szálon következik be. és írjuk ki a képernyőre az aktuális értéket! private void ContentPanel_Tap(object sender.BeginInvoke(() => { double newLeft = (double)crosshair.SetValue(Canvas. tbkHits. ezt a kódot is a Dispatcheren keresztül tudjuk csak úgy futtatni. if (newLeft < 0) newLeft = 0. } Ezután ellenőrizzük le. A kódban kiszámoljuk. rand.GetValue(Canvas. hogy probléma nélkül hozzáférjen a UI-szálhoz. } } Már csak a lényeg maradt hátra: kezeljük le a gyorsulásmérő változását. if (newTop < 0) newTop = 0. target.LeftProperty.LeftProperty) (double)crosshair.TopProperty. kivonva belőle a célkép szélességét és magasságát.ToString().GetValue(Canvas. hogy a jelenlegi X és Z tengelyen vett gyorsulással hány képponttal szükségeltetik arrébb tolni a célkeresztet.SetValue(Canvas. vagyis a célkereszt a célkép felett van-e! Ha igen.SensorReading.SensorReading.GetValue(Canvas.SetValue(Canvas. }). private void TimerEvent(object o) { Dispatcher. SensorReadingEventArgs<AccelerometerReading> e) { Dispatcher.TopProperty) + e. GestureEventArgs e) { } } A Timer eseményének kezelőjében helyezzük át a célképet egy véletlenszerű pozícióra! A Random osztály NextDouble metódusa egy 0 és 1 közötti értéket ad.Acceleration.TopProperty)) < 20) { hits++.Text = hits. a Dispatcher objektumon keresztül tudjuk ezt megtenni. GestureEventArgs e) { if (Math. hogy amikor a felhasználó megtapintja a kijelzőt.NextDouble() * 430).LeftProperty) + e. növeljük meg a számláló értékét. mozgassuk a célkeresztet! Mivel a gyorsulásmérő eseménye is háttérszálon fut le.X * 10. leellenőrizzük. a két kép fedi-e egymást.TopProperty) (double)crosshair.BeginInvoke(() => { target. de mielőtt még ezt megtennénk.Abs((double)target. Ha közvetlenül próbáljuk. További telefonos funkciók használata private void TimerEvent(object o) { } private void ContentPanel_Tap(object sender.NextDouble() * 600).GetValue(Canvas.GetValue(Canvas.Abs((double)target.LeftProperty)) < 20 && Math.Z * 10. 178 . double newTop = (double)crosshair.

Ez a korábban már megismert X. A mintavételezés a TimeBetweenUpdates tulajdonságban megadott intervallummal történik. hogy a felhasználó hogyan mozgatja térben a telefont.0. melyek az egyes tengelyeken mért forgási sebességet adják meg radián per másodpercben. newTop). } Az alkalmazás kész. ismét az Advanced Toolsra lesz szükségünk. float típusú mezőket tartalmazza. A CurrentValueChanged esemény második argumentuma jelen esetben SensorReadingEventArgs<GyroscopeReading> típusú. Ezek között jelen esetben is van egy Timestamp nevű.TopProperty. a korábbiakkal azonos funkciójú DateTimeOffset.0"> <Ellipse Name="ellipse" Width="100" Height="100" Fill="{StaticResource PhoneAccentBrush}" /> </Grid> 179 . ami GyroscopeReading típusú. a giroszkóp segítségével megállapíthatjuk. ContentPaneljében pedig elhelyezünk egy kört: <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12. de azért élvezhető A giroszkóp használata Míg a gyorsulásmérő a telefon helyzetét mérte. Ennek SensorReading tulajdonsága az. Mivel a giroszkóp nem tartozik a telefonok alapfelszereltségébe. Másik tulajdonsága pedig a Vector3 típusú RotationRate. hogy irányítsuk a gyorsulásmérőt. ami működéséhez mással nem tudja pótolni ezt az érzékelőt.Helyzetmeghatározás crosshair. tesztelhető. Példaalkalmazásunk most is a Windows Phone Application sablonra épül. ezért ne építsünk rá olyan programot. és tárolja a számunkra hasznos információkat.12. A CurrentValueChanged eseményére való feliratkozás és a Start metódus meghívása után egy háttérszálon kapjuk az eseményeket. A giroszkóp használata programozási szinten alig tér el valamiben a gyorsulásmérőétől! A giroszkópot a Gyroscope osztály egy példányán keresztül érjük el. }). 7-7 ábra – Nem egy Korszerű Hadviselés 3.SetValue(Canvas. Y és Z nevű. Ha nem akarjuk vagy tudjuk fizikai eszközön tesztelni.

Devices. gyro. 0.Xna. public MainPage() { InitializeComponent(). Loaded="PhoneApplicationPage_Loaded"> Adjuk hozzá a projekthez a Microsoft. Az iránytűt a Compass 180 . gyro. }). amikor előre-hátra döntik.Framework referenciákat. } else MessageBox. SensorReadingEventArgs<GyroscopeReading> e) { } } Ezután már csak kezelni kell az eseményt. 0.BeginInvoke(() => { ellipse. Adjunk hozzá egy Gyroscope referenciát az oldalhoz.RoutedEventArgs e) { if (Gyroscope.IsSupported) { gyro = new Gyroscope(). és a usingok közé tegyük be a Microsoft.SensorReading.RotationRate.Sensors..Sensors névteret! using Microsoft.7. } void g_CurrentValueChanged(object sender.Devices. További telefonos funkciók használata Emellett feliratkozunk az oldal betöltődését jelző eseményre: <phone:PhoneApplicationPage x:Class="GyroHandling. Amikor oldalt forgatják a telefont. } Az alkalmazás kész. már csak egy olyan telefont kell találni. System. akkor pedig függőlegesen: void g_CurrentValueChanged(object sender.Windows. leánykori nevén iránytű. és indítsuk el! public partial class MainPage : PhoneApplicationPage { Gyroscope gyro = null. iratkozzunk fel CurrentValueChanged eseményére.Devices. oldalirányban növeljük meg a korábban létrehozott kör méretét.Sensors és a Microsoft.SensorReading.MainPage" . 0.Height = 100 + 600 * e. gyro.TimeBetweenUpdates = new TimeSpan(0.Z.CurrentValueChanged += g_CurrentValueChanged.RotationRate. } private void PhoneApplicationPage_Loaded(object sender. 50). Az iránytű használata Az előzőektől eltérő működésű érzékelő a magnetométer.Show("Kevés a giroszkóp.Start().X. ellipse.Width = 100 + 350 * e. és a Loaded eseménykezelőjében − ha van giroszkóp − hozzuk létre. SensorReadingEventArgs<GyroscopeReading> e) { Dispatcher. Az iránytűhöz tartozó objektum létrehozása és a kapcsolódó infrastrukturális kód a már megszokott.").. amin tesztelni is tudjuk.

Row="1" Margin="12.12. Az utolsó tulajdonság pedig a HeadingAccuracy nevű double érték. egyre halványabb (átlátszóbb) legyen. csak a geográfiai északi sarkkal. hogy az operációs rendszer éppen kalibrálja az iránytűt. Statikus IsSupported tulajdonsága megadja. <Grid x:Name="ContentPanel" Grid. A TrueHeading ugyanezt teszi. amelyekből az irányt kaphatjuk meg. Végül a MagnetometerReading nevű.png" /> <TextBlock Name="tbkOpacity" Text="0" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="56" /> </Grid> </Grid> </phone:PhoneApplicationPage> A szokásos módon. Y és Z tengelyén mérve hány microtesla érzékelhető. Emellett pedig három másik. illetve a Start és Stop metódusokkal elindítani. Az Image és TextBlock elemeket adjuk hozzá a ContentPanelhez. hogy a telefon X... Érdemes még tudni.0. hogy feliratkozhatunk a Calibrate eseményre is. dél felé nézve teljesen tűnjön el.. és indítsuk el azt – ha támogatott az iránytű: public partial class MainPage : PhoneApplicationPage { Compass compass = null. SensorReading tulajdonságában ott van a jól ismert Timestamp tulajdonság. hogy mekkora a mérés pontatlansága. leállítani az irány figyelését.RoutedEventArgs e) { if (Compass.MainPage" .Windows. akkor jelenjen meg teljes egészében.. Vector3 típusú tulajdonság megadja. hogy támogatott-e ez a szenzor az eszközön. System. mely arról tájékoztat. Sajnos az emulátor ezt sem támogatja… A példányosítás után itt is egy CurrentValueChanged nevű eseményre tudunk feliratkozni. Loaded="PhoneApplicationPage_Loaded"> <Grid x:Name="LayoutRoot" Background="Transparent"> . Akkor készítsük el a Magnetométert! A Windows Phone Application sablon ContentPaneljén jelenítsünk meg egy képet! Ennek átlátszóságát szeretnénk úgy beállítani. amikor pedig elfordulunk északtól.IsSupported) 181 . hogy fokokban mérve merre néz a telefon a mágneses északi sarkhoz képest. public MainPage() { InitializeComponent(). A MagneticHeading nevű lebegőpontos érték megadja.0"> <Image Name="img" Source="magneto. mely fokokban mérve megmondja. a projekt referenciái közé vegyük fel a Microsoft.Helyzetmeghatározás osztály jelképezi. Ezenkívül pedig egy TextBlockban megjelenítjük a valódi északi sarkhoz viszonyított irányunkat. Adjunk hozzá egy Compass mezőt az oldalhoz. hogy amikor pontosan észak – pontosabban a mágneses északi sark – felé nézünk. } private void PhoneApplicationPage_Loaded(object sender.Devices.Sensors nevű dll-t. illetve iratkozzunk fel az oldal Loaded eseményére: <phone:PhoneApplicationPage x:Class="MagnetometerHandling. majd a Loaded eseménykezelőben állítsuk azt be! Iratkozzunk fel a CurrentValueChanged eseményére.Devices. A CurrentValueChanged esemény második argumentuma SensorReadingEventArgs<CompassReading> típusú.Sensors. a usingok közé pedig az azonos nevű névteret! using Microsoft.

} void compass_CurrentValueChanged(object sender. compass. } else MessageBox.MagneticHeading .SensorReading.ToString(). compass. 7-8 ábra: Mérjük meg a mágneses erőket 182 . További telefonos funkciók használata { compass = new Compass(). if (e. else maghead = (e. img.Text = e.(e.BeginInvoke(() => { tbkOpacity.Opacity = maghead. SensorReadingEventArgs<CompassReading> e) { } } A CurrentValueChanged esemény a megszokott módon egy háttérszálon történik.MagneticHeading < 180) maghead = 1 .SensorReading.SensorReading. mivel az emulátoron nem támogatott az iránytű (7-8 ábra). else if (e. amelynek a déli oldala fás!").180) / 180.7. tesztelhető – de csak telefonon.Show("Keress olyan mohát.TrueHeading. így belsejében – szintén megszokott módon – a Dispatcher és némi matematika segítségével állítjuk be a kép Opacity és a TextBlock Text tulajdonságát: void compass_CurrentValueChanged(object sender.SensorReading. SensorReadingEventArgs<CompassReading> e) { Dispatcher. double maghead = 0.MagneticHeading / 180).SensorReading. } Kész is a program.Start(). }).CurrentValueChanged += compass_CurrentValueChanged.MagneticHeading == 0) maghead = 1.

Készítsünk egy alkalmazást a Visual Studio Windows Phone Application sablonjának segítségével! Iratkozzunk fel a MainPage Loaded eseményére. illetve a ContentPanelben helyezzünk el egy képet! Ez utóbbit szeretnénk a Motion API segítségével mozgatni. mennyire fordult el a telefon. illetve arra. Ahhoz. Amennyiben nincs giroszkóp a telefonban.MainPage" . Az eszköz gyorsulása – ez a gravitáció nélkül értendő. hogy támogatott-e a Motion API az eszközön. különválasztva a gravitáció irányát és a tényleges gyorsulást.png" Height="550"></Image> </Grid> </Grid> </phone:PhoneApplicationPage> 183 .0"> <Image Name="img" Source="arrow. Az igazi nóvum az Attitude. hogy az alkalmazás számára hasznos információkat nyerjünk ki az érzékelőktől érkező adatokból. hogy éppen merre. a Yaw pedig a Z-tengely mentén vett elfordulás. hogy több érzékelő adatait is összevessük. Az eszköz három tengelye körül vett forgási együtthatók.. A fejlesztők munkáját megkönnyítendő a Microsoft a Windows Phone 7. a Vector3 típusú tulajdonságok tulajdonképpen a gyorsulásmérő és a giroszkóp adatait adják vissza – előbbit némileg módosított formában. gyakran sok matematikázásra van szükség. Ahogy látható. a Roll az Y-tengely. releváns információkat ad... Például nem szükséges a gyorsulás komponenseiből kiszámolnunk. Ezek az egyes tengelyek körül vett elfordulások. ezzel is időt spórolva meg a fejlesztőnek. a DeviceRotationRate egy nullvektort tartalmaz. Ez a Motion API. A Motion API-t a Motion osztályon keresztül érjük el. a Roll és a Yaw. a Gyroscope és a Compass osztályok) fölé.Helyzetmeghatározás Az érzékelők együttes használata a Motion API segítségével Az előzőekben leírt érzékelők hasznos információkkal szolgálnak a telefon helyzetét illetően. pontosabban forgatni tengelyei körül úgy. de mindegyik csak egy-egy aspektusban tudja vizsgálni azt. <Grid x:Name="ContentPanel" Grid. Ráadásul a Motion API használata teljesen megegyezik a korábban látott programozási interfészekével. A Start és a Stop metódusainak meghívása között dobja fel a CurrentValueChanged eseményt. mely a helyzetérzékelők adatait felhasználva könnyen kezelhető. ahogy a telefon forog: <phone:PhoneApplicationPage x:Class="MotionApiHandling.. A Pitch a telefon X-tengelye. Emellett megkapjuk a „nyers” adatokat is. tehát ha korábban már kezeltük a gyorsulásmérőt vagy társait. Loaded="PhoneApplicationPage_Loaded"> . Ennek statikus IsSupported tulajdonságából tudhatjuk meg.12. amire szükségünk van a helyzetmeghatározáshoz. melynek SensorReading tulajdonsága a következő tulajdonságokat tartalmazza: 7-3 táblázat: A MotionReading osztály tulajdonságai Tulajdonság Attitude DeviceAcceleration DeviceRotationRate Gravity Timestamp Típus AttitudeReading Vector3 Vector3 Vector3 DateTimeOffset Szolgáltatott információ Az eszköz helyzetét adja meg. melynek három fontos tulajdonsága a Pitch. A gravitáció iránya.0.5-ben beépített egy magasabb réteget is a helyzetérzékelők programozási felülete (vagyis az Accelerometer. tehát egyetlen objektumon keresztül elérhetünk mindent. minden ismerős lesz. hanem a Motion API-n keresztül egyetlen tulajdonságból kiolvasható ez az adat. Az előző érzékelő-esemény óta eltelt idő. Ezek segítségével mindenféle további számítás nélkül megkapjuk a telefon helyzetét a Földhöz képest. radiánban mérve.Row="1" Margin="12.

0.Row="1" <Image Name="img" Source="arrow. A másik két tengelyen való elforgatás ennél kicsit trükkösebb. iratkozzunk fel CurrentValueChanged eseményére.IsSupported) { m = new Motion() { TimeBetweenUpdates = new TimeSpan(0.Xna. A Silverlight nem támogatja a tényleges háromdimenziós forgatást. m.Projection> </Image> </Grid> Margin="12. :'("). az Y-tengelyen vett elforgatás pedig a Roll. és indítsuk el a figyelést! public partial class MainPage : PhoneApplicationPage { Motion m = null.RenderTransform> <RotateTransform x:Name="rt" </Image.CurrentValueChanged += m_CurrentValueChanged. SensorReadingEventArgs<MotionReading> e) { } } A CurrentValueChanged esemény kezelőmetódusában pedig – a megszokott módon.7.0.Devices. m. Ellenben a vizuális elemek Projection tulajdonsága segítségével lehetőségünk van az objektumok virtuális.Projection> <PlaneProjection x:Name="pp" </Image. } else MessageBox. using Microsoft.0"> Height="550"> /> /> A XAML rész kész.Framework dll-ekre! A mögöttes kódban emeljük is be a két. További telefonos funkciók használata A telefon megdöntését (amelyet a Yaw tulajdonsággal állítunk be) egy egyszerű RotateTransform segítségével kezelhetjük. 50) }. és a Loaded eseménykezelőben.Framework.RenderTransform> <Image. adjunk hozzá a projekthez egy referenciát a Microsoft.Devices. példányosítsuk az objektumot.Show("Motion API not supported. 184 . ha elérhető a Motion API. A vízszintes. public MainPage() { InitializeComponent().png" <Image.Start(). a Dispatcher segítségével – a PlaneProjection és a RotateTransform megfelelő értékeit adjuk meg.Sensors és a Microsoft. Adjunk hozzá a MainPage-hez egy Motion referenciát. } private void PhoneApplicationPage_Loaded(object sender. ezt a RotateTransformmal állítjuk be. ezekkel azonos nevű névteret a usingok közé! using Microsoft. X-tengelyen vett elforgatás a Pitch. hiszen a képet itt háromdimenziós objektumként kellene kezelnünk. A felhasználó felé néző Z-tengelyen vett elforgatást a Yaw adja meg. RoutedEventArgs e) { if (Motion. Ezeket rendre a PlaneProjection RotationX és RotationY értékéhez rendeljük hozzá.Xna. térbelinek tűnő elforgatására. Helyezzünk el egy RotateTransformot és egy PlaneProjectiont az Image-ben! <Grid x:Name="ContentPanel" Grid. 0.12. } void m_CurrentValueChanged(object sender. 0.Sensors.

amire fel tudjuk tölteni az alkalmazást.Attitude. és az A-GPS-t a cellainformációkkal és ismert wifik alapján történő lokalizálással egyesítő GeoLocation API használatát a GeoLocationWatcher osztályon keresztül. de fokban kell megadni a PlaneProjection és a RotateTransform számára. A telefonra ható erőket – így a gravitációt is – mérő gyorsulásmérő. 185 . és fokokban véve adja vissza.ToDegrees(e.ToDegrees(e. } Ha van fizikai eszközünk.SensorReading. rt.RotationY = MathHelper. ez egy radiánban vett értéket fogad.5-ben megjelent Motion API révén pedig mindenezeket a nyers adatokat akkumulálva.SensorReading. Ezután áttekintettük a telefon helyének megállapítását lehetővé tevő.BeginInvoke(() => { pp. ha felhasználjuk a Microsoft. akkor indulhat a tesztelés.FrameReported eseményig.Pitch). valamint a mágneses erők irányát megadó magnetométer minden telefon alapfelszereltsége.Framework névtérben található MathHelper osztályt.Attitude.Yaw). Konkrétan a ToDegrees metódusra lesz szükségünk. pp. helyzetmeghatározó érzékelők és programozási felületek állnak rendelkezésünkre. }). melynek statikus tagjai az ilyen és ehhez hasonló mindennapi transzformációk elvégzését könnyítik meg. Végül pedig számba vettük. SensorReadingEventArgs<MotionReading> e) { Dispatcher. Ezeknek az eszközöknek a kezelése nagyon hasonló. Összefoglalás Ebben a fejezetben megismerkedhettünk a Windows Phone 7-nel szerelt eszközökbe kötelezően vagy opcionálisan beépített érzékelők használatával.Attitude.Összefoglalás Mivel az értékeket radiánban kapjuk.RotationX = MathHelper.Angle = MathHelper. hogy milyen egyéb. mellyel hozzáférünk a kijelző által szolgáltatott nyers adatokhoz.Roll). Az emulátor sajnos egyelőre nem támogatja a Motion API-t.Xna. A Windows Phone 7. a telefon forgását mérő giroszkóp már opcionálisan beépíthető komponens. Először az érintőképernyő eseményeinek három rétegét tekintettük át a magas szintű Tap és társaitól a többérintéses kezelést lehetővé tevő Manipulation eseményeken keresztül a legalsó szinten lévő Touch. át kell alakítanunk őket.SensorReading. void m_CurrentValueChanged(object sender.ToDegrees(e. releváns információk formájában nyerhetjük ki az operációs rendszerből. Erre a legegyszerűbb módszer.

.

Relation Data: Relációs adatokat tárolhatunk egy lokális adatbázisban (SQL Server Compact Edition). ha tényleg szükséges! A fájlkezelés legyen transzparens a felhasználók számára! Ha átmeneti (Temp) fájlokat készítünk. vagyis itt egy alkalmazás korlátlanul gazdálkodhat a tárhellyel. ahogy csak szeretné. Ahogy a neve is mutatja. Leginkább az alkalmazásunk beállításainak mentésére használjuk. ahol az alkalmazásunk képes írni. A fejezetben kitérünk a következő témakörökre:      IsolatedStorage megismerése ApplicationSettings használata Hogyan olvassunk és írjunk fájlokat IsolatedStorage Tool-ok megismerése Lokális adatbázisok használata Isolated Storage A Windows Phone 7-nél nem beszélhetünk klasszikus értelemben a fájlkezelésről: ha I/O műveleteket szeretnénk elvégezni a fájlrendszeren. amit relációs adatbázisban tárolunk. akkor lehetőleg azonnal töröljük azokat. akkor csak az Isolated Storage áll a rendelkezésünkre. legyen szó egyszerű beállításokról vagy összetett adatokról. Bár nincs méretkorlát az alkalmazások készítői számára. Files and Folders: Fájlokat és mappákat kezelhetünk a segítségével (IsolatedStorageFile). mindössze annyi a különbség. hogy itt nincs megszabva kvóta. amint már nem használjuk. és nincs is többé szükség rájuk! Bizonyos esetekben célszerű ezeket a fájlokat szinkronizálni vagy archiválni a felhőbe (Cloud). csak és kizárólag az alkalmazásunk által használt Isolated Storage-ünket. vagyis az alkalmazások nem férhetnek hozzá egymás tárhelyéhez. így más alkalmazások semmilyen módon nem befolyásolhatják az alkalmazásunk működését. hogyan kezeljünk adatokat a Windows Phone 7 készülékünkön. olvasni. Adatkezelés Minden nagyobb alkalmazásnál eljön az az idő. a felhasználó adatai még megmaradnak. mint a Silverlightnál.8. Settings: Kulcs/érték adatokat tárolhatunk benne (IsolatedStorageSettings). akkor a megszokott környezetével találkozhat. valamint az általános fájlműveleteket is el tudja végezni. amiket a Linq To SQL technológiával érhetünk el. Ebben a fejezetben megismerkedhetünk azzal. néhány szempontot célszerű szem előtt tartani:     Csak akkor használjuk a fájlrendszert. így ha az alkalmazás törlésre kerül. Minden alkalmazás csak a saját Isolated Storage-ében tud garázdálkodni.1 verziója óta háromféle adatkezelési módszer létezik a készüléken (8-1 ábra):    187 . illetve ha a felhasználó másik kliensen jelentkezik be. Közvetlen módon tehát nem érhetjük el a teljes fájlrendszert. ott viszont úgy. A Windows Phone SDK 7. A Windows Phone 7 Isolated Storage megoldása nagyon hasonló a Silverlightos Isolated Storage megoldásához. Minden alkalmazás kérhet magának egy-egy ilyen elkülönített tárhelyet. ez egy tárhely (Storage). amikor tárolni kell adatokat a készüléken. ezzel növelve a biztonságot és a fájlkárosodás elkerülését.

hogy egy lokális adatbázisban relációs módon tároljunk adatokat.IO.IsoltedStorage) Fájlok és Mappák DataConentext (System. amely megvalósítja az IEnumerable<T> interfészt. amit egy normál gyűjteményen is. tehát minden olyan műveletet elvégezhetünk rajta. meg tudnám osztani valamilyen módon az IsolatedStorage-ot? Válasz: Nem. Ha később újra elindítja az alkalmazást. egyszerűbb eset egy kulcs/érték pár tárolási módszer. akkor a mobilon a munkát egyszerűbbé tehetjük számára azzal. akkor az ApplicationSettings kulcs/érték pár tárolási módszer a legcélravezetőbb megoldás. amint azt a 8-2 ábra is illusztrálja. 7.8. Kérdés: Ha lenne két olyan WP7-es alkalmazás. Az ApplicationSettings tulajdonképpen egy szótár. ami ugyanazt a fájl alapú adatforrást használja.IsoltedStorage) Isolated Storage Kulcs/érték Párok IsolatedStorageFile (System. Ebben az esetben például egy webszolgáltatáson keresztül oldhatjuk meg a fájlok közös használatát. az Application Settings-et fogjuk megismerni. de a Mango frissítéstől kezdve arra is van lehetőségünk. Például: ha egy felhasználónak egy szolgáltatás bejelentkezéséhez egy szövegdobozba kell beírnia a felhasználói nevét. Ebben a részben az első módszert.0 változatában csak a Settings és a Files and Folders adatkezelési módszer állt a rendelkezésünkre. a háttérben eltároljuk ezt a felhasználónevet. 188 .Data. Application Settings A fájlrendszert kétféleképpen érhetjük el: az első.Linq) Lokális adatbázis 8-1 ábra: A Windows Phone 7 adatkezelési lehetőségei A Windows Phone első. ahol olvashatjuk és írhatjuk a fájl stream-et. Amikor csak egyszerű alkalmazás-beállításokat szeretnénk elmenteni vagy lekérdezni. amellyel adatokat kezelhetünk a Windows Phone készüléken.IO. akkor a korábban megadott és eltárolt felhasználónévvel automatikusan ki lesz töltve az adott szövegdoboz. hogy ha már egyszer beírta. A következő fejezetekben megismerkedünk az összes módszerrel. Adatkezelés Alkalmazás IsolatedStorageSettings (System. a második pedig a tradicionális fájlkezelés.

Az alábbi példában egy egyszerű stringet láthatunk: // Felhasználónév hozzáadása – Új kulcs létrehozása IsolatedStorageSettings. Az alábbi kódrészlet az IsolatedStorageSettings felépítését mutatja be: namespace System. Remove(string key). Ha már létezik a kulcs. Save().IsolatedStorage { public sealed class IsolatedStorageSettings : IDictionary<string. Ahhoz. IEnumerable { public static IsolatedStorageSettings ApplicationSettings { get. ebben az esetben az első paraméter egy kulcs. TryGetValue<T>(string key. } public int Count { get. "Attila").ArgumentException-t kaphatunk.Application Settings 8-2 ábra: Bővítő metódusok egész sora áll a rendelkezésünkre Az ApplicationSettings egy speciális Dictionary<TKey. } public ICollection Values { get. hogy az IsolatedStorage-et elérjük. a fájlművelethez pedig a System.IO névtérre lesz szükségünk. out T value). TValue> objektum. } public object this[string key] { get. set. a System. Clear(). ICollection<KeyValuePair<string. ICollection. } public ICollection Keys { get. így például egy indexer segítségével is hozzáadhatunk egy új kulcs/érték-párt (így tudjuk a már létező kulcsok értékét is módosítani).Add("UserName". Contains(string key). object>>. Egy új kulcs/érték párt többféle módon hozhatunk létre: egyszerűen az Add metódus meghívásával. IEnumerable<KeyValuePair<string. ezért a rá vonatkozó szabályok élnek. amely egy kulcs/érték párost tud tárolni. object>>. és ezeket az értékpárokat az adott alkalmazás IsolatedStorage-ébe menti el. } public public public public public public } } void void bool bool void bool Add(string key.. object value).ApplicationSettings.IO.IO. IDictionary. Az 189 . Mivel ez egy Dictionary. aminek egyedinek kell lennie. a második paraméter pedig egy tetszőleges objektum lehet.IsolatedStorage névtérre. akkor egy System. object>.

Az adott kulcsok értékét persze le is kérdezhetjük. out userValue).ApplicationSettings["UserNme"].Contains("UserName")) { //Létezik a UserName kulcs. akkor a tartalmát felülírja a meghatározott értékkel. Age = 32 }. akkor egy KeyNotFoundException-t fogunk kapni. ehhez is használhatunk két módszert: az egyik az itt bemutatott indexeres módszer: //Felhasználóné lekérdezése var userName = IsolatedStorageSettings. } } .Show(IsolatedStorageSettings. valóban létezik-e a kulcs. } else { //Nem létezik MessageBox. 190 . Ez is egy Boolean értékkel tér vissza: ha sikerült a kulcsot megtalálni és kiolvasni a tartalmát. if (IsolatedStorageSettings. ha a kulcs nem található meg a szótárban..ApplicationSettings. A TryGetValue nagyon hasonlít a TryParse metódusokra. a tartalmát és irassuk ki MessageBox. a Contains metódust használhatjuk fel. de természetesen komplex objektumokat is eltárolhatunk az ApplicationSettings-ben. Adatkezelés indexeres megoldásnál.Show("Nincs ilyen kulcs!"). Ez a metódus true értékkel tér vissza.ApplicationSettings["UserName"] = "Attila".ApplicationSettings. akkor true-val. és azt tároljuk el. Person myPerson = new Person() { Name = "Jhon". ha már létezik a kulcs..ApplicationSettings["PersonData"] = myPerson.8.NET-es típusoknál használhatunk.ApplicationSettings["UserName"]. Olvassuk ki pl. amit a . A másik lehetőség a TryGetValue metódus használata: string userValue. // Felhasználónév mentése /vagy módosítása IsolatedStorageSettings. ha az adott kulcs nem létezik. nem kapunk hibát. akkor a userValue változó értéke üres (null) lesz. ha a kulcs nem létezik. A következő példában egy saját osztályt hozunk létre. Az Indexeres módszer esetén. Abban az esetben. IsolatedStorageSettings. false értékkel. Ebben az esetben nem kell törődnünk az adatsorosítással. } Az előző példákban csak egy egyszerű string adatot tároltunk el. //Adat mentése IsolatedStorageSettings. Ebben az esetben. ezt az ApplicationSettings saját maga megoldja. public class Person { public string Name { get. míg ha a TryGetValue metódust használjuk. set. ha létezik az adott kulcs. set. ha nem.TryGetValue<String>("Kulcs". majd olvassuk ki. } public int Age { get. abban az esetben.ToString()). akkor az létrejön. egyébként false-szal. ha meg akarunk győződni arról.

viszont sokszor fordul elő. és az alkalmazás leáll. Ha az összes értéket el akarjuk távolítani. string myValue = settings["Kulcs"]. melynek folyamatos kiírása fáradságos lehet.ApplicationSettings.Application Settings // Adat lekérdezése Person newPerson = IsolatedStorageSettings. settings["Kulcs"] = "Érték". Mivel az ApplicationSettings egy szótár. Az előző rövid példákban látható volt. hogy jó volna ezt centralizálni.ApplicationSettings["PersonData"] as Person. amely a paraméterében átadott kulcs értékét adja vissza. MessageBox. Egy dolgot azonban még tisztáznunk kell.Name). hogy az IsolatedStorage használata mennyire egyszerű.Show(newPerson. ez pedig az adatkötés technikája! Az előzőekben csak explicit módon mentettünk el és olvastunk ki adatokat. ezért mind a kulcsokon. Ha az adott kulcs nem található meg a szótárban. private const string PersonKey = "Person". Ez az osztály egy általánosan használható RetriveSettings segédmetódust tartalmaz.Remove("UserName").Save().ApplicationSettings.ApplicationSettings. A mentett adatokat persze el is távolíthatjuk az ApplicationSettings-ből.Keys) { // Feldolgozás } foreach (var value in IsolatedStorageSettings. akkor ki kell kényszerítenünk a mentést az ApplicationSettings Save metódusával. viszont ha az alkalmazás futása közben nem várt hiba történik. és az ApplicationSettings elérését egyszerűsíteni és ésszerűsíteni.Values) { // Feldolgozás } Egy alkalmazásnál sokszor használhatjuk az ApplicationSettings-et. A következő példában egy Settings osztályt hozunk létre.Clear(). mind az értékeken végig tudunk haladni a foreach utasítással: foreach (var key in IsolatedStorageSettings. amiben általános és/vagy ellenőrző módon tudjuk elérni az általunk használt kulcs/érték párokat. Ha biztosra szeretnénk menni. public class Settings { private const string ApplicationTitleKey = "ApplicationTitle".ApplicationSettings. ezek az információk nem kerülnek elmentésre. IsolatedStorageSettings. Az ApplicationSettings az alkalmazás bezárásakor elmenti az adatokat.ApplicationSettings. akkor az adott típus alapértelmezett értékével (ebben az esetben ez null) tér vissza. Eltávolíthatunk egy kulcsot. 191 .ApplicationSettings. ezért ezt egyszerűbben az alábbi módon is megoldhatjuk – így több billentyű leütését is megspórolhatjuk: var settings = IsolatedStorageSettings.ToString(). akkor a Clear metódust kell meghívnunk: IsolatedStorageSettings. ilyenkor a Remove metódust kell használnunk: IsolatedStorageSettings.

TryGetValue(settingKey.Resources> Miután az App. hogy a Settings osztály miért nem lett static? Így sokkal egyszerűbb lenne elérni a tulajdonságok értékét. xmlns:local="clr-namespace:PhoneAppTest" > <Application. nyissuk meg az egyik oldalt (jelen esetben a MainPage. Mostantól tehát minden kulcsnak külön tulajdonságot fogunk készíteni. } } } Az osztályban minden kulcsnak különálló tulajdonságot készítünk. Adatkezelés private T RetriveSettings<T>(string settingKey) { object settingValue. mint mindig példányosítani egy Settings-et! A válasz egyszerű: célravezetőbb ezt az osztályt az App.ApplicationSettings[PersonKey] = value. és a PhoneApplicationPage DataContext-jének adjuk át a MySettings-et az alábbi módon! 192 . out settingValue)) { return (T)settingValue. } } public Person MyPerson { get { return RetriveSettings<Person>(PersonKey). } set { IsolatedStorageSettings.. és erre ezt követően az alkalmazásunkban bárhol hivatkozhatunk kódból és XAML-ből egyaránt: .Resources> <local:Settings x:Key="MySettings" /> </Application.xaml fájlban deklaratív módon példányosítani. } set { IsolatedStorageSettings.xaml-ben elkészítettük a példányt. } public string ApplicationTitle { get { return RetriveSettings<string>(ApplicationTitleKey)..ApplicationSettings[ApplicationTitleKey] = value. így könnyebb az alkalmazásunkban ezeket a beállításokat írni és olvasni. if (IsolatedStorageSettings. így a Settings osztályon keresztül az összes kulcsértéket el tudjuk érni.8.xaml). Felmerülhet bennünk a kérdés. így csak az alkalmazás indulásakor egyszer készítünk egy Settings példányt.ApplicationSettings. ráadásul elkerüljük a szöveges értékű kulcsok elírását is. } return default(T).

IsVisible="True" DataContext="{StaticResource MySettings}"> Ezt követően az oldalra helyezzünk el egy TextBox-ot.0.-7. <TextBox Text="{Binding ApplicationTitle. SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray. és a szövegdobozba beírunk valamit. amint azt a 8-3 ábrán láthatjuk. hogy az oldal címe és a szövegdoboz tartalma az ApplicationSettings-ből kiolvasott érték lesz. majd kattintsunk a Start gombra az emulátoron. Ehhez készítsük el a felhasználói felületet. Ebben az esetben a Binding módja TwoWay. és a Text tulajdonságát kössük az ApplicationTitle-höz. és láthatjuk. az a háttérben tárolásra fog kerülni. ekkor az alkalmazás háttérbe vonul! Az emulátoron újra indítsuk el az alkalmazást.0.MainPage" .0" Name="textBox1" VerticalAlignment="Top" Width="460" /> A PageTitle Textblock Text tulajdonságához is kössük az ApplicationTitle-t: <TextBlock x:Name="PageTitle" Text="{Binding ApplicationTitle}" Margin="9. Mode=TwoWay}" Height="72" HorizontalAlignment="Left" Margin="6. Írjunk oda egy tetszőleges szöveget. azaz a kötés kétirányú..Application Settings <phone:PhoneApplicationPage x:Class="PhoneAppTest. 8-3 ábra: Application Settings demó alkalmazás Gyakorló feladat: A Settings osztályban van egy MyPerson tulajdonság is.. és mentsük el az értékét! 193 .6.0" Style="{StaticResource PhoneTextTitle1Style}"/> Ha elindítjuk az alkalmazást (6-3 ábra).

A már foglalt terület nagysága. isf)) { StreamWriter sw = new StreamWriter(myFileStream). hogy egy új fájlt létrehozzunk. sw.WriteLine("Hello World"). Ennek az osztálynak a példányosításakor kell meghatároznunk a fájl nevét. valamint egy StreamReader példányt használunk az olvasáshoz. Az alábbi táblázatban az IsolatedStorageFile fontosabb metódusait találjuk: Metódus CopyFile(String. Boolean) CreateDirectory Leírás Egy létező fájl másolása. Ahhoz. Ebben az egyszerű példában egy fájlt hozunk létre. hogy az IsolatedStorage engedélyezve van-e. és hagyományos fájlok elérésére volna szükségünk a fájlrendszeren. olykor ez kevés lehet a számunkra. hogy a FileMode ebben az esetben az Open értékét viseli. IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication(). majd a StreamWriter példány WriteLine metódusával írhatunk egy sort a fájlba. string text = sr. isf)) { StreamReader sr = new StreamReader(myFileStream). FileMode. Egy létező fájl másolása. Mappa készítése 194 . sw. az IsolatedStorageFileStream osztályra lesz szükségünk.txt". String) CopyFile(String. Adatkezelés IsolatedStorageFileStream Bár könnyű kulcs értékeket tárolni.txt". ez ebben az esetben egy IsolatedStorageFileStream. A maximálisan felhasználható szabad terület mérete. mely a „Hello World” szöveget tartalmazza: IsolatedStorageFile isf = IsolatedStorageFile. Lekérdezhetjük. sw.8. Ennek át kell adnunk egy Stream-et.Flush(). String. A fájlba egy StreamWriter példány segítségével írhatunk. Ha a cél útvonalon létezik a fájl. A fájlból olvasás hasonlóan egyszerű.Show(text). akkor opcionálisan felülírhatjuk. FileMode. MessageBox. using (IsolatedStorageFileStream myFileStream = new IsolatedStorageFileStream("data. } Az alábbi táblázatban az IsolatedStorageFile tulajdonságait foglaljuk össze: Tulajdonság AvailableFreeSpace IsEnabled Quota UsedSize Leírás Az IsolatedStorage-ben rendelkezésre álló szabad terület mérete. és annak elérési módját (FileMode enumeráció). } A GetUserStoreForApplication metódus egy IsolatedStorageFile példányt ad vissza.ReadToEnd(). Ebben a részben a tradicionális. annyi a különbség.Open.GetUserStoreForApplication().Create. stream-alapú fájlkezelést fogjuk közelebbről megismerni.Close(). valamint át kell adnunk egy IsolatedStorage példányt is. using (IsolatedStorageFileStream myFileStream = new IsolatedStorageFileStream("data.

és hozzáféréssel.CreateDirectory("UjKonvtar").IsolatedStorageFileStream Metódus CreateFile DeleteDirectory DeleteFile DirectoryExist FileExist GetCreationTime GetDirectoryNames() GetDirectoryNames(String) GetFileNames() GetFileNames(String) GetLastAccessTime Leírás Új fájl készítése Mappa törlése Fájl törlése Megvizsgálhatjuk. Mappa (és tartalmának) áthelyezése egy új útvonalra Fájl mozgatása egy új helyre. FileMode. hogy az adott fájl létezik-e. Visszaadja a fájl vagy mappa készítési idejét. Fájl megnyitása egy meghatározott módon Fájl megnyitása egy meghatározott módon. Egy könyvtár törlése is legalább ilyen egyszerű. Visszaadja. A felhasználóhoz tartozó izolált tárhelyet kezelő IsolatedStorageFile példányt kérhetünk a segítségével. FileMode) OpenFile(String.GetUserStoreForApplication(). Megadhatunk összetett könyvtár útvonalat is: myISF. ahol a metódusnak a könyvtár nevét adjuk át: IsolatedStorageFile myISF = IsolatedStorageFile. myISF. opcionálisan a fájl nevét is megváltoztathatjuk. hogy az adott mappa létezik-e. Visszaadja a fájlok neveit (Gyökérkönyvtárból kiindulva). Az IsolatedStorage és tartalmának eltávolítása GetUserStoreForApplication MoveDirectory MoveFile OpenFile(String. Megvizsgálhatjuk. Visszaadja a fájlok neveit egy meghatározott minta alapján. Visszaadja a mappák neveit (Gyökérkönyvtárból kiindulva).CreateDirectory("Folder1/Folder2/Folder3/UjKonvtar"). hogy a fájlhoz vagy mappához mikor fértek hozzá utoljára. hogy az adott könyvtár létezik-e: 195 . Visszaadja a mappák neveit egy meghatározott minta alapján.DeleteDirectory("UjKonvtar"). ehhez a DeleteDirectory metódust használhatjuk fel: myISF. FileAccess) Remove Nézzünk néhány gyakori felhasználási esetet! Könyvtár létrehozáshoz a CreateDirectory metódust használhatjuk fel. mind a könyvtár törlésekor célszerű ellenőrizni. Mind a könyvtár létrehozásakor.

IsNullOrEmpty(directoryName_in) && !myIsolatedStorage.GetUserStoreForApplication(). } } catch (Exception ex) { // Kivétel } } public void DeleteDirectory(string directoryName_in){ try { IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.DirectoryExists(directoryName_in)) myIsolatedStorage. Adatkezelés public void CreateDirectory(string directoryName_in) { try { IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile. Ráadásul. Gyakorlottaknak és kezdőknek egyaránt könnyen és hatékonyan használható API áll a rendelkezésére.IsNullOrEmpty(directoryName_in) && myIsolatedStorage. hogy a Windows Phone 7 alatt a fájlkezelés rendkívül egyszerű és gyorsan elsajátítható. } } catch (Exception ex) { // Kivétel } } { Láthatjuk. azok számára ez sok újdonságot nem is rejteget.GetUserStoreForApplication(). if(!string. if (!string. Isolated Storage gyakorlat A következő gyakorlatban egyszerű jegyzetelő alkalmazást fogunk elkészíteni (8-4 ábra). akik korábban Silverlight alatt használták ezt a funkciót.DirectoryExists(directoryName_in)) { myIsolatedStorage.8.DeleteDirectory(directoryName_in). Az alkalmazás felhasználói felülete előre el van készítve.hu/wp7. A projekt kiindulási anyagát a következő oldalról tölthetjük le: http://devportal. 8-4 Az elkészített jegyzetelő alkalmazás 196 .CreateDirectory(directoryName_in).

és .Text). Nyissuk meg az IsolatedStorageDemo. c.xaml.dat lesz a kiterjesztésük.cs fájlt. Fordítsuk le. és térjünk vissza a projekthez! Nyissuk meg az App. Nyissuk meg a MainPage. itt fogjuk a jegyzeteink számára elkészíteni a „Notes” mappát. Itt az ideje ezeket a funkciókat megvalósítani! Zárjuk be a futó alkalmazást. Ha nem létezik (pl. using (IsolatedStorageFileStream myFs = new IsolatedStorageFileStream(path.) using System.Text + ".dat". Ehhez az IsolatedStorageFile példány GetFileNames metódusát fogjuk segítségül hívni az alábbi módon: IsolatedStorageFile isf = IsolatedStorageFile. sem betölteni jegyzeteinket.DirectoryExists("Notes")) { isf. így a mySw példány WriteLine metódus paraméterének átadjuk a txtDocument. e.xaml. IsolatedStorageFile myISFile = IsolatedStorageFile. Nyissuk meg a Pages/SavedItems. if (!isf.GetUserStoreForApplication(). és indítsuk el az alkalmazást! Egyszerű jegyzetelő felületet kapunk.ItemsSource = isf. és oldjuk fel a System. hogy a Notes mappa létezik-e.IsolatedStorage.IO. Ha minden sikeresen lezajlott.IO és a System.Flush().IO. Ezt követően létrehozunk egy IsolatedStorageFileStream-et. 197 . mySw. az alábbi lépésekben: a. } d.dat"). f. de jelenleg még nem tudjuk sem elmenteni. lstMyNotes. és el is tudjuk menteni a jegyzeteinket. hogy a korábban elmentett jegyzeteinket vissza tudjuk tölteni.WriteLine(txtDocument. Itt az ideje megírni azt is. akkor a CreateDirectory metódussal létrehozzuk: IsolatedStorageFile isf = IsolatedStorageFile.GetFileNames("Notes\\*.Text tulajdonságának értékét.IsolatedStorageFileStream A gyakorlatban csak az adattárolással kapcsolatos kódokat fogjuk közösen megírni.Show("A jegyzetedet elmentettük!".OK).xaml. MessageBoxButton. b.xaml.cs-ben navigáljunk el a btnSave_Click eseményhez. ugyanis itt fogjuk elmenteni a jegyzetünket a fájlrendszerbe.IsolatedStorage névteret! (A feladatban a többi lapjához már hozzáadtuk ezeket a névtereket.GetUserStoreForApplication().. myISFile)) { using (StreamWriter mySw = new StreamWriter(myFs)) { mySw. Az alkalmazás minden indulásakor megvizsgáljuk a DirectoryExist metódussal.CreateDirectory("Notes").sln fájlt (Begin mappa)! Ha valamit a gyakorlat lépései során nem sikerülne pontosan követnünk. akkor egy MessageBox-ban ezt megüzenjük a felhasználónak.cs fájlt.cs fájlt.GetUserStoreForApplication(). } } MessageBox. hogy jelenleg milyen jegyzeteink vannak mentve. string path = "Notes\\" + txtTitle. Először a path változóban létrehozunk egy útvonalat a jegyzeteink számára: azok a Notes mappába fognak kerülni. és navigáljunk el az Application_Startup eseményhez. első indulás). és navigáljunk el a SavedItems konstruktorába: itt fogjuk kiolvasni a fájlrendszerről. using System. Ezt legegyszerűbben a StreamWriter-rel tudjuk írni. Most már elkészítettük az alkalmazásunk jegyzet (Notes) mappáját. FileMode. A MainPage. az End mappában megtalálható és kipróbálható az alkalmazás végleges formája. "Isolated Storage Demo".Create.IO. FileAccess.Write.

out fileName)) { IsolatedStorageFile isf = IsolatedStorageFile. Térjünk vissza a MainPage. Navigáljunk el a lstMyNotes_SelectionChanged eseményhez. if (selectedItem != null) { NavigationService. A NavigationContext.xaml?OpenFile="+selectedItem. itt azonban az IsolatedStorageFileStream FileMode felsorolt típusából az Open értéket választjuk. UriKind. using (IsolatedStorageFileStream myFs = new IsolatedStorageFileStream("//Notes//" + fileName. ami majd megnyitja az adott jegyzetet. Fordítsuk le a forráskódot (Ctrl+Shift+B).8.Open. if (NavigationContext.GetUserStoreForApplication().TryGetValue("OpenFile". ezt adjuk át a lstMyNotes listának. A StreamReader ReadToEnd metódusának segítségével a fájl teljes tartalmát kiolvassuk.Text = sr. } Itt egyszerűen a kiválasztott fájl nevét átadjuk a MainPage-nek.Text = fileName. nézzük át újra a kódot és javítsuk azt! Ha minden rendben lezajlott. ha átadtuk ezt a paramétert.ReadToEnd(). FileMode. A fájl olvasása a fájlírás analógiájára történik.QueryString. txtDocument.Replace(".TryGetValue metódusával megpróbáljuk elérni az OpenFile paraméter értékét. h. és StreamWriter helyett StreamReader-t használunk.cs –hez. most pedig megírjuk azt az egyszerű funkciót.xaml. 198 . hogy elegánsabban jelenjen meg a fejléc: string fileName = string.QueryString. isf)) { using (StreamReader sr = new StreamReader(myFs)) { txtTitle. és a metódus törzsébe írjuk a következőt: string selectedItem = lstMyNotes. akkor indítsuk el az alkalmazásunkat (F5)! Az megjelenik kezdőképernyőjén a jegyzeteink listájával. amivel a kiválasztott fájlt átadjuk a MainPage-nek. Ezzel elkészült az alkalmazásunk. és navigáljunk el az OnNavigatedTo eseményhez. amint azt a 8-5 ábra mutatja. és itt létrehozunk egy fileName nev string változót.dat kiterjesztést. ezt követően átadjuk a txtDocument-nek. akkor azt le is kell kérdeznünk.Empty. ""). Az előző pontnál megjelenítettük a jegyzeteink fájljait egy listában. A txtTitle esetén a fileName szövegből eltüntetjük a .Relative)). } } } i.SelectedItem as string. méghozzá a QueryString átadási mintát követve. és ha valamilyen hibát tapasztalunk.dat". g. és az átadott értéknek megfelelően megnyitni az adott fájlt. Adatkezelés A GetFileNames visszatérési értéke egy String tömb.Navigate(new Uri("/MainPage. Természetesen.

Itt az IsolatedStorageSettings. akkor sem jelez hibát. majd visszanavigálunk a MainPage oldalra. Ha már kiválasztottunk egy színt. 199 . de a TryGetValue egyik nagy előnye az. Nyissuk meg a Pages/Settings. Természetesen a MainPage –nél is alkalmaznunk kell a kiválasztott színt: nyissuk meg a MainPage. l. UriKind.Relative)). k. és el is van tárolva.xaml. a változó pedig az alapértelmezett értékét kapja (ebben az esetben a 0-t. akkor azt a következő Settings page-re navigáláskor jelenítsük meg a felhasználó számára! Navigáljunk el a Settings konstruktorához.cs fájlt. j.TryGetValue<int>("Foreground". ami kötés után a fekete színt reprezentálja).ApplicationSettings["Foreground"] = selectedItem. és navigáljunk el az lpForeground_SelectionChanged metódushoz. Itt az IsolatedStorageSettings. out currentIndex). m. NavigationService. majd kattintsunk a mentés gombra! Készítsünk egy új jegyzetet (+).Navigate(new Uri("/MainPage. Zárjuk be az alkalmazást. out foregroundColorIndex). hogy a jegyzetek betűszíne milyen legyen. és térjünk vissza a Visual Studio-hoz! A fájlkezeléshez hozzátartozik a beállítások kezelése is. akkor eddig a feladatot helyesen oldottuk meg.ApplicationSettings Foreground kulcsához hozzáadjuk a kiválasztott szín kulcsának értékét.IsolatedStorageFileStream 8-5 ábra: Jegyzetek megnyitása Az alkalmazás betöltése után írjunk egy jegyzetet. hogy ha az adott kulcs (esetünkben Foreground) még nem létezik.ApplicationSettings.ApplicationSettings.Key.TryGetValue<int>("Foreground". ezt követően kattintsunk a megnyitás gombra! A megjelenő ablakban a jegyzeteink lesznek láthatók. Használhatnánk az indexeres formát is.cs fájlt. majd a feltételbe írjuk a következő kódsorokat: IsolatedStorageSettings.xaml".TryGetValue metódusát használjuk.ApplicationSettings. és a következő pillanatban már a főképernyőn láthatjuk a jegyzetünk tartalmát! Ha ezeket a lépéseket sikerült elvégeznünk. melynek segítségével a felhasználó meghatározhatja. Válasszunk ki egy jegyzetet. és töltsük be a használt szín indexét: IsolatedStorageSettings. A következőkben a jegyzetelő alkalmazásunkat kiegészítjük egy olyan beállítással is. és navigáljunk el az OnNavigatedTo eseményhez! Írjuk hozzá a következő kódsort: IsolatedStorageSettings.xaml.

Fordítsuk le a forráskódot (Ctrl+Shift+B). hogy azok az általunk meghatározott útvonalon jöttek-e létre. 8-6 ábra: Színválasztó lap Ezen a gyakorlaton keresztül is láthattuk. törölhetünk és minden alapvető fájlműveletet elvégezhetünk a segítségével. hogy az alkalmazás használata során milyen fájlok keletkeztek. A jegyzet megnyitásánál jelenítsük meg valamilyen formában a jegyzet készítésének dátumát! 3. Például: kilistázhatjuk a mappák tartalmát.8. mint a Settings page-nél. majd alkalmazzuk a szövegdobozon. és javítsuk azt! Ha minden rendben lezajlott. ahol sok a fájlművelet. Ez egy parancssori eszköz. akkor indítsuk el az alkalmazásunkat (F5)! o. nézzük át újra a kódot. ahol láthatjuk. hogy a fájlkezelés rendkívül egyszerű a Windows Phone –on. Készítsük el az alkalmazást úgy. hogy mit és hogyan. Immár kész a teljes alkalmazás. de ebből a kontextusból nem tud kibújni. A könnyebb használat érdekében a Mango frissítés fejesztőkészletének része lett az Isolated Storage Explorer Tool (ISETool. Az Isolated Storage Explorer használatához a következő szintaxist lehet használnunk: ISETool. hasznos lenne látni.1\Tools\IsolatedStorageExplorerTool útvonal alatt találgató. Adatkezelés Csakúgy. a minél leleményesebb megoldása a lényeg.exe <ts|rs|dir[:device-folder]> <xd|de> <Product GUID> [<desktop-path>] 200 . Önálló feladatok Fejlesszük tovább a jegyzetelő alkalmazást! Nincs megkötés arra. Ezt a Toolt a $Program Files\Microsoft SDKs\Windows Phone\v7. 1. hogy a jegyzetünk betűszíne megegyezik az általunk kiválasztott színnel. másolhatunk. vagy vigyünk fel új menüpontokat! Rajtunk múlik a feladat. ahol fájlműveleteket végezhet. n. Minden alkalmazás rendelkezhet IsolatedStorage-dzsal. Tegyük megváltoztathatóvá jegyzetünk betűtípusát! IsolatedStorage – Tool Azoknál az alkalmazásoknál. és hogy tartalmuk helyes-e. Készítsünk egy jegyzetet. legyünk kreatívak! Módosítsuk szabadon a UI-t. itt is kiolvassuk a foreground tulajdonságot. hogy tudjunk jegyzetet törölni! 2. amely segítségével műveleteket tudunk végezni a készülék vagy az emulátor Isolated Storage-án. majd mentsük el! Válasszuk ki a beállítások menüpontot.exe). és a megjelenő ablakban válasszunk ki egy nekünk tetsző színt (8-6 ábra)! Ha kiválasztottunk egy új színt. akkor az alkalmazás rögtön visszanavigál a MainPage oldalra. és ha valamilyen hibát tapasztalunk. Az Isolated Storage Explorer Tool-t csak a regisztrált fejlesztői készülékeken lehet használni.

az „xd” helyett „de” kapcsolót kell használnunk. 8-7 ábra: Mappák és fájlok listázása emulátoron 6. Ehhez mindösszesen a következő parancsot kell kiadnunk: ISETool.1\Tools\IsolatedStorageExplorerTool 5.xml fájlból: <App xmlns="" ProductID="{d25bf842-f28d-45ff-9a4d-6057e6614321}" Title="PhoneApp2" 3. Navigáljunk el a Windows Phone 7 SDK IsolatedStorageExplorer mappájába: $Program Files\Microsoft SDKs\Windows Phone\v7. Keressük ki a ProductID-t a WPAppManifest. Indítsuk el az alkalmazást az alábbi módon: ISETool.exe ts <xd|de> <Product GUID> <desktop-path>. ahová másolhatunk vagy írhatunk fájlokat az IsolatedStorage-ből.IsolatedStorage – Tool Parancs TS RS DIR Device-folder XD DE Product GUID Desktop-path Leírás Snapshot készítése Snapshot helyreállítása Mappák és fájlok listázása Mappa meghatározása Emulátoron történő használat Készüléken történő használat A termék ProductID-je (WPAppManifest.) Ne felejtsük el átírni a saját ProductID-nkat! Az eredményt a 8-7 ábrán láthatjuk. például (8-8 ábra): 201 .exe dir xd d25bf842-f28d-45ff-9a4d-6057e6614321 (Amennyiben fizikai készülékről szeretnénk lekérdezni ezeket az információkat. Nyissunk meg egy parancssort! 4. és a helyi gépünkön szabadon megvizsgálhatjuk azok tartalmát. Készítsünk egy egyszerű Windows Phone 7 alkalmazást! 2.xml) Egy könyvtár a számítógépünkön. Listázni már tudunk. Nézzük meg ezt az eszközt használat közben! 1. hogyan másolhatunk fájlokat a telefonról a fájlrendszerünkre! Ezzel a funkcióval lementhetjük az alkalmazásunk mappáját. nézzük meg.

amelyet a . azt –ugyanúgy. Ezt az adatbázist csak a Linq To SQL API segítségével érhetjük el.exe TS xd d25bf842-f28d-45ff-9a4d-6057e6614321 "D:\IsolatedStorage” 8-8 ábra: Fájlok lementése emulátorról Ezen a parancssori eszközön kívül természetesen vannak grafikus modulok is. Ahhoz. A Linq To SQL lehetőséget biztosít arra. Ilyen eszköz például az Isolated Storage Tool (8-9 ábra).8.0 –ás) változatában nem volt beépített lehetőség.com/fcd19b08-f8bc-4397-84bc-c10cd44ca673?SRC=VSIDE 8-9 ábra: A Visual Studióba beépülő Isolated Storage Tool Lokális adatbázisok használata Windows Phone 7-en Lokális relációs adatbázis készítésére és használatára a Windows Phone 7 első (7. és így objektumorientált módon kezelhetjük adatainkat. ORM (Object Relational Mapping) keretrendszer. Adatkezelés ISETool. és azokat lefuttassuk az adott adatbázismotoron. a Mango frissítéssel viszont az Isolated Storage-ben az alkalmazásunk elhelyezhet relációs adatbázist is. Az SQL Servernél megszokott Transact SQL segítségével közvetlenül nem érhetjük el az adatbázist. Ezt Microsoft SQL Server Compact Edition (CE) teszi lehetővé. Ezt a kiegészítőt a következő oldalról tölthetjük le: http://visualstudiogallery.microsoft. illetve lehetőséget biztosít arra is. mint az Isolated Storage esetén − nem oszthatjuk meg a többi alkalmazással! Linq To SQL A Linq To SQL egy ún. hogy ez működjön. az alkalmazásba beépülő módon működő relációs adatbázis-kezelő. amely egy fájl alapú. hogy kódunkban beágyazva fogalmazzunk meg lekérdezéseket. olyan eszköz is létezik. az 202 . hogy adatokat töltsünk le a telefonunkról (vagy emulátorunkról a számítógépünkre).msdn.NET Framework tartalmaz. hogy a gépünkről töltsünk fel adatokat a telefonon futó alkalmazásunk könyvtárába. amely a Visual Studio-ba épül be. amely szintén lehetőséget biztosít arra. sőt. Az adatbázist csak saját alkalmazásunk írhatja és olvashatja.

Ezt a két világot meg kell feleltetni egymásnak. ezek a tulajdonságok képzik az adatbázis oszlopait. Egyszerű POCO (Plain Old CLR Object) objektumokat és tulajdonságaikat speciális jelzésekkel – attribútumokkal – jelölhetünk meg. akkor automatikusan az osztály neve lesz adatbázis táblájának a neve. hogy ez az osztály tulajdonképpen az adatbázis egy táblájának reprezentációja lesz. A megfeleletésen kívül szükségünk lesz egy proxy objektumra is. amely az adatbázis tábláit reprezentálja. Minden Table objektum entitásokból épül fel. Ezt a megfeleltetést nevezzük mappingnek. amelyekben sorok és oszlopok találhatók. Az osztályt ellátjuk egy Table attribútummal. ami megvalósítja a kapcsolatot az adatbázissal és az egyéb specifikus funkciókat is elvégzi. akkor az adatbázisban található tábla neve az lesz. 8-10 ábra: Lokális adatbázisok DataContext A DataContext egy proxy objektum. amelynek két tulajdonsága van: a Name és az Age. hogy jelezzük. A Table attribútumnál egy Name tulajdonságot is megadhatunk. amely az adatbázist reprezentálja. Ha megadjuk. ugyanis az adatbázisoknál táblák vannak. hogy van egy ilyen osztályunk. Ezt a táblát a DataContext-ben egy User osztály reprezentálja. amelyek speciális attribútumokkal van ellátva. ezt DataContextnek nevezzük (8-10 ábra). Ha nem adunk meg nevet. Ennek megértéséhez képzeljük el az alábbi példát: Van egy Users táblánk. melynek van egy Name és egy Age oszlopa. amit megadtunk. hogy dolgozni tudjunk az adatokon.Lokális adatbázisok használata Windows Phone 7-en adatbázisok világát közelebb kell hoznunk az objektumorientált világhoz. Nézzünk egy példát. hogy az adott objektum milyen módon reprezentálja az adatbázist. azt speciális attribútumokkal kell ellátnunk az adatbázis speciális megkötéseinek. A DataContext Table típusú objektumokat tartalmaz. Mapping A mapping maga a megfeleltetés egy adattábla és az azt reprezentáló objektum között. ezzel jelezve. míg egy objektumorientált programban entitások és tulajdonságok vannak. Azon kívül. Minden entitás egy „Plain Old CLR Object” (azaz POCO). amelyek pedig a táblák oszlopait írják le. amelyben a Countries táblát a Country osztálynak feleltetjük meg! Az itt leírt Country osztály az alkalmazás futtatásánál egy Countries nevű táblát hoz létre az adatbázisban: [Table(Name="Countries")] public class Country { } Ebben a példában a Country nevű adatbázis táblához a megegyező nevű osztály tulajdonságait rendeljük: [Table] public class Country { } 203 . tulajdonságainak leírásához. Ezekkel az attribútumokkal definiáljuk. Az osztály tulajdonságait pedig a Column attribútummal látjuk el.

8. idegen kulcs  elsődleges kulcs kapcsolat). minden index egy vagy több oszlopot fedhet le. Nézzünk egy konkrét példát az adatbázis leképezésére! Létrehozzuk a Customer osztályt. } } A Column attribútumnál határozhatjuk meg azt is.Data. Ezek az osztályok lesznek felelősek a mappingért. hogy az adott érték lehet-e null: [Column(CanBeNull=true)] public string Name { get. ha az osztály el van látva a Table jelölővel. hogy ez az osztály a Customers táblához fog kapcsolódni. set. Adatkezelés A táblákat és az üzleti objektumainkat már egymáshoz rendeltük. Például ha szeretnénk létrehozni egy táblát az ügyfeleink nyilvántartására.Mapping. hogy készítünk egy egyszerű osztályt. } Az alábbi táblázat a rendelkezésre álló attribútumokat sorolja fel. Oszlopok megfeleltetésére szolgál. hogy létrehozzunk egy adatbázist. ennek megfelelően ezeket az objektumokat el kell látni a megfelelő attribútumokkal. Ebben meghatározzuk. adatbázis állítja-e elő az adott oszlop értékét (Például: AutoIncrement –es ID mező). IsDbGenerated=true)] public int ID { get. A Name tulajdonságával meghatározhatjuk.Linq névtérre. és képességeit írja le: Attribútum [Table] [Column] [Index(Columns="Column1.Data. OtherKey="TargetEntityID")] Leírás Táblák megfeleltetésére szolgál. Az adatbázist úgy tudjuk létrehozni. IsUnique=true. További indexek meghatározására szolgál. namespace PhoneDatabase { [Table(Name="Customers")] public class Customer { [Column(IsPrimaryKey=true)] 204 . és ellátjuk a megfelelő attribútumokkal. Adatbázis létrehozása Ahhoz. Name="MultiColumnIndex")] [Association(Storage="ThisEntityRefName". melyeket a Column attribútummal rendelünk az adatbázis oszlopaihoz.Column2 DESC". ThisKey="ThisEntityID". amelyet ellátunk egy Table attribútummal. A leképezéshez szükségünk lesz a System. Táblák közötti kapcsolat meghatározására szolgál (pl.Linq. using System. hogy az adott oszlop elsődleges kulcsú-e. amibe felveszünk néhány tulajdonságot. viszont a táblák oszlopait még nem rendeltük tulajdonságokhoz! Ehhez a Column attribútumot hívjuk segítségül! Csak akkor láthatjuk el a tulajdonságainkat ezzel az attribútummal. egy DataContext típust és legalább egy entitás osztályt létre kell hoznunk. Az osztályban elhelyezhetünk saját tulajdonságokat. ehhez létrehozunk egy Customer osztályt. hogy az adott nevű adattábla oszlop melyik tulajdonsághoz legyen rendelve: [Table] public class City { [Column(IsPrimaryKey=true.Mapping. set. A Column attribútumnál további lehetőségeink is vannak: meghatározhatjuk például.

és kész a DataContext is. Ahhoz.Linq névtérben található). vagy lekérdezéseket fogalmazzunk meg ezen a táblán. hogy létrehozzuk. 205 .sdf")) { if (!db. megszokottabb módszerre? De van! A következő részben ezzel fogunk megismerkedni. amely legyen Table<Customer> típusú! Ez reprezentálja a Customers táblában lévő adatokat.sdf. namespace PhoneDatabase { public class CustomerDataContext : DataContext { private Table<Customer> customers.CreateDatabase(). hogy az adott adatbázis létezik-e.sdf fájlra hivatkozunk. } } public CustomerDataContext(string connectionString) : base (connectionString) { customers = GetTable<Customer>(). de macerás munka ezt minden esetben manuálisan létrehozni. } } } A CustomerID tulajdonságot a tábla elsődleges kulcsaként jelöljük meg. Célszerű az adatbázis létrehozása előtt ellenőrizni. amelyet átadunk a DataContext konstruktorának: using System. DataContext példányosításakor meg kell adnunk a connection stringet. set. azaz az Isolated Storage legfelső mappájában egy Customer. szükségünk lesz egy DataContext-re is. set. amiben van egy Customer tábla. set. public Table<Customer> Customers { get { return customers. using (CustomerDataContext db = new CustomerDataContext("isostore:/Customer. set. A tulajdonságot a konstruktorban inicializáljuk. } [Column] public string City { get.DatabaseExists()) { db. Nincs lehetőség valami kényelmesebb. Hozzuk létre a Customers tulajdonságot. ami ebben az esetben isostore:/Customer. } [Column] public string ContactName { get. } } } Most már kész az entitás osztályunk.Linq.Data. } [Column] public string CompanyName { get.Lokális adatbázisok használata Windows Phone 7-en public int CustomerID { get. Itt az ideje az adatbázist fizikailag is létrehozni! Ehhez a DataContext példány CreateDatabase metódusát kell meghívnunk. Ehhez létre kell hoznunk egy újabb osztályt − ezt nevezzük el mondjuk CustomerDataContext-nek! Ezt az osztályt a DataContext osztályból kell származtatnunk (a DataContext a System. Ennek a konstruktornak paraméterként átadjuk az adatbázis eléréséhez szükséges connectionString paramétert.Data. } } Most már van egy adatbázisunk.

Indítsuk el az SQL Server Mangement Studio 2008 Express változatát (ha ez az alkalmazás nincs meg. Nemcsak létre tudunk hozni adatbázist. és a táblák között kapcsolatok is vannak. különösen. 5.8. 4. hogy létrehozzunk egy SQL Server CE adatbázist. arra is van lehetőségünk. hogy az adatbázisunk nem lesz levédve. akkor legegyszerűbben a Web Platform Installer-rel telepíthetjük fel)! 2. ekkor felugrik a Create New SQL Server Compact Database ablak (8-12 ábra). hogy van egy entitás osztályunk és egy DataContext példányunk. A fájl neve ebben az esetben a D meghajtó TestDb mappájára mutat. 8-12 ábra: Create New SQL Server Compact Database Most nem foglalkozunk a titkosítással.sdf adatbázist létrehozni a Management Studio. majd a megjelenő helyi menüben válasszuk ki a New Table menüpontot! 206 . Az Object Explorer-ben kattintsunk a Tables elemre jobb egérgombbal. A Database file-nál válasszuk a <New Database…> menüpontot. előállítsuk hozzá az entitás osztályokat és a DataContextet. itt kattintsunk a Connect gombra. ebben a mappában fogja a MyMusic. Bár elég egyszerű létrehozni adatbázist úgy. Ezt követően kattintsunk az OK gombra! Ugyan most kapunk egy figyelmeztetést. Indítás után egy Login képernyő fogad. Adatkezelés Adatbázis létrehozása II. hogy már meglévő adatbázist (sdf) hozzáadjunk a projekthez és kezeljük azt. ekkor az SQL Server Management Studio-ból kezelhetjük ezt az adatbázist. Nézzük meg ezt az esetet lépésről lépésre! A célunk tehát az. majd felhasználjuk egy WP7 alkalmazásban. és kattintsunk a Yes gombra! A későbbiek folyamán a titkosítással is fogunk foglalkozni. mégis egy bonyolultabb adatbázis szerkezetének létrehozása sok munkával járhat. ha nagyon sok táblánk van. Ezt követően visszaugrunk a Connect To Server ablakhoz. Itt a Server type-nál válasszuk az SQL Server Compact –ot (8-11 ábra)! 8-11 ábra: A Connect To SQL Server dialógus 3. 1. így az Encryption mode maradhat UNENCRYPTED. de ezzel most ne törődjünk.

A megjelenő New Table ablakban definiáljuk a Musics adattáblát.Lokális adatbázisok használata Windows Phone 7-en 6.cs fájlt (8-14 ábra). ahol az adatbázist elkészítettük (Ez jelen esetben a D:\TestDb mappa). True értékre állított Identity tulajdonsággal és annak alapértelmezett értékeivel. Persze itt is megtehetnénk. ami bár hivatalosan még mindig nem támogatott eszköz. A forrásfájlban lesznek az entitásosztályaink.sdf-ből készítünk MyMusic.exe alkalmazást az alábbi paraméterekkel: sqlmetal MyMusic. Az Artist és a Title mezők nvarchar típusúak. Ez a forrásfájl jelenleg az adatbázis mellett található. Kattintsunk az OK gombra! 7. a Windows Phone 7 fejlesztés során mégis nagy hasznát tudjuk venni. a Rating mező int típusú. Ehhez létre kell hoznunk az entitásokat reprezentáló osztályokat.sdf /code:MyMusic Ebben az esetben a MyMusic. de van szerencsére egy SQLMetal nevezetű eszköz is. hogy kézzel generáljuk az entitás osztályokat és a DataContextet. ahogyan azt a 8-13 ábra mutatja! 8-13 . valamint a DataContext is.A Musics adattábla definiálása Az ID oszlop egy int típusú elsődleges kulcs. bezárhatjuk az SQL Server Management Studio-t. Az adatbázist Windows Phone alól viszont csak Linq To SQL-lel érhetjük el. 207 . majd indítsuk el az SqlMetal. Most már elkészült az adatbázisunk. Indítsuk el a Visual Studio 2010 Command prompt-ot! 9. 8. A Command Prompt-ban az egyszerűség kedvéért navigáljunk el abba a mappába.

az SqlMetal nem generál teljesen kompatibilis kódot a Windows Phone 7-tel. Ez azért van. Mint korábban is említettük.Data.Data. akkor a 8-15 ábrán láthatóhoz hasonló hibát kapnánk: MyMusic db = new MyMusic("isostore:/MyMusic.Data. Ezt követően. Adatkezelés 8-14 ábra: Az SqlMetal használat közben 10. és válasszuk ki az Add Reference menüpontot! 13. alakítsuk át a két konstruktort az alábbi módon: public MyMusic(System. mappingSource) { OnCreated(). Igen ám. majd a megjelenő helyi menüben válasszuk ki az Add Existing Item menüpontot.Data névterében valóban nem létezik IDbConnection.Net fülre. hivatalosan nem is támogatott eszköz.Linq assembly-t is! Jobb egérgomb a References-re a Solution Explorerben.Data.Linq névteret! 14. System.IDbConnection connection) : base(connection.IDbConnection connection. mert a Windows Phone 7 System. Adjuk hozzá a projekthez a System. Amint elkészült az alkalmazás sablonja. a következő hibaüzenetet kapnánk: The type or namespace name 'IDbConnection' does not exist in the namespace 'System.Data. Most már kész az adatbázisunk és a hozzá tartozó osztályok is elkészültek! Itt az ideje használatba venni ezeket: indítsuk el a Visual Studio-t. } Ettől a ponttól kezdve már használatba vehetjük az adatbázist. de ha megpróbálnánk elérni azt. } public MyMusic(System. ha megpróbálnánk lefordítani az alkalmazást.MappingSource mappingSource) : base(connection. adjuk hozzá az adatbázist és az SqlMetal által generált forrásfájlt! Ehhez a Solution Explorer-en kattintsunk jobb egér gombbal. Ahhoz. hogy ez a DataContext helyes legyen.Mapping. 208 . és készítsünk egy új Windows Phone Application projektet (legyen a neve DatabaseSample)! 11. mappingSource) { OnCreated(). A megjelenő ablakban kattintsunk a .Data' (are you missing an assembly reference?) 15. és válasszuk ki a fentebb említett fájlokat! 12.Linq.8. mégis megkönnyíti a fejlesztést. és válasszuk ki a System. az SqlMetal viszont legenerálta azt.sdf").

egy speciális connection stringet kell megadnunk: MyMusic db = new MyMusic("Data Source = 'appdata:/MyMusic. using (Stream input = Application. Az adatbázist most már elérhetjük. The Database file cannot be found. hogy ezt az adatbázist használjuk (Reference Database). amint azt a 8-16 ábra is mutatja. de csak lekérdezéseket fogalmazhatunk meg rajta. mert az IsolatedStorage-ban nem szerepel ez az adatbázis.Relative)). azaz csak olvasható az adatbázis tartalma.Stream) { using (IsolatedStorageFileStream output = iso.sdf".GetResourceStream(new Uri("MyMusic. azonnal egy Permission Denied hibaüzenetet kapnánk. 209 . Bár Contentre van állítva az adatbázis Build Action tulajdonsága. Ezt a hibát azért kapjuk. Amint módosítani szeretnénk. (Az adatok módosításáról és hozzáadásáról a következő alfejezetben olvashatunk. File Mode = read only").sdf")) { byte[] readBuffer = new byte[4096]. Ehhez használhatjuk például az alábbi segédmetódust: public class DatabaseHelper { public static void MoveReferenceDatabase() { IsolatedStorageFile iso = IsolatedStorageFile. 17. és az XAP-ban is benne van ez az adatbázis.) 8-16 ábra: Permission denied üzenet az adatbázis módosításakor 18. 16. int bytesRead = -1. Ahhoz.GetUserStoreForApplication(). az adatbázist át kell másolnunk az Isolated Storage-ba.sdf'.CreateFile("MyMusic. UriKind. hogy ezt elkerüljük.Lokális adatbázisok használata Windows Phone 7-en 8-15 ábra: SqlException was unhandled. mégsem található az Isolated Storage-ban! Ahhoz.

Customers. City = "Budapest" }.sdf"). és ezek után a megszokott módon tudjuk lekérdezni. hogy példányosítjuk a megfelelő entitás osztályt. Láthattuk. Bár ez a módszer nem teljesen támogatott. és a tulajdonságait feltöltjük a kívánt értékekkel. db.SubmitChanges(). Az összes adat lekérdezése: var result = from c in db.Read(readBuffer. Adatkezelés while ((bytesRead = input. hogy ebben az esetben a connection stringet a hagyományost isostore értékre kell visszaállítanunk: MyMusic db = new MyMusic("isostore:/MyMusic. majd ezt az osztálypéldányt átadjuk az InsertOnSubmit metódusnak. ----------------------------------------------------------------------------------------var result = db. amíg a SubmitChanges metódust meg nem hívjuk: Customer myCust = new Customer() { CustomerID = 1. akkor egy segédmetódust is definiálnunk kell az adatbázist mozgatásához. az átmásolja az adatbázist az Isolated Storage-ba. akár bővítő metódusokkal le tudjuk kérdezni az adatainkat. 210 . itt az ideje megismerkedni azzal.Select(s => s). db. mégis nagyon sokszor hasznos lehet. Adatok lekérdezése − SELECT Az adatok lekérdezéséhez is a Linq To SQL-t hívjuk segítségül.Length)) > 0) { output. hogy milyen lépéseket kell megtennünk ahhoz.Customers select c. CompanyName = "Livesoft". ha azonban módosítani is szeretnénk. hogy már meglévő adatbázist használjunk fel a Windows Phone 7 készülékünkön.Customers. akkor egyszerűen csak hozzáadjuk az adatbázist és az legenerál egy forrásfájlt a projektünkhöz. módosítani az adatbázis tartalmát. Ne felejtsük el. Ha csak olvasható adatbázist akarunk használni.8. Az adatbázisunk még üres. readBuffer. } } } } } 19. Az adatbázisban mindaddig nem kerül az új rekord letárolásra. Amint meghívjuk a MoveReferenceDatabase metódust. ContactName = "Attila Turoczy". A lekérdezések szintaktikája nagyon egyszerű: akár Linq szintakszis használatával. 0. 0.Write(readBuffer.InsertOnSubmit(myCust). hogy hogyan töltsük fel az adatbázist adatokkal. Nézzünk néhány lekérdezést! A következőkben mindkét lekérdezési formát bemutatjuk. mint a T-SQL-nél! Egyszerűen csak annyi a dolgunk. bytesRead). és hogy hogyan kérdezzük le azokat! Adatok felvitele − INSERT A Linq To SQL használata során nem kell INSERT SQL Scriptet írnunk.

foreach (var item in result) { item. Adatok módosítása − UPDATE Ha frissíteni szeretnénk az adatbázis tartalmát. ----------------------------------------------------------------------------------------var result = db.First(). használata nagyon egyszerű. és hívjuk meg a SubmitChanges-t! var selectedItem = (from c in db.Customers. Az alábbi példában lekérdezzük az összes ügyfelünket. akkor egy where feltételt kell meghatároznunk: var result = from c in db. akkor is nagyon egyszerű dolgunk van: csakúgy.City == "Budapest"). mindössze annyi a dolgunk.Customers where c. majd minden ügyfelünk városát átírjuk Seattle-re. mint korábban.Where(s => s. adjuk át paraméteréül a DeletOnSubmit metódusnak. Látható.Customers. ----------------------------------------------------------------------------------------var result = db. hogy a szintaktika logikusan felépített.OrderBy(s => s. 211 . ----------------------------------------------------------------------------------------var result = db. db.SubmitChanges().CompanyName. itt sem kell SQL Script-eket írnunk. majd meghívjuk a SubmitChanges metódust. és a végén meghívjuk a SubmitChanges metódust: var result = from c in db.Customers orderby c.Customers select c.Customers.SubmitChanges().City == "Budapest" select c.Lokális adatbázisok használata Windows Phone 7-en Egy oszlop lekérdezése: var result = from c in db. } db. amit törölni szeretnénk.CustomerID == 1 select c).City = "Seattle".Customers. Adatok törlése − DELETE Ha az adatbázisunkból szeretnénk törölni adatokat. Válasszuk ki azt az rekordot (objektumot).City).DeleteOnSubmit(selectedItem). hogy a lekérdezett adatok tulajdonságát átírjuk a megfelelő értékre.Select(s => s. Sorbarendezés: var result = from c in db. az is rendkívül egyszerűen kivitelezhető.CompanyName).Customers where c. Ha az eredményhalmazt szűkíteni szeretnénk.Customers select c.City select c. db.

} Adatbázis kezelés gyakorlat A következő gyakorlatban egy mini bevásárlólista alkalmazást fogunk elkészíteni. set.Linq. Az alkalmazás felhasználó felülete már előre el van készítve (8-17 ábra).Password='Pa$$word1'"). IsDbGenerated=true)] public int Id { get. illetve a lekérdezéseket megírni. és azt csak jelszóval tudjuk elérni.cs fájlt az Entities mappán belül. A ShopItem törzsét a következő módon alakítsuk ki: [Column(IsPrimaryKey=true. A ShopItem osztály definícióját lássuk el a [Table] attribútummal! [Table] public class ShopItem { 4.Data.DatabaseExists()) { db. hogy milyen oszlopokkal szeretnénk dolgozni.sdf'. 8-17 ábra: A bevásárló alkalmazás egy képernyője 1. hogy az adatbázis tartalma titkosítva legyen. Ezt a jelszót a connection string-ben kell átadnunk! Az adatbázis titkosításához AES-128. Indítsuk el a Visual Studio 2010-et és töltsük be a LocalDatabaseDemo.Mapping. if (!db. 3.Mapping névteret! using System. Meg kell határoznunk.sln fájlt! 2. } [Column] public string Title { get. Ha az adatbázis titkosított.CreateDatabase(). Adatkezelés Az adatbázis biztonsága A lokális adatbázis lehetőséget biztosít arra. Az alábbi példában látható.hu/wp7 oldalról tölthetjük le.8.Data. A kiinduló projektet a http://devportal. Nyissuk meg a ShopItem. } 212 . hogyan hozzunk létre egy biztonságos adatbázist: CustomerDataContext db = new CustomerDataContext("Data Source='isostore:/Customer.Linq. csak jelszóval érhetjük el. míg a jelszóhoz az SHA-256 titkosítási eljárást használja a rendszer. nekünk csak az adatbázist kell megterveznünk. majd oldjuk fel a System. set.

cs fájlját. } } public ShopDataContext(string connectionString) : base(connectionString) { this. } 9. és navigáljunk el a save_Click eseményhez.CreateDatabase(). if (!db.ToInt32(txtPrice. nem történik semmi. és az Application_Startup metódusban hozzuk létre az adatbázisunkat a CreateDatabase metódus segítségével! Abban az esetben. ha már létezik az adatbázis. ShopItem shopItem = new ShopItem() { Title = txtTitle. de még üres. Speciális eset az Id tulajdonság. Létre kell hoznunk egy DataContextet is. A ShopDataContext kódját pedig a következőképpen írjuk meg: private Table<ShopItem> shopItem. hogy az adott terméket megvettük-e már.cs fájlt. Nyissuk meg az App. a Price tulajdonságban a termék hozzávetőleges árát. ugyanis nemcsak azt jelöljük.xaml. 213 . hogy ez egy oszlop.xaml. hogy ez egyúttal egy olyan elsődleges kulcs. 5.cs fájlt. ShopDataContext db = new ShopDataContext("isostore:/shop.Lokális adatbázisok használata Windows Phone 7-en [Column] public int Price { get.DatabaseExists()) { db. Price = Convert.shopItem = GetTable<ShopItem>(). Ezzel kész az entitásosztály definíciója. majd oldjuk fel a System.Text) }.Linq. set.sdf"). hanem azt is. set.Text. } A Title tulajdonságban tároljuk el a vásárolni kívánt termék nevét. hogy a tulajdonságok mindegyikét egy [Column] attribútummal láttuk el. Már elkészült az adatbázisunk.sdf"). majd adjuk hozzá az alábbi kódsorokat: try { ShopDataContext db = new ShopDataContext("isostore:/shop. hogy az adatbázishoz tudjunk kapcsolódni.Data. Nyissuk meg a ShopDataContext. Töltsük fel adatokkal! Nyissuk meg a Pages mappa NewShopItem.Linq névteret! using System. } [Column] public bool IsBought { get. public Table<ShopItem> ShopItem { get { return shopItem. Látható. } 8. amely értékét az adatbázis fogja előállítani.Data. míg az IsBought azt mutatja. 6. A ShopDataContext osztályt származtassuk le a DataContext osztályból! public class ShopDataContext : DataContext { 7.

IsBought == false).Where(s => s.ShopItem.Relative)). amiket még nem vettünk meg! lstShopItems. azaz még nem vásároltuk meg az adott terméket. amit nem vettünk még meg! Ha ennek az értéke nagyobb. } else { txtSum.ShopItem where c. hogy mennyivel tud többet a Linq. Nem töltöttük ki az IsBought tulajdonság értékét. 11.Text = "0 Ft".Count() > 0) { txtSum. Itt az ideje megjeleníteni az adatainkat.Navigate(new Uri("/MainPage. hogy hány darab olyan termékünk van.OK).Format("{0} Ft". hogy a kiválasztott termékeknek mennyi a teljes ára: if (db. amely tulajdonságainak az értékeit a felhasználói felületi hozzá tartozó elemei határozzák meg.OriginalSource as Button). akkor megvizsgáljuk azt is. } Itt egy ShopDataContext-et példányosítunk. akkor kihúzzuk azokat a termékeket.FirstOrDefault(). és kérdezzük le azokat a termékeket az adatbázisból.Content.sdf").Price)). amelyeket már betettünk a kosárba. var selectedItem = (from c in db. meghívjuk az InsertOnSubmit metódust.Show("Hiba: " + ex. } catch (Exception ex) { MessageBox. NavigationService.Id == selectedIndex select c). 10. Már csak egy lépés maradt hátra.DataContext = from c in db. így az alapértelmezett értéke a false lesz.Where(s => s. Azért.SubmitChanges(). db.ShopItem .ShopItem. UriKind. Ezt követően egy ShopItem példányt hozunk létre. "Hiba!". Ha ez megvan. hogy ha vásárolunk valamit a listáról. Adatkezelés db. 12.ToString()). db.ToInt32((e.xaml". mégpedig az. Navigáljunk el a GetData metódusba.ShopItem where c. MessageBoxButton. fejlesszük tovább a GetData metódust: egy feltételben vizsgáljuk meg.IsBought == false select c. hogy lássuk. Ehhez navigáljunk el a btnCheck_Click eseményhez és írjuk be a következőt: int selectedIndex = Convert. aminek megadunk egy connection string-et (ezt globálisan is megtehetnénk). A konstruktor előtt most hozzunk létre egy ShopDataContext példányt! (Task – 9) ShopDataContext db = new ShopDataContext("isostore:/shop. mint nulla.8. 214 .InsertOnSubmit(shopItem). } 13.Sum(s => s. majd a SubmitChanges metódussal eltároljuk az adatbázisba. Ezt követően visszanavigálunk az eredeti oldalra.IsBought == false).Text = String.Message.

majd kattintsunk a termékek neve melletti pipára! Miután rányomtunk. Ezután lekérdezzük az adott azonosítójú terméket az adatbázisból. Az egyszerűség kedvéért ezt követően meghívjuk a GetData metódust. Vigyünk fel még néhány elemet. hogy a Windows Phone 7 készülékeken is a . az adott elem kikerül a listából.SubmitChanges(). 14. itt elérhető a Linq To SQL technológia. Az ugyan nem jelenik meg a felhasználói felületen. ha ez a folyamat mégse így történne. akkor az adatokat elmentjük az adatbázisba. ahol az előzőleg felvitt termékek láthatóak. Láthattuk. 215 . akkor az IsBought tulajdonságot true értékre állítjuk. nézzük át újra a lépéseket. de a háttérben bele van írva az adott termék azonosítója (Id tulajdonság). majd meghívjuk a SubmitChanges metódust. hogy hogyan is kell a Windows Phone 7 alkalmazásokban adatot kezelni: hogyan kell adatokat lementeni. amely az első elemet veszi ki a visszaadott eredmény gyűjteményből. valamint hogyan lehet az adatokat egy relációs adatbázisban eltárolni. letisztult megoldásokat kapjuk. Abban az esetben. és a hibákat javítsuk! Összefoglalás Ebben a fejezetben megnéztük. és adjunk hozzá egy új terméket! Amikor a mentés gombra kattintunk. Indítsuk el. hogy hogyan működik! Kattintsunk az új ( + ) gombra. és az összesen értéke is a kipipált elem értékével csökken. Ha ez az érték nem null. Első lépésben lekérdezzük a terméket reprezentáló gomb tartalmát. amivel újra lekérdezzük az összes nem megvásárolt terméket és az ezekhez tartozó összeget. Ahogyan Silverlight alatt is van Isolated Storage. Ezt követően a főképernyőn találjuk magunkat. } GetData(). ha nincs ilyen azonosítójú elem. Abban az esetben. és nézzük meg. Elkészült az alkalmazásunk. beállításokat eltárolni. db.IsBought = true.NET-ben megszokott.Összefoglalás if (selectedItem != null) { selectedItem. akkor az objektum alapértelmezett értékével tér vissza. A Linq kifejezés végén egy FirstOrDefault bővítő metódus áll.

.

így az adott hírforrást szabványos módon olvashatjuk – miközben a hírportál honlapja természetesen lehet bármilyen egyedi. hogy minden Windows Phone operációs rendszert futtató készüléknek legalább 256 megabájt memóriával és 1 GHz körüli processzorral kell rendelkeznie. Webszolgáltatások segítségével természetesen írhatunk saját hitelesítési mechanizmust. olvasás. paramétereit és visszatérési értékét (pl. Ennek kapacitása természetesen szűkös. Webes tartalom közvetlen elérése: Az internet tartalmának túlnyomó része HTML. A fejezetben ennek különféle lehetőségeit ismerjük meg. mintha egy helyben. olcsón. hogy a számításigényesebb feladatokat kiszervezzük – célszerűen szerveroldalra. Ezek mindegyikéhez csatlakozhatunk telefonalkalmazásainkból. Remek példa erre az RSS feed. A Microsoft kötelezően előírta. központi adatbázissal való kapcsolat lehetőségét. és fájlok képében érhető el. aminek legjobb módja. hogy a telefonok nagyságrendileg olyan erősek. A webszolgáltatások segítségével szerverünk kiajánlhat egy műveletet. Egy sor szabványos technológia segítségével kliensünk (ez esetben a telefon) ezt a metódust ugyanúgy hívhatja meg. és utána biztonsági szempontból    217 . A platform ehhez gazdag támogatást nyújt. de ez nekünk és felhasználóinknak is kényelmetlen. Ezért nagyon fontos spórolnunk az akkumulátor kapacitásával. rugalmasan juthatunk számítási kapacitáshoz. és a távoli szervert alkalmazásunk szerves részeként használhatjuk. hanem az akkumulátor: ritka. és nem alkalmas egy komolyabb alkalmazás (mondjuk egy raktárkezelő) központi adatbázisának. Az OData szabvány segítségével rengeteg adatforrást tudunk manipulálni a fejlesztő számára egyszerű módon. feldolgozhatnak. Ennek elérését megoldhatnánk egy sor egyénileg fejlesztett webszolgáltatással (írás. string GetName(int userId)). valamint számos további Microsoft és külső fejlesztők által készített program és webes alkalmazás is használható OData kiszolgálóként. Egy másik ilyen lényeges trend a közösségi média rohamos terjedése. a felhasználók elvárják a többi felhasználóval.9. Nekünk azért. Legyen szó szinte bármilyen alkalmazásról. A kommunikáció módjai A legfontosabb kommunikációs módszerek egy alkalmazás fejlesztése során:  Webszolgáltatások: A webfejlesztés világában régóta bevett technológia. Ilyen esetekben egy központi szerveren futó adatbázist célszerű igénybe venni. tárhelyhez vagy épp adatbázishoz. hogy Windows Phone alkalmazásunk kommunikálhasson külső szerverekkel. Ez egy széles körben elterjedt formátum. Felhasználó-hitelesítés: Ha internetre csatlakozó alkalmazást írunk. hogy egy rendszeresen használt okostelefon 1-2 napnál tovább bírja újratöltés nélkül. amivel időben gyorsan változó híreket írhatunk le. mert sokat kell kódolnunk. HTML oldalakról vagy bármilyen más fájlról. Így a webszolgáltatásokat könnyen alkalmazhatjuk. Ez azt jelenti. mint egy netbook. a SharePoint. Windows Phone alkalmazásaink bármilyen internetes tartalmat letölthetnek. Adatbázis-elérés: a Windows Phone 7. legyen szó RSS feedekről. Az SQL Server. de ezzel nem kell fáradnunk. Ezenfelül épp napjainkban lehetünk tanúi a számítási felhő térhódításának. A felhő segítségével percek alatt. hiszen a többi telefonon futó alkalmazáspéldány nem fér hozzá.5 (Mango) már tartalmaz közvetlenül a telefonon futó SQL adatbázist. akkor óhatatlanul felmerül a felhasználó bejelentkeztetésének kérdése. a telefonalkalmazásunkban lévő műveletről lenne szó. amelynek megadja a nevét. Fontos tehát. A legsúlyosabb korlátozást viszont nem is a számítási kapacitás adja. törlés minden egyes táblára). Kommunikáció szerverrel A telefonok hardvere robbanásszerűen fejlődik.

ám a felhasználói élményt 218 . A Windows Phone platform ezenkívül néhány egyedi telefon-szerver kommunikációs funkciót is biztosít. Mindez azt jelenti. másrészt megvárja és lefordítja a választ.NET-világban erre a Windows Communication Foundation-t (WCF) használjuk. Ha a proxy osztály szinkron működésű. és befogadja a szervertől kapott választ. Ezekről a speciális funkciókról a könyv további fejezeteiben lehet olvasni:  Maps: Telefonalkalmazásunkba beépíthetünk térkép-vezérlőt. A Maps vezérlőelemről és képességeiről a 4. Facebook vagy Yahoo fiókjukkal jelentkezhetnek be alkalmazásunkba. videó vagy dokumentum. melyek szerveroldalról is frissíthetők anélkül. A fejezet során a fentiek közül mindegyiket részletesen megismerjük. Push Notifications: A Windows Phone platform kulcsfontosságú elemét alkotják a telefon kezdőképernyőjén látható lapkák. Természetesen nem tárolódik a teljes világtérkép a telefon memóriájában. kódunk addig nem is halad tovább. Ez az osztály már a kliensoldalon használt programnyelvben (pl. mert még egy név/jelszó párost kell megjegyezniük. Ha valamelyiket meghívjuk. hogy milyen metódusokat szeretne kiajánlani. de a platform erre is nyújt kész megoldást.  Webszolgáltatások használata A webszolgáltatások működése Amint a bevezetőben már volt róla szó. amíg a háttérben történő műveletek be nem fejeződtek. A kliensoldali programkódunkból ezeket a metódusokat tudjuk használni. A fejlesztőkörnyezet ebből egy úgynevezett proxy osztályt generál. Kommunikáció szerverrel kritikus infrastruktúrát kell üzemeltetnünk.9. amit az interneten keresztül is meghívhatunk. A fejlesztés során a programozó először meghatározza. Google. Ilyen lehet például a felhasználó által feltöltött fényképalbum. Amint láttuk. hogy a webszolgáltatások komplex internetes kódjával egyáltalán nem kell bajlódnunk – az oda-vissza fordítást (az angol plumbing szó magyar fordításával„vízvezeték-szerelést”) elvégzi helyettünk a fejlesztőkörnyezet. és tartalmazza a leírófájlban található összes metódust. A felhasználóinknak pedig azért. Az ebben közzétett információ tartalmazza a metódus visszatérési értékét. akkor a proxy osztály generált kódja elküldi kérésünket az interneten keresztül. A fentiek segítségével szinte bármilyen kommunikációs igénynek meg tudunk felelni. egy webszolgáltatás nem más. hogy alkalmazásunknak futnia kellene. Ennél van jobb megoldás is: a Windows Azure egyik szolgáltatását kihasználva például felhasználóink meglévő Live ID. fejezetben található részletes leírás. nevét és elvárt paramétereit (a bevezetőben látott példa: string GetName(int userId)). és ezek küldik aztán vissza a metódus futási eredményét a kérőnek. akkor a két háttérműveletet egy egységként kezeli. majd elkészíti a szolgáltatást. Ez programozói szempontból egyszerű. Ezek fordítják le az internet felől beérkező kérést a metódust futtató programnyelv számára értelmezhető formára. azaz miután meghívtuk a proxy osztály valamelyik metódusát.  Adattárolás: Az OData segítségével könnyedén tárolhatunk adatsorokat. Ilyenkor többnyire (a használt technológiától függően) egy XML formátumú leíró fájl jön létre. C#-ban) készül. mint egy szerveren lévő metódus. Saját szerverrel és webszolgáltatással természetesen ez is megoldható. Ezután a kliensoldalon az ottani fejlesztőkörnyezet számára megadjuk ezt a leíró fájlt. A . Ezekről a 10. de minden más szerveroldali technológia is ad lehetőséget webszolgáltatások készítésére. Kódunk szemszögéből mindez tűnhet szinkron vagy aszinkron műveletnek. de a rekordok mellett gyakran fájlokat is el kell mentenünk. Egy osztálykönyvtár segítségével közvetlenül a telefonról írhatjuk és olvashatjuk a Windows Azure tárhelyszolgáltatását. az épp megnézett terület a Bing Maps szolgáltatásból töltődik le. fejezetben van bővebben szó. a webszolgáltatás meghívásakor a háttérben valójában két művelet történik: a proxy osztály egyrészt elküld egy kérést. Ennek működéséhez persze egy sor technológia kell.

NET Empty Web Application típusú új projektet. a tényleges kód nem ide kerül. de futásidőben ezt a fájlt kell majd meghívni kívülről 219 . Mi a WCF-et használjuk majd.cs kódfájl.cs kódfájl. Ezt elkerülendő a Windows Phone által generált proxy osztályok csak aszinkron működésűek lehetnek. és ma már egy előző generációs technológiát képvisel. Mindhárom elemnek fontos szerepe van a webszolgáltatás létrehozásában. 9-1 ábra: A webszolgáltatás hozzáadása A szolgáltatás hozzáadása után három elem is létrejön projektünkben: az ISampleService. ami nagyon megkönnyíti majd az aszinkron műveletekkel való programozást. ez csak egy interfészt ad majd.svc. és az alkalmazásunk ezalatt „lefagyottnak” tűnhet. hogy a C# nyelv 5-ös. A válasz megérkezésekor az általunk megadott eseménykezelő fut majd le.Webszolgáltatások használata ronthatja. akkor szükségünk lesz az ingyenes Visual Web Developer Express változatra is. és nevezzük ezt el WebServiceServerSample-nek! A projekt létrejöttekor üres. ezen sorok írásakor fejlesztés alatt álló verziójában szerepelni fog az async kulcsszó. fejlesztői szempontból ez kicsit kényelmetlenebb. A webszolgáltatás meghívása és válasza között (akár a szerver terheltsége. Amikor meghívjuk a proxy valamelyik metódusát. Jó hír. akkor az alkalmas lesz mindkét típusú fejlesztésre. fel kell iratkoznunk a válaszra. Mivel kódunkat emiatt szét kell darabolnunk. akár az internetkapcsolat lassúsága miatt) néha másodpercek is eltelhetnek.NET Frameworkön belül. a SampleService. azaz a kérés elküldését és a válasz megérkezését különválasztják. ami az aktuális webszolgáltatás-fejlesztő eszköz a . Hozzunk létre benne egy új webszolgáltatást! Ehhez vegyünk fel a projektbe egy WCF Service típusú elemet SampleService néven! A listában (lásd 9-1 ábra) láthatunk egy Web Service-nek keresztelt elemet is. Ez egy ASMX kiterjesztésű fájlt hoz létre. Webszolgáltatás egy mintaalkalmazásban Írjunk egy Windows Phone alkalmazást.svc jelenleg egy sorból áll. Ha a Visual C# Express van a gépünkön a Windows Phone fejlesztéshez. Ha viszont a Visual Studio valamelyik fizetős verzióját használjuk. ami egy webszolgáltatást hív meg! Kezdjük a webszolgáltatással! Ehhez kell majd egy webfejlesztésre alkalmas Visual Studio verzió. de a felhasználói élménynek nagyon jót tesz. A SampleService. Hozzunk létre egy ASP.cs állományban kell definiálnunk a kiajánlani kívánt metódusokat. Az ISampleService.svc leírófájl és az ehhez tartozó SampleService. és így tudjuk folytatni programunk működését.

Az attribútum nagyon fontos. 220 .NET Development Server (Cassini) lesz.cs fájlt! Itt szintén látjuk majd a DoWork() metódust (ezúttal már attribútum nélkül).) Egy egyszerű fordítási szolgáltatást készítünk: a telefonalkalmazás felküld egy szót. hogy megírhassuk. A fájlt megnyitva láthatjuk. Nevezzük át ezt a metódust az általunk kívántra! [OperationContract] string Translate(string input). Végül a SampleService. hogy a metódust meg szabad hívni az internet felől is (azaz ki kell kerülnie a leírófájlba). meghívható. és helyettesítsük az alábbi kóddal! public string Translate(string input) { if (input == "alma") { return "apple". és egy string változót is ad vissza. egyszerű. Kommunikáció szerverrel a szolgáltatás eléréséhez. hogy egy void DoWork() nevű metódus már létezik. e fájl nélkül is működhet a szolgáltatás. „szótárunk” mindössze két szót tartalmaz majd. } else { return "(ismeretlen)". Teszteljük működését! Az F5-tel indítsuk el alkalmazásunkat! Ennek hatására elindul egy helyi gépünkön futó. kifejezetten fejlesztésre való webszerver. (Az ISampleService.cs-ben deklarált metódusok tényleges kódja.cs nem létfontosságú. hogy webszolgáltatásunk sikeresen lefordult. Ez igazolja. mert ezen a néven generálja majd a futtatókörnyezet a korábban már tárgyalt leírófájlt. Most írjuk meg a metódushoz tartozó kódot! Ehhez nyissuk meg a SampleService.svc. Beállítástól függően ez vagy az ASP.9. ez tudatja a futtatókörnyezettel. mi pedig visszaküldjük azt angolul. Bemutató alkalmazásról lévén szó. de itt nem tárgyalt WCF konfigurációs okok miatt célszerű használni. vagy az IIS Express. } else if (input == "szilva") { return "plum".cs-be kerül az ISampleService.svc. Néhány másodpercen belül megnyílik az alapértelmezett böngészőnk. Ahhoz.cs interfészben. először deklarálnunk kell az ISampleService. Az ehhez szükséges metódus egy string változót vár. Töröljük ki. ami egy [OperationContract] attribútummal van ellátva. } } Ezzel a szerveroldallal gyakorlatilag el is készültünk. és a 9-2 ábrához hasonló weboldal tárul elénk.

és minden gépen más lesz.Webszolgáltatások használata 9-2 ábra: A fejlesztői szerverből kiszolgált webszolgáltatás Ha egy üres oldalt vagy valamilyen hibaüzenetet látunk. hogy használhassuk a webszolgáltatást. és válasszuk az Add Service Reference menüpontot! A megjelenő párbeszédpanel tetejére írjuk be a korábban kimásolt URL-t. E művelet során olvassa majd be a Visual Studio a szerverünk által publikált leíró állományt. Válasszuk a Windows Phone OS 7. hogy a telefon melyik verziójához készítjük a projektet. Most térjünk át a kliensoldalra. ha nincs ott. hogy webes projektünknek még futnia kell!) A Visual Studio letölti és feldolgozza a megcélzott webszolgáltatás adatait. fel kell rá vennünk egy referenciát. majd kattintsunk a Go gombra! (Fontos. Jelenleg egy ilyet tartalmaz a webszolgáltatásunk: az imént megírt Translate() metódust. Referencia felvételéhez kattintsunk jobb gombbal a projekt nevére (WebServiceClientSample) a Solution Explorer ablakban. később még szükség lesz rá! A fent leírtak gyakorlatilag változtatás nélkül működnek akkor is. majd a párbeszédpanel közepén található területen megjeleníti az általa támogatott metódusokat (lásd 9-3 ábra). neve pedig WebServiceClientSample! A projekt létrehozását követően a Visual Studio megkérdezi majd. ha a szerveroldalon Windows Azure-t használunk. A /SampleService. és készíti el a bevezetőben említett proxy osztályt. és írjuk meg a szervert meghívó Windows Phone alkalmazást! Ehhez nyissunk egy új Visual Studio projektet. Adjunk egy nevet a referenciának (SampleServiceReference). és kattintsunk az OK gombra! 221 .svc elérési útnak viszont szerepelnie kell. kézzel írjuk be! Az URL-t jegyezzük meg.1 (vagy valamelyik újabb) változatot! Ahhoz. amely legyen Windows Phone Application típusú. akkor ellenőrizzük az URL-t! A localhost nevet követő portszám véletlenszerűen generált.

ClientConfig néven találjuk meg projektünkben. elég csak ki-be kapcsolnunk). amely MainProgressBar névre hallgat és alapértelmezésként nem látható. Ezért meghívásához először feliratkozunk arra az eseményre.SampleServiceClient(). Ha alkalmazásunkat élesben szeretnénk felhasználni.TranslateCompletedEventArgs>( client_TranslateCompleted). akkor ebben az állományban kell átírni a webszolgáltatás URL-jét a végleges címre. Hozzuk létre programunk felhasználói felületét! Ehhez helyezzünk ki egy szövegdobozt és egy gombot a tervezőfelületre! A szövegdoboz neve legyen MessageTextBox. és ez alá szúrjuk be az alábbi kódot: <ProgressBar Name="MainProgressBar" IsIndeterminate="True" Visibility="Collapsed"></ProgressBar> Ezzel létrehoztunk egy határozatlan futású ProgressBart (azaz nem kell megadnunk. ezért kézzel kell hozzáadnunk alkalmazásunk XAML kódjához. a gomb neve pedig legyen TranslateButton! Az igazán elegáns megoldás érdekében ezután helyezzünk el egy ProgressBart is (ez az a vezérlőelem. aztán ténylegesen elküldjük a kérést. Ezenfelül. Most kattintsunk duplán a gombra. és tulajdonságait elhelyezi egy új fájlban. RoutedEventArgs e) { SampleServiceReference.TranslateCompleted += new EventHandler<SampleServiceReference.9. bekapcsoljuk a ProgressBar-t: private void TranslateButton_Click(object sender. Keressük meg a XAML kódban a gombunkat leíró sort (<Button>). amikor a telefon dolgozik valamin)! A ProgressBar nem látható az eszköztáron. hogy épp hány százalékon áll. Ezt ServiceReferences. hogy a felhasználó felé jelezhessük a háttérben zajló munkát. de amint korábban már szó volt róla. Kommunikáció szerverrel 9-3 ábra: A Service Reference-hozzáadó ablak A Visual Studio legenerálja a proxy osztályt. client. ami a kérés befejezését jelzi majd.SampleServiceClient client = new SampleServiceReference. hogy belépjünk a Click eseménykezelőjébe! Kódunknak meg kell hívnia a webszolgáltatást. ami a Windows Phone „mozgó pontjait” generálja. 222 . a webszolgáltatás aszinkron.

és megjelenítjük azt a felhasználó számára.Webszolgáltatások használata client. Az itt leírtak már elegendőek egyszerű kliens-szerver kommunikáció létrehozásához. Ha ez később változik. Nemcsak a primitív adattípusok.TranslateCompletedEventArgs e) { MainProgressBar.Visible. hanem komplex változók is használhatók a kommunikáció során.Error. fel kell készülnünk az esetleges hibákra! Ha hiba történik. hogy az átküldeni kívánt objektumnak sorosíthatónak kell lennie. annak gazdag Windows Communication Foundation irodalom áll a rendelkezésére.Visibility = Visibility.NET adattípus ilyen. Teszteljük le! Indítsuk be a telefonalkalmazást (és győződjünk meg róla. egy saját magunk által létrehozott adattípus (Employee) vagy szinte bármi más. a saját osztályainkat pedig mindössze el kell látnunk a [Serializable] attribútummal. megjeleníti a ProgressBar-t. hanem kezeljük a hibát.Collapsed. Ehhez kattintsunk jobb gombbal a létrejött referenciára. 223 . és válasszuk az Update Service Reference menüpontot! A webszolgáltatások segítségével lényegében tetszőleges kommunikációt lebonyolíthatunk telefonunk és egy szerver között. Ez mindössze annyit tesz. egy tömb (int[]). } else { MessageBox. Ez a technológia egy óriási témakör.ToString()). 9-4 ábra: A végrehajtott webszolgáltatás-hívás eredménye Ezzel megismertük egy új webszolgáltatás létrehozását. melynek most csak a felszínét karcolgattuk. if (e. hogy megjeleníti a webszolgáltatástól kapott választ. hogy a webalkalmazás még mindig fut-e)! Írjunk be egy magyar szót (legyen „alma” vagy „szilva”)! Látni fogjuk. void client_TranslateCompleted(object sender. } } Ezzel elkészültünk a mintaalkalmazással.Show(e. majd kisvártatva megkapja és megjeleníti a választ (lásd pl 9-4 ábra). Ilyen például egy generikus lista (List<string>).Visibility = Visibility.Show(e. Lényeg. MainProgressBar. SampleServiceReference. akkor nem hagyjuk programunkat lefagyni. akkor a proxy osztályt is frissítenünk kell.Error != null) { MessageBox.TranslateAsync(MessageTextBox. } A kérés befejezésekor lefut az eseménykezelő. Mivel a szolgáltatás meghívása az interneten keresztül történik.Text). A legtöbb . Aki ennél jobban szeretne elmélyedni a webszolgáltatások használatában. hogy alkalmazásunk elindítja a kérést.Result).

Ezen metódushívásban átadunk egy úgynevezett callback függvényt – ezt hívja majd meg a futtatókörnyezet.9. ha pedig pontosabb irányításra van szükségünk.1 vagy újabb verzióval! Vegyünk fel a felületére egy HttpButton nevű gombot. hogy szükségünk lenne a HTTP válaszra. vagyis azt bármilyen állapot-információ átadására is használhatjuk. így egyéb . Először is „kicsomagoljuk” a HttpWebRequest példányt. alkalmazhatjuk a HttpWebRequest/HttpWebResponse osztályokat. amit átadtunk a callback metódusnak. ha a válasz beérkezett. } Most készítsük el a RequestCallback nevű metódust. HTTP kommunikációra kitalált osztály létezik a Windows Phone platformban: a HttpWebRequest/HttpWebResponse páros.com weboldalt fogjuk majd letölteni és megjeleníteni. request. amire hivatkoztunk! A logika kissé nyakatekert. Ez tartalmazza a beérkezett HTTP választ. RoutedEventArgs e) { HttpWebRequest request = (HttpWebRequest)HttpWebRequest. A WebClient gyakorlatilag nem más. Miután ezzel elkészültünk. A HttpWebRequest-nél ezzel szemben először létrehozunk egy HttpWebRequest típusú osztályt. majd dupla kattintással lépjünk be a Click eseménykezelőbe! Ahogy a webszolgáltatásoknál.example. A konkrét kód azonban kissé másképpen néz ki. Ebben az alfejezetben az erre alkalmas módszereket ismerjük meg. A Stream változó string változóba olvasásához szükségünk lesz a System. egy HTML oldal vagy valamilyen fájl. Emellett egy másik paraméterben egy tetszőleges objektumot adhatunk meg. Alapvetően két. „HttpWebRequest” felirattal.NET-es tapasztalatainkból már ismerősek lehetnek. hogy nem a saját szerverünktől szeretnénk lekérni valamit. Ezeket az interneten használt HTTP protokoll segítségével tudjuk elérni.IO névtérre. Windows Phone OS 7. Ennek oka is hasonló: egy letöltés több másodpercet is igénybe vehet. Ott feliratkoztunk a művelet befejezésének eseményére. request).BeginGetResponse(RequestCallback. hanem egy Stream-ként. amit egy eseménykezelővel kaptunk el. itt is kizárólag aszinkron metódusokat használhatunk. Kommunikáció szerverrel Webes tartalom letöltése A webszolgáltatások kiváló eszközt nyújtanak a saját szerverünkkel való kommunikációra. Azonban a HttpWebResponse példányban nem stringként szerepel a megkapott weboldal. ezért helyezzük az alábbi sort a kódfájl legtetejére: 224 . Az előző alfejezethez hasonlóan most is egy példaalkalmazást készítünk. Ilyen lehet például egy kép. Gyakran előfordul azonban. Írjuk meg a gomb Click eseménykezelőjét az alábbiaknak megfelelően: private void HttpButton_Click(object sender. Egyszerűbb feladatokra érdemes a WebClient-et használni. az alkalmazásnak ez idő alatt nem szabad lefagyottnak tűnnie.Create("http://www. majd egy metódushívással közöljük. A létrehozott HttpWebRequest példánynak mindenképpen szerepelnie kell benne. így ezt az adatfolyamot még ki kell olvasnunk egy string változóba. mint a webszolgáltatások esetében. illetve a WebClient osztály. mert ettől a példánytól tudjuk majd elkérni a beérkezett HTTP választ. a megkapott válasz első 50 karakterét kiíratjuk a felhasználó számára egy üzenetdobozban. Ezek az osztályok nem telefonspecifikusak. mint egy absztrakciós réteg a HttpWebRequest/HttpWebResponse felett. hanem az interneten keresztül akarunk letölteni egy állományt.com"). mert talán ez a legjobb módja a használható technikák megismerésének. Kezdjük működésük megismerését az alacsonyabb szintű HttpWebRequest/HttpWebResponse párossal! Ezek segítségével az example. ezt az objektumot a meghívott callback függvény is megkapja. amely egy HttpWebResponse példányt hoz létre. Utána ezen a példányon meghívjuk az EndGetResponse() metódust. Hozzunk létre egy Windows Phone Application típusú projektet HttpSample néven.

Éles alkalmazásban célszerű lenne egy ProgressBar vezérlőelem segítségével tájékoztatni erről.EndGetResponse(ar).AsyncState. 50)). hogy a program épp dolgozik.ReadToEnd(). Dispatcher.Webes tartalom letöltése using System. programunk ezt beolvassa memóriába. majd az eseménykezelő paraméterei között készen megkapjuk a letöltött HTML oldalt egy string változó formájában. Amint láthattuk. Dupla kattintással nyissuk meg Click eseménykezelőjét! A WebClient osztály használata szintén aszinkron történik. HttpWebResponse response = (HttpWebResponse)request. A WebClient osztály alkalmazása ennél lényegesen egyszerűbb.BeginInvoke(() => { 225 . Az alábbiakat pedig gépeljük be a Click eseménykezelő alá: private void RequestCallback(IAsyncResult ar) { HttpWebRequest request = (HttpWebRequest)ar.DownloadStringAsync(new Uri("http://www. majd kiíratja az első 50 karakterét (9-5 ábra).example. Ehhez az alábbi kódra van szükségünk: private void WebClientButton_Click(object sender.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted). Egyszerűen feliratkozunk a kérés befejeződését jelző eseményre. de ennek modellje megegyezik a webszolgáltatásoknál már látottal. DownloadStringCompletedEventArgs e) { Dispatcher. Ennek használatát az előző fejezetrészben láthattuk.BeginInvoke(() => { MessageBox. }). hogy működik! Bővítsük ki alkalmazásunkat egy újabb gombbal! Ennek neve legyen WebClientButton. Teszteljük alkalmazásunkat! Egyszerűen indítsuk el az F5 gomb segítségével. } void client_DownloadStringCompleted(object sender.Substring(0. } Elkészültünk. client. Lássuk.IO. felirata pedig „WebClient”. a HttpWebRequest/HttpWebResponse osztályok használata meglehetősen nyakatekert. majd kattintsunk a „HttpWebRequest” gombra! Néhány másodperc elteltével beérkezik a HTTP válasz. client. 9-5 ábra: A beérkezett HTTP válasz első 50 karaktere A felhasználó nem értesült arról.Show(responseString. elindítjuk a kérést. RoutedEventArgs e) { WebClient client = new WebClient().GetResponseStream()). de segítségükkel alacsony szinten hozzáférünk a kommunikáció részleteihez.com")). most az egyszerűség kedvéért nem alkalmaztuk. string responseString = new StreamReader(response.

Ha egy RSS feed-et vagy egy HTML oldalt szeretnénk lekérni telefonalkalmazásunkból. frissítés (Update).. az eBay. míg ha az eBay katalógusra voltunk kíváncsiak.Substring(0.. hanem az OpenReadAsync() metódust. hogy legyen szó bármilyen adatforrásról. Ha az OData szolgáltatás címe például http://localhost:8080/owind. de kicsit máshogy kell kiadnunk a kéréseket. Ezeket hívják CRUD műveleteknek. Ez az információt fogyasztók számára teljesen lényegtelen. Hiába adott azonban az elvégezhető műveletek köre. egy XML fájl vagy akár egy szöveges fájl. A fenti két példában szöveges információt töltöttünk le a webről. Az OData definiál egy interfészt. annak adatait bármilyen platformról egységes módon lehet olvasni. } Teszteljük ezt is! Ismét indítsuk be az alkalmazást. a Categories gyűjtemény fizikailag bármi lehet..Result.svc/Categories Fontos észrevenni. Az egyszerűbb. azt is megtehetjük.. Aki ezt megteszi. ahol az URL tartalmazza az elvégezni kívánt műveletet. nem változnak a rajta elvégezhető műveletek. }). A WebClient-nél pedig ne a DownloadStringAsync() metódust használjuk. hogy a gyűjtemény teljesen általános fogalom.. akkor ahhoz ADO. ezt a módszert kell használnunk. Ha a helyi SQL Serverünket akartuk megcímezni.svc. Kommunikáció szerverrel MessageBox. akkor alkalmazzuk a HttpWebRequest/HttpWebResponse párost! Adatelérés az OData protokollon keresztül Az interneten vagy vállalatoknál számos olyan szoftver található.9. A HttpWebRequest már eleve egy Stream-et ad vissza. amitől adatrekordokat kérhetünk le. ugyanis a válasz szabványos XML-ben érkezik majd: <feed xml:base="http://localhost:8080/owind. a vállalati SharePoint-tól a különféle dokumentumokat. ha adatokat szeretnének lekérdezni – legyen szó akár adatbázisról. Ha valamiért finoman hangolni szeretnénk a kimenő HTTP kéréseket (például szükségünk van a HTTP fejlécekre is).NET-et használtunk. akkor valamilyen RSS feed-et próbáltunk letölteni.svc/" . <link rel="edit" title="Category" href="Categories(1)" /> . a SharePoint-hoz különféle osztálykönyvtárakkal fértünk hozzá. ezt tetszésünk szerinti objektumra konvertálhatjuk a memóriában. Az adatbázis-motoroktól például a bennük tárolt táblák sorait. Legyen szó bármilyen adatforrásról. Így a fejlesztőknek nem kell más és más technológiával kísérletezniük. az adatelérés ugyanazon a szabványos módon működhet. Az OData protokoll arra a gondolatra épül.> . a Netflix online filmnéző portálról a filmek listáját tölthetjük le. amellyel szintén egy Stream-et kapunk vissza! Ezzel megismertük az internetről való letöltés módszereit. kattintsunk a WebClient gombra! Néhány másodperc elteltével megjelenik a válasz első 50 karaktere. Ha egy képet vagy valamilyen más fájlformátumot szeretnénk letölteni. olvasás (Read). akkor az alábbi kéréssel kérdezhetjük le tőle a Categories nevű gyűjtemény tartalmát: http://localhost:8080/owind.Show(e. Állhat mögötte egy SQL tábla. akár egy vállalati projektről. az adatokon alapvetően négy műveletet tudunk végrehajtani: létrehozás (Create). és így tovább. <content type="application/xml"> 226 .. amit az adatforrások gazdái implementálhatnak.com-ról a megvásárolható termékek katalógusát. akár internetes boltról. törlés (Delete). 50)). sokáig más és más módon tudtunk csak hozzáférni az egyes adatforrásokhoz alkalmazásainkból. magától értetődő WebClient használata az esetek többségében megfelelő. vagy akár el is menthetjük a telefon Isolated Storage tárhelyére. Az OData előírásai szerint az adatforrásnak HTTP kéréseket kell fogadnia.. <entry> ..

1 vagy újabb verzióját! Az első lépésünk. és támogassa a Windows Phone OS 7. Mac vagy akármilyen egyéb eszköz. akár az előző fejezetrészben megismert HttpWebRequest osztállyal kiadhatunk nyers HTTP kéréseket. </feed> Minden CRUD művelethez definiáltak a fentihez hasonló. amely az OData osztálykönyvtár igénybevételével beolvassa az eBay. a rekordokat pedig C# osztályok képében kapjuk meg. Ahogy a fejezetben már többször. beers. a Visual Studio felismeri.</d:Picture> </m:properties> </content> </entry> . hogy felveszünk egy referenciát az OData végpontra. hogy akár egy böngésző segítségével. (És ez adja egyben az OData platformfüggetlenségét – HTTP kéréseket gyakorlatilag bármilyen platformról indíthatunk. Az OData megismeréséhez egy mintaalkalmazást készítünk. és válasszuk az Add Service Reference parancsot! A cím mezőbe írjuk be az eBay OData végpontjának címét: http://ebayodata.. and ales</d:Description> <d:Picture m:type="Edm.Adatelérés az OData protokollon keresztül <m:properties> <d:CategoryID m:type="Edm.Int32">1</d:CategoryID> <d:CategoryName>Beverages</d:CategoryName> <d:Description>Soft drinks. Így számos platformra.cloudapp. melyekre az OData adatforrás válaszolni fog. többek között a Windows Phone-ra is készült OData kliensoldali osztálykönyvtár. legyen az Windows. a Namespace mezőben pedig nevezzük el a referenciát Ebay-nek! Amint a 9-6 ábrán is látható.Binary">FRwvAAI. Amint láthattuk. 9-6 ábra: Referencia felvétele az OData végpontra 227 . kódunkból tudjuk manipulálni az adatforrást. Ehhez (a korábban már látott webszolgáltatásokhoz hasonlóan) kattintsunk a projekt nevére a Visual Studióban. az OData fogyasztók pedig ezeket használhatják.... teas. Ez azt jelenti. Az osztálykönyvtár segítségével nem kell a nyers HTTP kérésekkel bajlódnunk. coffees.net/. Linux.com aktuális akcióit. objektumorientált módon. Az OData szolgáltatóknak ezeket kell megvalósítaniuk.) Ez azonban kényelmetlen. nyissunk egy új Windows Phone Application típusú projektet! Legyen ennek neve ODataSample. az URL részeként kiadható parancsokat. hogy ez nem hagyományos webszolgáltatás. az OData adatforrásokat egyszerű HTTP kérésekkel tudjuk lekérdezni. hanem adatszolgáltatás (lásd a panel jobb oldala).

Ha akarnánk. Ezután létrehozunk egy LINQ lekérdezést. Kommunikáció szerverrel Az OK gomb megnyomása után a Visual Studióhoz készült OData könyvtár legenerálja a végpont eléréséhez szükséges osztályokat.EBayData context. Az általunk megadott LINQ lekérdezés nem tartalmaz szűrőfeltételt. valamint egy EBayData nevű kontextusosztály is generálódik. A két változót több metódusból is szeretnénk majd használni. Ez a gyűjtemény kezdetben üres. az összes Deal típusú objektumot lekéri. Ennek a példánynak létrejöttekor átadjuk a megcímzendő szolgáltatás URL-jét.EBayData(new Uri("http://ebayodata. programunk futása során ezt fogjuk feltölteni a szerveroldalról lekérdezett rekordokkal.Deal>(context). Ennek a példánynak a kontextusra (az EBayData típusú változó példányára) adunk át egy referenciát.cloudapp. majd létrehozunk egy példányt a korábban deklarált Deal típusú objektumokat tartalmazó gyűjteményből is. Az EBayData típusú változó biztosítja a szolgáltatás megszólításához szükséges metódusokat. A feltöltést közvetlenül az alkalmazás indulásakor elkezdjük. amelyekkel a kódból megszólíthatjuk az OData szolgáltatást. nyers HTTP kérésekkel és a visszaérkező XML válaszok feldolgozásával is kommunikálhatnánk a végponttal. Az ismétlés kedvéért: ezek a generált objektumok kizárólag a fejlesztő kényelmét szolgálják. A DataServiceCollection<Ebay. mint az OData által támogatott műveletek halmaza. így tudja majd.xaml. Az eBay által kínált minden objektumtípushoz (pl. így deklarációjukat közvetlenül a public partial class MainPage : PhoneApplicationPage sor (és az azt követő nyitó kapcsos zárójel) után helyezzük el: Ebay. 228 . deals = new DataServiceCollection<Ebay. Bidders. context = new Ebay. var query = from deal in context. A LINQ eszközeivel definiálhatunk különféle szűrőfeltételeket.net/")). Most készítsük el a szolgáltatás megszólításához szükséges kódot! Ehhez szükségünk lesz egy névtérre.Data. A feladat elvégzéséhez két fontos változót kell deklarálnunk. így a kódot közvetlenül a public MainPage() konstruktorban helyezzük el.Deal> deals. hogy a deals gyűjteménybe mit szeretnénk betölteni a szerveroldalról. melyet a MainPage. melyeket az OData könyvtár fordít le az OData által elvárt URL-szintaxisra. DataServiceCollection<Ebay. amellyel megadjuk.Client. Deals) készül egy-egy osztály. A következő feladatunk a deals gyűjtemény feltöltése az OData végpontról lekérdezett objektumokkal.9. Items. public MainPage() { InitializeComponent().Deal> nevű változó pedig egy Deal típusú objektumokat tartalmazó gyűjteményt képvisel. Ez a kontextusosztály rendelkezik majd azokkal a műveletekkel. rendezéseket. hogy egy érvényes LINQ lekérdezés futásidejű hibát dob. majd kiadjuk az utasítást a deals gyűjtemény feltöltésére az általunk megadott LINQ lekérdezés szerint. így előfordulhat. Végül a korábban már látott módon feliratkozunk a lekérdezés befejezését jelző eseményre. Az OData végpont megszólításához elsőként létrehozunk egy példányt az EBayData nevű osztályból. A generált osztályok ezeket a feladatokat végzik el helyettünk.Services.Deals select deal.cs kódfájl tetején helyezzünk el! using System. hogy honnan kell az adatokat lekérnie. A LINQ eszköztára bővebb.

Ha úgy találjuk.LoadCompleted += new EventHandler<LoadCompletedEventArgs>(deals_LoadCompleted). mert ez a metódus is a deals_LoadCompleted eseménykezelőt hívja meg. ami több megabájtnyi XML-be férne csak bele). Hozzuk létre a deals_LoadCompleted metódust az alábbi kóddal: void deals_LoadCompleted(object sender. Így ha a lekérdezés sok eredményt adna vissza.LoadNextPartialSetAsync(). foreach (var deal in deals) message += deal.Show(e. és a visszaadott objektumok betöltődnek a deals gyűjteménybe.ebay. hogy a megfelelőket töltöttük-e le. hogy valóban az épp elérhető akciókat kérdeztük le (9-7 ábra). LoadCompletedEventArgs e) { if (e. A deals_LoadCompleted eseménykezelő meghívásakor lekérdezésünk lefut.Title + Environment.Error != null) { if (deals. } } Ezzel elkészültünk. így lekérdezésünk addig fut. Valamennyi rekordot szeretnénk lekérdezni. akkor egy üzenetdobozban kiíratjuk az aktuális eBay akciók címeit. programunknak nem kell megvárnia. majd a válaszban jelzi. akkor a LoadNextPartialSetAsync() hívással az eredményhalmaz következő szeletét is letölti. MessageBox. amíg a teljes adathalmaz megérkezik (ez sok ezer rekordot is jelenthet. } } else { MessageBox. Ehhez nem kell új eseménykezelőt felvennünk. Az eBay honlapján ellenőrizhetjük is.LoadAsync(query). Ehelyett a protokoll ilyenkor az első néhány rekordot adja át. deals. } Az OData protokollt felkészítették a nagyméretű adathalmazokra. hogy még vannak betöltetlen rekordok az adatforrásban. 229 .Continuation != null) { deals.NewLine.ToString()). amíg minden objektum meg nem érkezik a szerverről. A http://deals. és kisvártatva megjelennek az aktuális eBay akciók. ezért ha kódunk azt érzékeli. hogy még van további része is az eredményhalmaznak. Az esetleges hibát pedig természetesen kezeljük. A fent említett mechanizmus miatt azonban előfordulhat. hogy a lekérdezés még folytatható. } else { string message = "". Teszteljük alkalmazásunkat! Indítsuk el az F5-tel.Adatelérés az OData protokollon keresztül deals.com/ honlapot megnyitva láthatjuk.Error. hogy minden objektum megérkezett.Show(message).

illetve feltölthetünk egyszerű táblajellegű információkat. valamint a protokollal kapcsolatos részletes információk és a fórum. az eBay. az látogasson el a http://www. egymástól több száz kilométerre lévő adatközpontba is szétmásolja. hogy mindhárom tárhelyszolgáltatás alkalmas komoly. a SharePoint. Mindhárom szolgáltatásra igaz. Ez utóbbi nem váltja ki az SQL szervert. Adattárolás Windows Azure-ban Internetre kapcsolt telefonalkalmazásunknak gyakran szüksége lehet saját fájlok és egyéb adatok tárolására. ráadásul egyszerű objektumorientált API-n keresztül. A webszolgáltatásokhoz hasonlóan az OData is rendkívül széles témakör. így a véletlen adatvesztés gyakorlatilag kizárt. a Netflix és még sokan mások. Ismerjük meg ezeket részletesebben! 230 .odata. Aki szeretné jobban megismerni az OData protokollt. Ebben a részben a Windows Azure tárhelyszolgáltatásának elemeit és ezek használatát ismerjük meg − egy Windows Phone alkalmazásból. mint pl. Ennél azonban sokkal egyszerűbb és olcsóbb megoldást is alkalmazhatunk: a Windows Azure tárhelyszolgáltatását kihasználva néhány száz forintért tárolhatunk gigabájtokat. egy telefonkönyv (Table Service). Az Azure emellett komoly kötelezettségeket vállal a szolgáltatás rendelkezésre állására is. Kommunikáció szerverrel 9-7 ábra: Az OData-n keresztül letöltött objektumok és az eBay honlapja Ezzel megismertük az OData használatának alapjait. Így elmondhatjuk. létrehozhatunk benne aszinkron kommunikációra alkalmas várakozási sorokat (Queue Service). amint később azt látni fogjuk. Érdemes megismerkedni a protokollal. Ezeket az igényeket természetesen megoldhatjuk egy saját szerverrel. Az itt megtanultak alapján már tudunk egy ODatafogyasztásra képes alkalmazást készíteni.org weboldalra. melyre alkalmazásunk egy webszolgáltatáson keresztül tölti fel az anyagokat. professzionális alkalmazások kiszolgálására is. ráadásul két. hogy az Azure a feltöltött adatokat három példányban tárolja. ahol megtalálható az OData-szolgáltatók és a különféle platformokra elérhető OData kliensek folyamatosan bővülő listája.9. Az Azure Storage háromféle szolgáltatást nyújt: tárolhatunk benne fájlokat (Blob Storage). mert rengeteg Microsoft-termék és számos külső gyártó már most támogatja! Ilyen például az SQL Azure.

Storage Accounts & CDN fülre. és mellette a View gombot. majd válasszuk a Storage Accounts listaelemet (9-8 ábra)! Ekkor megjelennek az előfizetéshez tartozó Azure Storage tárhelyek. ezekre lesz majd szükségünk a tárhely programozásához.Adattárolás Windows Azure-ban Fájlok (blob-ok) A Blob Storage gyakorlatilag egy fájlszerver a felhőben. A fájlok méretének felső korlátja egy terabájt (1 TB). akár mappákba rendezve is. Ehhez szükség van egy Azure előfizetésre. A konténerekbe pedig tetszőleges mennyiségű fájlt feltölthetünk. de ez az emulátor csak PC-n futtatható. a felhőben lévő tárhelyet kell megcímeznünk. Az előfizetésünkön belül hozzunk létre egy Azure Storage tárhelyet! Ehhez látogassunk el az Azure portálra (http://windows.azure. Mindegyik konténerre úgy gondolhatunk.microsoft. A feltöltött fájlokat később URL-jük alapján a telefonról vagy az internetről is elérhetjük.com/windowsazure/offers/ oldalon juthatunk hozzá − gyakran van ingyenes kipróbálási lehetőség is. Azure előfizetésünkhöz úgynevezett konténereket hozhatunk létre. így telefonalkalmazásunkból egy valódi. 9-8 ábra: Az Azure menedzsment portál. a jobb felső sarokban találjuk a Primary access key sort. Most készítsük el mintaalkalmazásunkat! 231 . A New Storage Account gomb segítségével hozzuk létre tárhelyünket! Ennek során kell megadnunk a tárhely nevét. Erre kattintva tekinthetjük meg a tárhelyhez tartozó két automatikusan generált jelszót. Az Azure kínál ugyan egy emulátort. Ilyen előfizetéshez a http://www. Miután létrejött.com). mint egy merevlemez egy partíciójára. A fejezetben megszokott módon egy mintaalkalmazáson keresztül ismerjük meg az Azure Storage használatát. majd jelentkezzünk be az előfizetéskor megadott Live ID azonosítónkkal! A bal alsó sarokban kattintsunk a Hosted Services. benne tárhelyeinkkel A tárhely nevét és egyik jelszavát tároljuk el.

Miután ezzel elkészültünk.1 vagy újabb operációs rendszer verziót használva! A Toolkit osztályainak használatához vegyünk fel egy referenciát a WindowsPhoneCloud. hogy egyszerű HTTP kérésekkel parancsokat tudunk kiadni. mert később még többször szükségünk lesz rá.codeplex. a Blob Storage használatának előfeltétele. vagy alkalmazásunkon belül különböző felhasználóink is kaphatnak külön-külön konténert. a háttérben zajló HTTP kéréseket az osztályok eltakarják előlünk. befejezni csak egy másik metódusból fogjuk. Ennek a mappának a helyét szintén jegyezzük meg. Ez azt jelenti. Ez szolgál majd a konténerek létrehozására. Ez azonban kényelmetlen. Így itt először is példányosítunk egy CloudBlobContainer típusú osztályt. Kommunikáció szerverrel Az Azure tárhely rendelkezik egy REST-es menedzsment felülettel. Most adjunk értéket a credentials változónak! Ezt célszerű a program indulásakor. A Toolkit telepítése után készítsünk egy új Windows Phone Application projektet AzureStorageSample néven. hogy létrehozzon magának egy konténert (ha ezt korábban még nem tette meg). BlobButton néven. Ezért a használt változóinkat nem a metóduson belül deklaráljuk.WindowsPhoneCloud. Kattintsunk duplán a BlobButton gombra.9. hanem a program törzsében. Töltsük ezt le a CodePlex-ről. Amint korábban volt róla szó. "JELSZÓ"). mert később szükségünk lesz majd rá! A szerveroldali programozáshoz készült Windows Azure SDK természetesen szintén tartalmaz kész osztályokat az Azure Storage eléréséhez.xaml.Text.cs kódfájl legtetejére: using using using using Microsoft. „Blob feltöltése” felirattal! Erre a gombra kattintva alkalmazásunk feltölt majd a felhőbe egy példafájlt. nekünk csak ezek metódusait kell hívni. Az itt tárgyalt Windows Phone alapú osztályok hasonlítanak ezekre.StorageClient. 232 . a http://watwp. CloudBlobClient blobClient. a JELSZÓ helyére pedig a tárhely jelszavát (amit lementettünk az Azure menedzsment portálról). CloudBlobContainer container.com/ URL-en érhető el! Telepítése során a fájlokat egy általunk meghatározott mappába helyezi. így készült hozzá egy osztálykönyvtár. alkalmazásunk felületére vegyünk fel egy gombot. így a gombra kattintva a kérés csak elindul. credentials nevű változóban tároljuk el a tárhely megcímzéséhez használt nevet és jelszót. Az Azure osztályok – a fejezet korábbi részeiben tárgyalt okokból – aszinkron működésűek. Az értékadáshoz írjuk az alábbiakat a public MainPage() konstruktor InitializeComponent() sora alá: credentials = new StorageCredentialsAccountAndKey("TÁRHELYNÉV". Az első. egyszer megtenni.Samples.Credentials. Ilyen konténerből tetszőleges számúval rendelkezhetünk.IO. Microsoft.Samples. Alkalmazásunk első lépése. A TÁRHELYNÉV helyére írjuk a tárhely nevét (amit létrehozáskor megadtunk). A két másik változó pedig a Blob storage használatához kell. Ez az osztálykönyvtár a Windows Azure Toolkit for Windows Phone része.StorageClient. System. ám némileg más logikát alkalmaznak. hogy belépjünk Click eseménykezelőjébe! A korábban említett REST-es API-t egy sor osztály fedi le. Windows Phone OS 7. így különböző alkalmazásaink. Helyezzük a következő sorokat a public partial class MainPage : PhoneApplicationPage sor (és az azt követő kapcsos zárójel) alá: StorageCredentialsAccountAndKey credentials.dll könyvtárra! Ezt a Toolkit mappája alatt a Binaries mappában találjuk.StorageClient. System.WindowsPhoneCloud. A szükséges névterek importálásához helyezzük el a következő sorokat a MainPage. hogy létrehozzunk benne fájljaink számára egy konténert.

core.Upload("test. a felhasználó által az internetről letöltött állományt vagy bármi mást is fel tudunk tölteni Blob Storage-ba.txt". így befejeződése után valahogy folytatnunk kell kódunk futtatását. a konténer neve pedig legyen phonetest1! container = new CloudBlobContainer(credentials). BlobUploadedCallback).Begin). A Stream egy általános célú változótípus. StreamWriter streamWriter = new StreamWriter(memoryStream). Ennek egyrészt tartalmaznia kell tárhelyünk nevét. CloudBlobContainerCreated). akkor folytatjuk feladatunkat: feltöltünk egy blob-ot. A CloudBlobContainer példány létrehozása után egy metódus segítségével megindítjuk az alkalmazásunk által használni kívánt konténer létrehozását. hogy az melyik konténerrel dolgozzon (a fenti URL-t kell itt is használnunk).Seek(0.core. hanem a metódushívásban átadunk paraméterként egy callback függvényt. így a most létrehozott CloudBlobContainer példánynak egyszerűen csak ezt kell átadnunk. Aszinkron metódust hívtunk. így megvizsgálja. } A blob feltöltése is egy aszinkron művelet. Ha nem.Dispatcher. } }). Írjuk az alábbi kódot a gomb Click eseménykezelője alá: private void CloudBlobContainerCreated(CloudOperationResponse<bool> returnValue) { this.Exception. ha még nincs ott.windows.net/phonetest1").net/phonetest1".WriteLine("Hello!").blob.windows. memoryStream. streamWriter. blobClient. SeekOrigin. és csak akkor próbálkozik meg létrehozásával.Exception == null) { MemoryStream memoryStream = new MemoryStream(). streamWriter. Tárhelyünk nevét helyettesítsük be. Ennek létrehozásakor megadjuk.CreateContainerIfNotExist(new Uri("https://TÁRHELYNÉV. A használt metódus intelligens. hogy létezik-e már az adott konténer. így egy második callback függvényt is készítenünk kell.BeginInvoke(() => { if (returnValue.blob.net). amelybe beleírunk néhány betűt. másrészt egy kötelező elemet (blob. memoryStream. valamint átadjuk neki a hitelesítési információkat. Paraméterként át kell adnunk a kívánt konténer URL-jét. Ha igen. így éles alkalmazásban egy képet.Show(returnValue. Ezeket az adatokat már eltároltuk a credentials nevű osztályba. Utána pedig egy metódushívással elvégezzük a feltöltést. ezért létrehozunk egy MemoryStreamet. Ennek már mindössze annyi feladata van. melyet a metódus majd meghív befejezésekor.Flush().windows. hogy történt-e hiba a végrehajtás során. blobClient = new CloudBlobClient( "https://TÁRHELYNÉV. Következő feladatunk a callback függvény megírása. Ehhez egy CloudBlobClient nevű objektumot használunk.Adattárolás Windows Azure-ban A menedzsment API hívásához osztályainknak rendelkezniük kell a szükséges hitelesítési adatokkal.core. Ezúttal nem egy eseményre iratkozunk fel.ToString()). credentials). container. A feltöltendő adatot egy Stream típusú változóban várja az osztály. 233 . harmadrészt a konténer elvárt nevét. akkor erről értesítjük a felhasználót. } else { MessageBox. A függvényben megvizsgáljuk. hogy tájékoztassa a felhasználót a feltöltés kimenetéről (sikeres vagy sikertelen). Ez a callback függvény a fent látható CloudBlobContainerCreated.

Show(returnValue. A myazurestorage.Dispatcher.9.Exception. amit kibontva ellenőrizhetjük.com honlap használata.Exception == null) { MessageBox. 9-9 ábra: A létrehozott konténer és blob Ezzel megismertük a Blob Storage használatának alapjait. hogy test. } Teszteljük alkalmazásunkat! Az F5 gombbal futtassuk. Várakozási sorok (queue-k) Következő Storage elemünk a várakozási sor.txt fájlunk valóban létrejött-e (9-9 ábra).com weboldalt a Microsoft fejlesztette. Itt meg kell adnunk tárhelyünk nevét és jelszavát. Talán a legegyszerűbb a http://www. Ellenőrizzük ennek megtörténtét! Ehhez valamilyen eszközzel rá kell csatlakoznunk a Blob Storage-ra. Természetesen a szolgáltatás képességeinek és a használható API-nak csak egy nagyon kis részét láttuk. majd egy webes felületen böngészhetjük a Blob Storage tartalmát. Kommunikáció szerverrel private void BlobUploadedCallback(CloudOperationResponse<bool> returnValue) { this. nem kell jelszavunk ellopásától tartanunk.ToString()). Az Azure várakozási sor kisméretű (maximum 64 kilobájtos) üzenetek megbízható kezelésére alkalmas. vagyis a Queue Service.BeginInvoke(() => { if (returnValue. hogy tetszőleges számú egyszerre működő termelővel és fogyasztóval megbirkózik. de ennek alapján már el tudunk készíteni egyszerű alkalmazásokat.myazurestorage. kapacitása pedig gyakorlatilag korlátlan. Előnye. A Blob Storage nyújtotta lehetőségekről és a Windows Phone által támogatott API-ról bővebben olvashatunk az Azure és a Windows Azure Toolkit for Windows Phone honlapjain. 234 .Show("Blob feltöltve!"). A BLOBs fülre kattintva megtaláljuk a phonetest1 konténert. } }). majd nyomjuk meg a „Blob feltöltése” gombot! Alkalmazásunk a háttérben létrehozza a konténert és feltölti a tesztfájlt. } else { MessageBox. így megbízhatunk benne.

Ha ügyelünk arra. hogy történt-e hiba. } A callback függvényben nincs más dolgunk. CloudQueue queue. Blob Storage-ba). majd elhelyezünk benne egy üzenetet. Dupla kattintással lépjünk be Click eseménykezelőjébe! Első dolgunk a sor létrehozása lesz.windows.Show(returnValue.core. mellyel egy sort hozunk létre. így kódunk egy callback függvényben folytatódik majd.Exception.Adattárolás Windows Azure-ban Egy ügyes mechanizmussal gondoskodik arról. Mivel a hibás egység sosem jutott el odáig. akkor beírni egy üzenetet a sorba. queue. }). ha még nem létezik. RoutedEventArgs e) { queueClient = new CloudQueueClient("https://TÁRHELYNÉV. A kivett üzenetek bizonyos időre virtuálisan eltűnnek a sorból (alapértelmezésként 10 percre. CloudQueueMessageAddedCallback). nagyméretű fájlokat és egyéb adatokat máshová célszerű helyeznünk (pl. } 235 . valamint a korábban eltárolt hitelesítési adatainkat.Dispatcher.AddMessage(message. } else MessageBox. egyedileg elnevezett sort hozhatunk létre. A Windows Phone-hoz készült API csak bájttömb beírását teszi lehetővé. private void QueueButton_Click(object sender. queue = (CloudQueue)queueClient. ezért létrehozunk egy szöveget. akár szöveges.CreateIfNotExist(CloudQueueCreatedCallback). felirata pedig „Queue üzenet létrehozása”. credentials). „videót kell konvertálni”).Exception == null) { CloudQueueMessage message = new CloudQueueMessage() { AsBytes = Encoding. A feladatok végrehajtásához szükséges.GetQueueReference("phonetest1"). ezekre az üzeneten belülről egy URLlel hivatkozhatunk. és mindegyik sorba külön-külön pakolhatunk üzeneteket. queue.GetBytes("Hello") }. amíg azok sikeresen feldolgozásra nem kerültek. Véglegesen törölni csak egy külön utasítással lehet. de ez az időtartam feljebb is vehető). ezért az kis idő elteltével újra megjelenik. hogy a sorba kerülő üzenetek addig ne törlődjenek. akkor egy hibára futó feldolgozóegységnél az üzenet nem vész el. Most hozzuk létre a gombot! Annak neve legyen QueueButton. Utána ettől az objektumpéldánytól kérünk egy referenciát egy phonetest1 nevű sorra. hogy törölje az üzenetet. és ha nem.UTF8. amit egy metódushívással létrehozunk. A sorban lévő üzeneteket ugyanis először csak kivesszük.ToString()). Ehhez szükségünk lesz néhány osztályszintű változóra. Ehhez egy CloudQueueClient objektumot készítünk. és egy másik egység újra megpróbálkozhat a feldolgozásával. Ennek átadjuk a Queue szolgáltatás URL-jét. Az üzenetek tartalma tetszőleges formátumú lehet.queue. mint ellenőrizni. A meghívott metódus aszinkron. Az üzenetek méretére vonatkozó korlát szándékos: a várakozási sorban csak a feladatok leírását kell tárolnunk (pl.net". illetve akár egy bájttömb is. A Queue szolgáltatás felépítése hasonlít a Blob Storage felépítéséhez: Azure tárhelyünk alá tetszőleges számú. Helyezzük az alábbi sorokat a MainPage osztály tetejére: CloudQueueClient queueClient.BeginInvoke(() => { if (returnValue. A Blob Storage-hoz készült példaalkalmazásunkat kiegészítjük egy újabb gombbal. hogy az üzeneteket csak sikeres feldolgozásuk után töröljük. amint bájttömbbé konvertálva helyezünk el egy üzenetben: private void CloudQueueCreatedCallback(CloudOperationResponse<bool> returnValue) { this.

és nyomjuk meg a QueueButton gombot! A Blob Storage példához hasonlóan most is a myazurestorage. és minden tábla felveszi a belerakott objektumok sémáját. Egy táblába többféle objektumot is beletehetünk.Exception.com segítségével ellenőrizhetjük. de a táblában minden objektum minden tulajdonságához létrejön egy-egy oszlop. hogy üzenetünk valóban létrejött-e. Tárhelyünk alatt tetszőleges számú.BeginInvoke(() => { if (returnValue. dátum típusú mezőt. A táblákhoz nem kell sémát rendelnünk – azaz nem kell őket megterveznünk.Show(returnValue. vagyis több mezőből álló adatsorokat tárolhatunk. és a Dog objektumnak Name és Age tulajdonsága van.Exception == null) { MessageBox. Itt mindössze értesítjük a felhasználót a művelet eredményéről. private void CloudQueueMessageAddedCallback(CloudOperationResponse<bool> returnValue) { this. akkor a táblában automatikusan létrejön egy Name és egy Age típusú oszlop. Kommunikáció szerverrel Az üzenet létrehozása természetesen szintén aszinkron. Ezeket nem kell kézzel beraknunk azokba az 236 . ha az üzenet időbélyegzője néhány órával korábbi vagy későbbi.Show("Üzenet létrehozva!"). } Teszteljük alkalmazásunkat: indítsuk el. mint a magyar idő –a weboldal az Azure adatközpont helyi idejét jeleníti meg. ami érdekes ütközéseket és hibajelenségeket okozhat. Vagyis ha egy Dog típusú objektumot helyezünk egy táblába. Ismét látogassunk el az oldalra! A Queues fülön megtaláljuk a phonetest1 várakozási sort és benne az imént létrehozott üzenetünket (9-10 ábra).Dispatcher. } else { MessageBox. 9-10 ábra: A létrehozott várakozási sor és üzenet Táblák (table-k) Az Azure Storage harmadik eleme az Azure Table Service.9.ToString()). Itt strukturált. Ne lepődjünk meg. táblaszerű információt. ezért feladatunkat egy újabb callback függvényben fejezzük be. } }). így ezt inkább kerüljük! A táblába helyezett objektumoknak tartalmazniuk kell egy PartitionKey és egy RowKey nevű szöveges mezőt és egy Timestamp nevű. Objektumokat helyezhetünk beléjük. egyedileg elnevezett táblát hozhatunk létre.

Ha ezzel nem akarunk bajlódni. és az Add almenüből válasszuk a Class menüpontot! Új osztályunkat nevezzük SampleData-nak! Miután létrejött. de ne az Add Reference dialógus .dll fájlra. tárolt eljárásokat. Int32.NET alaptípusok közül sem mindet (pl. táblánként több millió adatsort is eltárolhatunk.Data. A táblába helyezett objektumokat entitásoknak nevezzük.NET füléről válasszuk ki. Vegyünk fel egy referenciát a System. mint egy SQL szerveré. hogy nem relációs. általunk definiált osztályokat) nem használhatunk. a Float adattípust nem). vagy éppenséggel sok millió. A fenti korlátozások jelen sorok írásakor aktuálisak voltak.StorageClient. Egészítsük ki példaprogramunkat Azure Table Service támogatással! Térjünk vissza a Visual Studióba és hozzunk létre egy új gombot az alkalmazás felületén! A neve legyen TableButton. mint pl.Samples. hogy rendkívül olcsó.Client. az azonos PartitionKey értékkel rendelkező entitásokat fizikailag egymáshoz közel tárolja. Az osztály tetejére írjuk a következő sort: using Microsoft. akkor ezt a feladatot néhány forintért ellátja a Table Service. A kettőnek együttesen egyedinek kell lennie. minden objektumnak lehet különböző PartitionKey értéke is. Egy entitás teljes mérete 1 megabájt lehet. Komplex vagy saját típusokat (azaz listákat. Egy népszámlálás adatsorainál a PartitionKey érték lehet például az illető városa. idegen kulcsokat. de egyszerű adatsort kell tárolnia. amiket táblában szeretnénk tárolni – elég leszármaztatni osztályainkat a TableServiceEntity ősosztályból. le kell származtatnunk azt a TableServiceEntity ősosztályból. A későbbiekben leírt árazásból láthatjuk majd. egy CMS rendszernél vagy egy banki alkalmazásnál viszont egyértelműen a SQL Azure a megfelelő választás. az Azure Table Service-be osztályok példányait tudjuk feltölteni. hogy óriási táblaméreteket támogat. és így tovább. és a . A PartitionKey és a RowKey azonban fontos! A táblákban mindössze ezen a két mezőn van index (a többire nem is rakhatunk).Adattárolás Windows Azure-ban osztályokba. és ha város alapján keresünk vissza entitásokat. mert nekünk a DLL 4. Double.Services. A Table Service előnye. azaz képességei lényegesen szerényebbek. hanem a Browse fül segítségével tallózzuk ki a Toolkit mappája alatt található Binaries mappából! Ez azért szükséges.0-s verziója kell. Másik előnye.WindowsPhoneCloud. azaz tábláinkra nem vehetünk fel plusz indexeket. A jellemzők legfrissebb listája mindig az MSDN-en olvasható. A PartitionKey értékét a skálázásban használja az Azure. majd fel kell vennünk bele néhány tulajdonságot. hogy néhány száz forintból hatalmas adatbázisokat tarthatunk fenn! Hátránya viszont. Guid vagy String).NET alaptípusok lehetnek (pl. Hozzunk létre egy erre szánt osztályt! Jobb gombbal kattintsunk a projekt nevére a Solution Explorer ablakban. míg a Browse fülön a 2. Ha programunknak egy High Score listát kell nyilvántartania. Egy bonyolult adatstruktúrát alkalmazó programnál. Amint korábban láttuk. a RowKey értéke pedig az illető személyi száma. másféle feladatkörökre érdemes alkalmazni őket. Boolean. Ezek típusai alapvetően a . A RowKey nem hordoz ilyen jelentést. akkor nagyon gyorsan tudunk haladni. Így a kettő együtt garantáltan egyedi (sőt a RowKey akár önmagában is). így a logikailag összetartozó adatokat érdemes azonos PartitionKey értékkel ellátni. A táblába rakott entitásoknak a három kötelező mezőn kívül maximum 252 általunk megadott mezője lehet. felirata pedig „Table sor hozzáadása”! A Table Service használatához szükségünk van továbbá még egy DLL fájlra. A Timestamp mezővel semmi dolgunk. azt az Azure kezeli. ám az Azure többi szolgáltatásához hasonlóan a Table Service is folyamatosan fejlődik.0 verziót találnánk. A Table Service és a SQL Azure tehát nem versenytársak. Az osztály tartalma pedig legyen a következő: 237 .

private void TableCreatedCallback(CloudOperationResponse<bool> returnValue) { this.CreateTableIfNotExist("phonetest1".NewGuid(). } A táblamentés természetesen aszinkron történik.Dispatcher. tableContext. tableClient = new CloudTableClient(tableContext).Show("Táblasor hozzáadva!")). } public int Age { get.NewGuid().ToString()). } else { MessageBox.Exception == null) { SampleData sampleData = new SampleData(). 238 .Name = "Demo".AddObject("phonetest1". sampleData.BeginInvoke(() => MessageBox.net". hogy a PartitionKey és a RowKey értékek egyediek legyenek. tableContext. sampleData. Ezután dupla kattintással lépjünk be a TableButton gomb Click eseménykezelőjébe! Az előző mintapéldákban látottakhoz hasonlóan először létrehozunk egy TableServiceContext osztályt a megfelelő hitelesítési adatokkal.ToString(). sampleData.Show(returnValue.9. Ekkor történik meg a tényleges kommunikáció a szerverrel. RoutedEventArgs e) { tableContext = new TableServiceContext("https://TÁRHELYNÉV.cs fájlhoz! Szükségünk lesz néhány újabb osztályszintű változóra.Age = 10.BeginInvoke(() => { if (returnValue. a többi változódeklaráció alá! CloudTableClient tableClient. } }).RowKey = Guid. A művelet befejezése után értesítjük a felhasználót: private void TableContextSaved(IAsyncResult result) { try { var response = tableContext. ezeket vegyük fel a kódfájl tetejére. credentials).EndSaveChanges(result).table. } } Most térjünk vissza a MainPage.Dispatcher.xaml.windows. tableClient. private void TableButton_Click(object sender. set. majd ezzel aszinkron módon létrehozatunk egy táblát. set. ITableServiceContext tableContext.Exception. this. sampleData.ToString().BeginSaveChanges(TableContextSaved. } A callback metódusban létrehozunk egy példányt a SampleData osztályunkból. TableCreatedCallback). Majd (az Entity Frameworkhöz és a LINQ to SQLhez hasonló módon) felvesszük az entitást a táblába. és elmentjük a változásokat. Kommunikáció szerverrel public class SampleData : TableServiceEntity { public string Name { get.PartitionKey = Guid. Ügyelünk arra. null).core. sampleData).

} } Teszteljük az alkalmazást! Indítsuk el. kattintsunk rá a „Table sor hozzáadása” gombra. Árazás A Windows Azure platform fontos jellemzője. semmiféle belépési költséggel vagy járulékos összeggel nem kell számolnunk – kizárólag azt kell fizetnünk. benne egy partíciót (amit egyetlen feltöltött entitásunk PartitionKey értékéből számolt az oldal). Jelen sorok írásakor a tárhelyszolgáltatás árai a következők:  A feltöltés ingyenes.  Egy gigabájt adat letöltése: 15 dollárcent. Így ha használni szeretnénk valamelyik tárhelyszolgáltatást.ToString())). a teljes API az Azure és a Toolkit honlapjain ismerhető meg. A Queue és Blob szolgáltatáshoz hasonlóan a Table Service képességeinek is csak egy töredékét fedtük le. Az Azure árazása folyamatosan változik.Adattárolás Windows Azure-ban } catch (Exception ex) { this.BeginInvoke(() => MessageBox.  Egy gigabájt adat tárolása (legyen az sor. és azon belül az elmentett entitásunkat (9-11 ábra).  10 ezer elemi írási/olvasási művelet: 1 dollárcent. és jellemzően egyre olcsóbb lesz. 9-11 ábra: Entitásunk a Table Service-ben Ezzel megismertük az Azure Storage harmadik szolgáltatását is. 239 .com/windowsazure/pricing/. tábla vagy fájl) egy hónapig: 14 dollárcent. majd a már látott módon nyissuk meg a myazurestorage.Dispatcher. A fenti adatok kizárólag tájékozató jellegűek! Az Azure aktuális árazását a következő honlapon találjuk: http://www. hogy szolgáltatásait önállóan is igénybe vehetjük. A Table Service segítségével költséghatékony. amit használunk.com oldalt! A Tables fülön megtaláljuk majd a phonetest1 táblát.microsoft. rendkívül skálázható módon tárolhatunk táblajellegű információkat.Show(ex.

hogy ez csak néhány mező kitöltését és egy gyors e-mailes hitelesítést igényel. Azure Storage használatáról szóló fejezetrész után már mindkettővel rendelkezünk. így fejlesztői szempontból nehéz a feladat. hogy ezt elkerüljük. hogy az Azure táblák és várakozási sorok árazása megegyezik a fájlok árazásával – ebből a havi pár száz forintból egy több gigabájtos adatbázist vagy várakozási sort is fenntarthatunk a Table Service és Queue Service használatával. Az előző. garantált rendelkezésre állás és adatbiztonság mellett. Windows Phone alkalmazásunk közvetlenül e szolgáltatások valamelyikébe küldheti el a felhasználót bejelentkezni. hogy az adatbázist nekünk kell tárolni. mindkét fél számára előnyös módon. nekünk kell kezelni a felhasználók problémáit (például jelszó-változtatás). hogy telefonalkalmazásunkról közvetlenül szólítjuk meg a hitelesítés-szolgáltatókat. A szolgáltatás neve Access Control. amelynek a Cloud kategóriában kell lennie (9-12 ábra). Vegyük észre. Kommunikáció szerverrel Amint láthattuk. És ami a legrosszabb: szolgáltatásunk használata előtt felhasználónknak át kell esnie a regisztrációs procedúrán. Emberünknek csak egy már létező nevet és jelszót kell beírnia. akkor ezt nem mi magunk írjuk meg.NET Membershipet is használhatnánk. Megtehetnénk. A lenti lépések végrehajtásához szükségünk lesz a Toolkitre és egy élő Azure előfizetésre. Szerencsére van arra módunk. az itt ismertetett lépésektől kis eltéréssel az ASP. Ebben a fejezetrészben a Windows Azure Toolkit for Windows Phone kihasználásával készítünk egy Access Control alapú hitelesítésre alkalmas alkalmazást. és továbbítja kérésünket a megfelelő hitelesítésszolgáltató felé. Még itt is igaz azonban. Előnye. A Microsoft Windows Azure felhőplatformja azonban kínál egy szolgáltatást. de erre gyakran nem adnak közvetlen támogatást. néhány száz forintért sok gigabájt adatot tárolhatunk a felhőben. hitelesítése. hogy telefonalkalmazásunkból nagyon könnyen használható. Amint látni fogjuk.9. Ez pedig gyakran túl sok: talán az Olvasóval is előfordult már. hanem a Windows Phone 7 Cloud Application típust válasszuk. esetleg Gmail-es e-mail címe van. akkor ellenőrizzük. Ha nem találjuk. vagy rendelkezik Live ID azonosítóval (például van Hotmail fiókja. és kap egy egyedi azonosítót a felhasználóhoz.NET Membership). hogy egy regisztrációs űrlapot meglátva rögtön visszafordult és másik szolgáltatást keresett. Ha kicsit óvatosabbak vagyunk. de mégis hitelesítsük a felhasználót! Egyszerűen használjuk valamelyik már meglévő regisztrációját! Az internet polgárainak túlnyomó többsége már tagja a Facebooknak. így a hitelesítési munkát teljes egészében megspóroltuk. amely köztes félként működik. hanem külső gyártótól származó. használ Messengert vagy van XBOX Live előfizetése). A klasszikus megoldás erre egy saját hitelesítő mechanizmus használata. Így elfedi előlünk az egyes szolgáltatók meghívásának bonyolultságát. Indítsunk egy új Visual Studio projektet! A megszokottól eltérően ne a Windows Phone Application típust. Ezt a bejelentkezési módszert hívjuk federált hitelesítésnek. hogy a Windows Azure Toolkit for Windows Phone-t jól raktuk-e fel! 240 . Alkalmazásunk értesül a bejelentkezés tényéről. biztonsági szempontból alaposan átgondolt és tesztelt hitelesítési réteget vetünk be (ilyen például az ASP. de így is elvesz pár percet a felhasználó idejéből. Felhasználó-hitelesítés szerveroldalról Ha alkalmazásunk internetes erőforrásokat is használ. természetes igényként jelentkezik a felhasználók kezelése. Lehet.

Ezúttal dolgozhatunk az Azure Storage emulátorral is.com címen! A portál bal alsó sarkában kattintsunk a Service Bus. Access Control & Caching kategórianévre! Megnyílik a kategória.NET Membership-et. hanem egy kész sablont generál. Ezeket az Azure menedzsment portálról tudjuk leszedni. Most mindössze annyi dolgunk van. amíg státusza Activating-ról Active-ra vált! Ez néhány percig is eltarthat! Miután a fentiekkel elkészültünk. hogy leszedjük a portálról az ACS konfigurálásához szükséges hitelesítési adatokat. ahol szolgáltatásunkat konfigurálhatjuk. úgyhogy nyissuk meg a portált a http://windows.azure. ahová az ACS hitelesítési adatainkat kell beírnunk. Ezt nagyrészt elvégzi majd helyettünk a varázsló. A bal felső sarokban válasszuk az Access Control elemet! Megjelennek a már létrehozott Access Control névtereink. Itt bejelölhetnénk az ASP. 241 . amiket be is kérdez tőlünk. hogy hol akarjuk tárolni fájljainkat (azaz egy Azure Storage account-ot). Válasszuk tehát az Use the Windows Azure Access Control Service lehetőséget! Megjelenik két szövegmező. jelöljük ki névterünket. így pipáljuk be az Use Storage Emulator jelölőnégyzetet. és várjuk meg. és a szalagon kattintsunk rá az Access Control Service gombra (9-13 ábra)! Megnyílik egy újabb webes interfész. Az első képernyőn azt kell megadnunk. Ehhez bizonyos alapinformációkra van szüksége. majd kattintsunk a Next gombra! A következő párbeszédablakban kell megadnunk a használni kívánt hitelesítési mechanizmust. de a példa kedvéért használjuk az Access Control Service-t. akkor a New gomb segítségével hozzunk egyet létre.Felhasználó-hitelesítés szerveroldalról 9-12 ábra: A Windows Phone 7 Cloud Application projekttípus Ez a projekttípus nem egy üres alkalmazást. valamint hogy milyen Push Notification típusokat szeretnénk használni. Ha még nincs egy sem.

Kommunikáció szerverrel 9-13 ábra: Az Access Control a Windows Azure portálon Az Access Control webes interfészének bal oldalán kattintsunk a Management service elemre. és másoljuk ki az ott megjelenített értéket (9-14 ábra)! 9-14 ábra: Access Control szolgáltatásunk menedzsment-jelszava 242 . Kattintsunk a Password elemre. majd válasszuk a Management Client elemet a Management Service Accounts listából! Megjelennek az Access Control szolgáltatásunk menedzseléséhez használható hitelesítési adatok.9.

Az eddig megismert témakörökhöz hasonlóan az Access Control szolgáltatásból is csak a legszükségesebbeket láttuk. Ha ez megtörténik. ráadásul használata meglehetősen olcsó. így érdemes elgondolkodnunk alkalmazásán! Összefoglalás A fejezetben megismertük. majd kattintsunk az OK gombra! A varázsló létrehozza az alkalmazássablont.Összefoglalás Access Control szolgáltatásunk nevét és az imént kimásolt jelszót illesszük be a Visual Studio párbeszédpanelbe. és közösségi szolgáltatásokat nyújthat. hogy alkalmazásfejlesztés közben milyen lehetőségeink vannak az interneten keresztül történő kommunikációra. Érdemes utánaolvasni a Toolkit honlapján és az Azure dokumentumaiban. Ez egy komplex műveletsor. Érdemes élni a platform által nyújtott lehetőségekkel! 243 . Az alkalmazás teljes forráskódját pedig megtekinthetjük a Visual Studióban. Indítsuk el az F5 gombbal! Ennek hatására beindul a szerveroldali komponens az Azure emulátorban. mert a kódgeneráláson felül Access Control szolgáltatásunk konfigurációja is megtörténik a háttérben. így egy ideig eltarthat. és bejelentkezhetünk az általunk választott hitelesítés-szolgáltató segítségével. A kód létrehozása után kaphatunk egy Visual Studio figyelmeztetést. Egy hálózati képességekkel felruházott alkalmazás túllép a telefon korlátain. Vegyük figyelembe.Phone projekt nevére. a Reload gombra kattintva hagyjuk jóvá a műveletet! Alkalmazásunk rögtön kész is a tesztelésre. hogy az ACS (az Azure többi szolgáltatásához hasonlóan) önállóan is igénybe vehető. Mellette külön indítsuk el a Windows Phone alkalmazást is: jobb gombbal kattintsunk az AcsSample. vagy a készülék képességeinél sokkal nagyobb erőforrásigényű feladatokat is elvégezhet. és a Debug almenüből válasszuk a Start new instance menüpontot! A telefonalkalmazás megnyílik. hogy projektünket újra be kell tölteni.

.

hanem nagyméretű lapkákból. melyek tartalmát a fejlesztő szabadon változtathatja – ahogyan azt a 10-1 ábra mutatja. fontos eseményekről maradna le.10. akkor sokkal gazdagabb élményt kínálhatunk. hogy egy külső eseményről nem a felhasználót szeretnénk tájékoztatni. így ha más módon nem tudnánk üzenni a felhasználónak. Ezért lehetőségünk van felugró üzenetet (toast notification) is küldeni – ilyen például az SMS érkezésekor látható sáv. amelyeket esetleg egy szám megjelenítésével dinamikussá lehet tenni. A lapkákhoz –mint értesítési felülethez – szorosan kapcsolódnak a Windows Phone által kínált további értesítési szolgáltatások. Frissíthetjük őket az alkalmazás futtatása közben. Lapkák és értesítések A Windows Phone egyedi lehetőséget biztosít a felhasználóval való kapcsolattartásra – ez pedig a live tile (magyarul élő lapkának fordíthatjuk). A lapkák a telefon kezdőképernyőjén kapnak helyet. A telefon kezdőlapja nem élettelen ikonokból áll. szöveget vagy számot jeleníthetünk meg. 10-2 ábra: Felugró üzenet Végül az is lehet. hanem a telefonon futó alkalmazásunknak akarunk üzenni. például minden folyamatban lévő játszmához egy-egy. de akár szerveroldalról. 10-1 ábra: Windows Phone lapkák A lapkákon képeket. ahogyan azt a 10-2 ábra illusztrálja. az alkalmazás futása nélkül is. A fejezetben részletesen megismerkedünk a lapkák és a további értesítési szolgáltatások képességeivel. A platform eszközeivel erre is lehetőségünk van. Ezek az üzenetek a felhasználó aktuális tevékenységétől függetlenül mindig megjelennek. Ha ezeket jól tudjuk használni. mintha 245 . Alkalmazásunkhoz akár több lapka is tartozhat. programozásával.

A felhasználót már a kezdőképernyőről folyamatos információkkal láthatjuk el. hogy rendszeres időközönként kérdezgetnénk (és így feleslegesen terhelnénk) a szervert. így sokkal valószínűbb. alsó részében pedig a szélesebb lapkát láthatjuk. A 10-3 ábra felső részében a négyzet alakú. és széleset. hogy újra és újra visszatér majd alkalmazásunkhoz. ha járatával bármi történik – így a felhasználó a weboldal folyamatos nézegetése nélkül is állandóan naprakész lehet. hogy később hatékonyan tudjuk őket felhasználni. Egy légitársaság alkalmazása felugró üzenettel értesítheti a felhasználót. Ha az ellenfél megtette lépését. Néhány példa a lapkák és értesítések használatára  Közösségi oldalunkhoz tartozó alkalmazásunk számmal jelenítheti meg a felhasználó olvasatlan üzeneteinek számát. Lapkák és értesítések alkalmazásunk csak bezárásáig működne.     A lapkák tulajdonságai A lapkák egyszerű. ő pedig arra nyomva egyből a megfelelő játszmában találhatja magát. és valós időben értesíthetjük a számára fontos eseményekről. Így a felhasználó egyrészt nyomon követheti a történéseket. szöveggel pedig kiírhatja a legújabb üzenetet. melyekből kettő fér egymás mellé.10. Sakk-alkalmazásunkban minden egyes folyamatban lévő játszmához tartozhat egy lapka. viszonylag kevés információt közöl a felhasználóval – legyen az névnap-előrejelző. ezt a lapkán keresztül közölhetjük a felhasználóval. felesleges adatforgalom nélkül. ám valójában rengeteg jellemzővel és képességgel ruházták fel őket a Windows Phone fejlesztői. Méret A Windows Phone kétféle méretű lapkát támogat: négyzet alakút. Ízléses képek használatával szinte biztosra vehetjük. részvényárfolyam-letöltő vagy focipontszám-nyilvántartó. hogy a felhasználó kitűzi majd kezdőlapjára alkalmazásunkat. Ahelyett. ami gyakran változó. mely nagyjából két négyzet szélességének megfelelő. ha bármi változás történt – így az alkalmazás mindig a legfrissebb információ birtokában van. sportfogadó-alkalmazásunkban a szerver üzenhet az alkalmazásnak. egyszínű négyzeteknek tűnnek. 10-3 ábra: A kétféle méretű Windows Phone lapka 246 . A következőkben megismerkedünk ezekkel a jellemzőkkel. Időjárás-előrejelző alkalmazásunkban a lapkát rendszeresen frissíthetjük a várható időjárással. Hasonlóképp érdemes lapkákat használni minden olyan alkalmazásban. másrészt pedig késztetést érez majd az alkalmazás megnyitására.

ahogyan azt a 10-4 ábra illusztrálja. és törölhetjük is őket a kezdőképernyőről. Ám alapértelmezésként ezek a lapkák mindössze az alkalmazás ikonjából és nevéből állnak. a másodlagos lapkák tárgyalásánál. a tartalmát a program frissíti A lapkák felépítése A lapkák megjelenítését egy sor előre definiált tulajdonsággal szabályozhatjuk (ezek kódból történő felhasználását később tárgyaljuk). Ez csak az alkalmazás elsődleges lapkájára érvényes. Kiszögezés és elrendezés A lapkák fontos jellemzője. A pontosság kedvéért: a Windows Phone teljes kijelzője 480 pixel széles és 800 pixel magas. ezért nagyon jó.A lapkák tulajdonságai Széles lapkája mindössze néhány beépített Windows Phone alkalmazásnak van – ilyenek pl. arra kizárólag a felhasználónak van joga. animálhatjuk. azaz rendelkezik majd lapkával. Mivel a kezdőképernyőt a felhasználó a telefon minden bekapcsolásakor látja. Mi. 10-5 ábra: Dinamikus lapka. az külön programozói erőfeszítés nélkül is kitűzhető lesz a kezdőképernyőre. a részleteket lásd később. és a lapka törlésével a hozzá tartozó alkalmazás nem kerül eltávolításra. Minden tulajdonság pontosan meghatározott módon változtatja meg a 247 . Azonban lapka kitűzését kódból még kezdeményezni sem tudjuk. Statikus és dinamikus lapkák Ha egy alkalmazást fejlesztünk. 10-4 ábra: Statikus lapka az alkalmazás nevével és ikonjával A később megismert technikákkal a lapka tartalmát frissíthetjük. megnyomáskor az alkalmazás kezdőlapjára visznek – vagyis ezek a statikus lapkák. Egy ilyen dinamikus lapkára mutat példát a 10-5 ábra. a Calendar és a Pictures. hogy egy telefon felhasználójaként tetszésünknek megfelelően rendezhetjük el őket – megváltoztathatjuk sorrendjüket. fejlesztők kizárólag négyzet alakú lapkával rendelkező alkalmazásokat tudunk fejleszteni. Az ilyen képességekkel felruházott lapkákat nevezzük dinamikusnak. ha alkalmazásunk lapkája is megjelenik ott. a széles lapkák számunkra nem használhatók. a négyzet alakú lapkák 173 pixel szélesek és magasak. A frissen feltelepített alkalmazások alapértelmezésként nem kerülnek ki a kezdőképernyőre.

akkor minden egyes folyamatban lévő játékhoz tartozhat egy másodlagos lapka. ám ehhez az alábbi feltételeknek kell teljesülniük: 248 . Számláló – a jobb felső sarokban. ahogyan azt a 10-6 ábra mutatja. Nem kötelező minden tulajdonságot beállítanunk. Másodlagos lapkát már létrehozhatunk kódból. minden Windows Phone alkalmazás rendelkezik legalább egy lapkával. amint azt a 10-7 ábra mutatja. amire aztán tetszésünk szerint bármit rajzolhatunk. 10-6 ábra: Lapka címmel és számlálóval A hátsó felület lehetséges tulajdonságai:    Háttérkép – a teljes lapkát kitöltő kép. Tartalom – nagyobb betűkkel. akkor a lapka időnként megfordul a tengelye körül. Például a cím mindig a bal alsó sarokban. Ennek angol neve: application tile. Fejlesztőként lehetőségünk van további. ugyanazzal a betűtípussal jelenik meg. hogy azt is mutassa. A másodlagos lapkák létrehozására kicsit eltérő szabályok vonatkoznak. másodlagos lapkák (angolul: secondary tile) létrehozására is. Másodlagos lapkák Amint korábban láttuk. Cím – kis betűkkel. 10-7 ábra: Egy lapka hátsó felülete címmel és tartalommal Ezeket a tulajdonságokat használva a többi Windows Phone alkalmazással konzisztens lapkákat hozhatunk létre. a lapka felső részében megjelenő felirat. Ha valamiért teljesen egyedi formatervet szeretnénk.10. akkor csak a háttérképet használjuk. mint az elsődlegesekére. Például ha egy játékszoftvert írunk. amely szintén különbözhet az elülső felület címétől. Cím – kis betűkkel. maximum 99 lehet (0 esetén nem jelenik meg). Értéke minimum 1. Lapkák és értesítések lapka megjelenését. Minden lapka két felülettel rendelkezik: egy elülsővel és egy hátsóval. Alapértelmezésként csak az elülső felület látható. mint az elülső felület képe. és ez más lehet. kör közepére írt szám. a bal alsó sorban megjelenő felirat. Az elülső felület lehetséges tulajdonságai:    Háttérkép – a teljes lapkát kitöltő kép (emlékeztetőül: a lapkák 173 pixel szélesek és magasak). a bal alsó sorban megjelenő felirat. ha a hátsónak is adunk valamilyen tartalmat.

5-ös.1 (vagy újabb) verziójú projektet hozzunk létre.xaml?id=3 Webprogramozóknak ez a felépítés ismerős lehet – az interneten is ugyanígy tudunk paramétereket átadni egy webalkalmazásnak. neve LocalTileApiSample! Fontos. A másodlagos lapkák létrehozásakor ugyanis be kell állítanunk egy alkalmazásunkra mutató URL-t is. amivel már alkalmazásunk kódjából is tudjuk manipulálni lapkáinkat. akkor erre a később ismertetett lehetőségeket használhatjuk. a másodlagos lapkái még megmaradnak. hogy egy véletlenül feltelepített rosszindulatú (vagy csak hanyagul megírt) alkalmazás teleszemetelje gondosan kialakított kezdőképernyőjét. hogy minden másodlagos lapkának különböző linkkel kell rendelkeznie. Lapka frissítése Elsőként nézzük. Deep Linking A másodlagos lapkák nagy előnye. hogy a projekt létrehozása után megjelenő párbeszédpanelen Windows Phone OS 7. hogy a másodlagos lapka kitűzését követően programunkat leállítja a telefon. azok pontosan hogyan is indítsák el alkalmazásunkat. Senki sem szeretné. Fontos. Ha a felhasználó törli az alkalmazás elsődleges lapkáját. Ezt a korlátozást az alkalmazás piactérbe (Marketplace) való feltöltésekor ellenőrzik le – ha nem tettünk neki eleget.Lapkák létrehozása és frissítése alkalmazásunkból  A másodlagos lapka kitűzését végző kód csak egy egyértelműen erre a célra szolgáló vezérlőelem hatására futhat le. amint azt a 10-8 ábra mutatja.  Ezek a szabályok a felhasználó biztonságát szolgálják. és a kezdőképernyőre visszaugorva megmutatja a felhasználónak a frissen kitűzött lapkát. 249 . másrészt ennek a képernyőnek (XAML fájlnak) paramétereket is át tudunk adni. Ha egy már létező linket megpróbálunk újra felhasználni. Figyelembe kell vennünk. A ShellTile API egyaránt alkalmas másodlagos lapkák létrehozására. hogyan lehet egy már létező lapka adatait frissíteni! A módszer ugyanaz elsődleges lapkák és másodlagos lapkák esetén is.0-ás kiadásában a lapkákat kizárólag egy külső szerver igénybevételével lehetett frissíteni. Mango kiadásban megjelent a ShellTile API. hiszen minden egyes másodlagos lapka létrehozását a felhasználónak kell kezdeményeznie. Segítségével az alkalmazás futása alatt tudunk műveleteket végezni. alkalmazásunkat visszautasítják. hogy alkalmazásunk mely képernyőjét (XAML fájlját) nyissa meg a lapka. Lapkák létrehozása és frissítése alkalmazásunkból A ShellTile API A Windows Phone első. azt egy példaalkalmazáson keresztül ismerhetjük meg: Hozzunk létre egy új Visual Studio projektet! A projekt típusa legyen az alapértelmezett Windows Phone Application. hogy megadhatjuk. 7. Egy ilyen URL lehet például az alábbi: /MainPage. A kód nagyon egyszerű. Ha az alkalmazás futásán kívül. Ez esetenként jelentős pluszmunkát és pluszköltséget jelenthetett. futásidejű hibát (InvalidOperationException) kapunk. Ez egyrészt tartalmazza. Azaz rendelkeznünk kell egy „Lapka hozzáadása” gombbal vagy jelölőnégyzettel. és a már létező lapkák tulajdonságainak frissítésére. például valamilyen időzítés szerint vagy külső esemény hatására szeretnénk lapkáinkat frissíteni. A szabályokat betartva tetszőleges számú másodlagos lapkát hozhatunk létre – ez nem jelent biztonsági problémát. A 7.

ActiveTiles. egyiket sem kötelező használni – saját alkalmazásunkban majd csak azokat állítsuk be. ahogyan azt a 10-9 ábra mutatja. Lapkák és értesítések 10-8 ábra: Windows Phone OS 7. Szerezzünk egy referenciát az alkalmazásunkhoz tartozó elsődleges lapkára! Ehhez írjuk be az alábbi sort: var appTile = ShellTile.10. „elsődleges lapka frissítése” felirattal! Nevezzük el ezt UpdateAppTileButton-nak! A nyomógomb a szerkesztőfelületen úgy jelenik meg. //Cím az elülső oldalon tileData. 10-9 ábra: Az új nyomógomb a szerkesztőfelületen A szerkesztőfelületen kattintsunk duplán a gombra. A ShellTile objektumot alapértelmezésként nem ismeri fel a Visual Studio.Title = "Elülső cím". Az első kódsorból látható. //Számláló az elülső oldalon 250 .Phone. ezzel belépünk a gombhoz tartozó eseménykezelő kódba. és akkor is létezik (azaz nem null). StandardTileData tileData = new StandardTileData().Shell. akkor régi SDK-t használunk – frissítsünk a legújabb verzióra! A projekt létrejötte után helyezzünk el az alkalmazás felületén egy új gombot.First(). A lapka frissítéséhez létre kell hoznunk egy adatszerkezetet.1 változat használata Ha ez a kérdés nem jelenik meg.Count = 15. hogy az ActiveTiles gyűjtemény legfelső elemét kérjük el a platformtól. ha a lapka még nincs kitűzve a telefon kezdőképernyőjére. Ez az elem minden esetben az alkalmazás elsődleges lapkáját tartalmazza. amelyekre szükségünk van! Kezdjük a lapka elülső oldalán található címmel és számlálóval! tileData. Most állítsuk be a lapka tulajdonságainak új értékeit! Amint korábban láttuk. Így begépelése után írjuk a következő sort a kódfájl legtetejére: using Microsoft. amely a megadni kívánt új adatokat tartalmazza.

vagy akár egy képfájlra mutató internetes URL-t is megadhatunk. hogy az URL relatívként értelmezendő. Mentsük el a képet PNG vagy JPG formátumban. majd az Add menüből válasszuk az Existing Item. 251 .png". és a Solution Explorer ablakban kattintsunk jobb gombbal a projekt nevére (LocalTileApiSample).. AppTileBackground néven! Térjünk vissza a Visual Studióba. akkor a telefon azt átméretezi majd nekünk. de ha eltérő méretűt hozunk létre. statikus képet is helyezhetünk. UriKind.BackgroundImage = new Uri("/AppTileBackground. A Solution Explorer-ben jelöljük ki a frissen beszúrt fájlt. tileData.Lapkák létrehozása és frissítése alkalmazásunkból Adjunk meg egy háttérképet is! Egy lapkára előre elkészített. és szúrjuk be alkalmazásunkba! 10-10 ábra: Az Add Existing Item funkció kiválasztása Most közölnünk kell a Visual Studióval. már nincs más dolgunk. hogy a frissen megadott fájlt tartalomként akarjuk használni – ezután tudunk majd kódból hozzáférni..Relative paraméter nagyon fontos. A sor végén található UriKind. majd a Properties ablakban állítsuk Build Action tulajdonságát Content értékűre! 10-11 ábra: Képfájl felvétele az alkalmazásba tartalomként Miután ezzel elkészültünk. a program hibára fut.Relative). mint beírni a tileData adatstruktúrába az így létrehozott kép URL-jét. menüpontot (10-10 ábra)! Tallózzuk ki az imént létrehozott képet. Ha ezt nem írjuk be. Kezdjük most egy előre gyártott képpel! Kedvenc képszerkesztő alkalmazásunkban hozzunk létre egy képet! Érdemes 173×173 pixelesre gyártani. Ez adja meg.

10-12 ábra: A lapka megjelenése a kezdőképernyőn Térjünk vissza a Visual Studióhoz. Újra futtassuk le az alkalmazásunkat! Nyomjuk meg az „Elsődleges lapka frissítése” gombot. és láthatjuk a beállításaink eredményét. nekünk nincs beleszólásunk) a lapka megfordul majd. mit alkottunk! Az elkészült beállítások életbeléptetéséhez az alábbi sort kell beírnunk.Update(tileData). és nézzük meg. majd lépjünk be abba. tileData.Update(tileData). appTile. és állítsuk be a lapka hátsó felületének tulajdonságait is! A következő kódrészleteket az appTile. mert a nagyon elhúzódó letöltéseket a telefon megszakítja!) tileData. A megírt teljes metódus törzse az alábbi: 252 . és nyomjuk meg az „Elsődleges lapka frissítése” gombot! Ha ezután visszatérünk a kezdőképernyőre. Alkalmazzuk az idáig elkészült beállításokat. hogy a lapka tulajdonságai tényleg megváltoztak. tileData. hanem egy internetes képet válasszunk! Kedvenc képkereső szolgáltatásunkkal keressünk egy szimpatikus. majd a telefon Windows gombjával lépjünk ki a kezdőképernyőre! Néhány másodperc elteltével (amit kizárólag a telefon határoz meg. kisméretű ikont. amint azt a 10-12 ábra is mutatja. sor fölé írjuk be! A hátoldalon szintén van Title tulajdonság. amint azt a 10-13 ábra mutatja: 10-13 ábra: A lapka hátoldala Ezzel a lapkák valamennyi tulajdonságának beállítását és használatát láttuk. helyette Content van. látni fogjuk. majd vágjuk ki ennek URL-jét a böngészőből! (A kép ne legyen túl nagy. Háttérképnek most ne egy helyi. amely egy szöveges értéket vár. Futtassuk programunkat az F5 megnyomásával! Az emulátorban tűzzük ki a programot a telefon kezdőképernyőjére.BackTitle = "Hátulsó cím".10.BackContent = "Tartalom". számláló viszont nincs. Lapkák és értesítések Ezzel elkészültünk a lapka első oldalának beállításával.BackBackgroundImage = new Uri("http://IKON_AZ_INTERNETROL").

Az így elkészült másodlagos lapkát pedig egyszerűen felvesszük az alkalmazás lapkái közé: ShellTile.Update(tileData). másrészt egy paramétert is átadunk (neve: color.png". a másikat „Piros” felirattal! A gombok megnyomására alkalmazásunk egy-egy másodlagos lapkát hoz majd létre.Lapkák létrehozása és frissítése alkalmazásunkból private void UpdateAppTileButton_Click(object sender. értéke: blue). Készítésükkor pedig paramétereket építhetünk beléjük. Ezeket (a felhasználó kérésére) kódból mi magunk hozhatjuk létre. appTile. a másik pedig piros háttérszínnel indítja majd programunkat. tileData.BackBackgroundImage = new Uri("http://IKON_AZ_INTERNETROL"). tileData. tileData. tileData. Használjuk erre az OnNavigatedTo eseményt! Álljunk a kurzorral egy üres kódsorhoz (mondjuk közvetlenül a private void UpdateAppTileButton_Click sor fölé). és gépeljük be: override onnavigatedto 253 . az itt beírt három sort másoljuk át a „Piros” gomb Click eseményének kezelőjébe is (ügyelve arra. tileData. //Számláló az elülső oldalon tileData. hogy két részből áll: egyrészt megadjuk a megnyitandó Silverlight nézetet (MainPage. tileData).) vihetjük a felhasználót.BackContent = "Tartalom". } Másodlagos lapka létrehozása Amint korábban már láttuk. a leendő másodlagos lapka csak címet kap: StandardTileData tileData = new StandardTileData().Title = "Kék".xaml?color=blue". hogy a gomb feliratát és paraméterét átírjuk „Piros”-ra és red-re)! Most állítsuk be. hogy nem kell minden tulajdonságot megadnunk. hogy eljussunk a kódnézetbe! Másodlagos lapka létrehozásához ugyanarra a StandardTileData adatszerkezetre lesz szükségünk. //Cím az elülső oldalon tileData.Relative). amiket megnyomásukkor megkap az alkalmazás. A gombok nevei legyenek BlueButton és RedButton! Létrehozásuk után kattintsunk duplán a „Kék” feliratú gombra. amikor alkalmazásunk betöltődik. UriKind.First(). Nézzük meg figyelmesen a lapka beágyazott URI-ját! Láthatjuk.Relative). UriKind.Title = "Elülső cím". alkalmazásunkhoz tartozhatnak másodlagos lapkák is. egyiket „Kék”. A „Kék” gomb hatására létrehozott másodlagos lapka kék háttérszínnel. StandardTileData tileData = new StandardTileData(). RoutedEventArgs e) { var appTile = ShellTile.Create(new Uri("/MainPage. Alkalmazásunk e paraméter alapján tudja ellenőrizni majd.BackTitle = "Hátulsó cím".xaml).Count = 15. így ezeket feldolgozva egyből programunk „belsejébe” (pl. Hozzunk létre programunk felületén két gombot. Kihasználva.ActiveTiles. Miután ezzel megvagyunk.BackgroundImage = new Uri("/AppTileBackground. mint amit az előző fejezetrészben is használtunk. hogy a felhasználó melyik lapka segítségével indította el. a megfelelő játszmába. megfelelő részvényhez stb. hogy a lapkákra kattintva alkalmazásunk a megfelelő háttérszínben pompázva induljon – azaz használjuk a Deep Linking lehetőséget! A háttérszínt beállító kódot akkor kell futtatnunk.

A kikereséshez használhatjuk a lapka URL tulajdonságát. Erre a felhasználónak az alkalmazásunktól függetlenül is van lehetősége.Blue). Ez a módszer nem igényel külső szervert. Másodlagos lapka törlése Előfordulhat.QueryString["color"] == "blue") { LayoutRoot. hogy egyáltalán kaptunk-e color nevű paramétert. Futtassuk az F5 gombbal alkalmazásunkat! Nyomjuk meg előbb a Kék. hogy az nem létezik-e már! Lapkák frissítése Background Agent-ek segítségével A korábban bemutatott ShellTile API segítségével alkalmazásunk futása alatt teljes körűen tudjuk frissíteni. hogy létezik-e a törölni kívánt lapka a gyűjteményben. majd a Piros gombot! Látni fogjuk. és létrehoz nekünk egy-egy új másodlagos lapkát. akkor alkalmazásunk hátterét kékre állítjuk. lezárulta után célszerű automatikusan törölni a hozzá tartozó. majd dupla kattintással lépjünk be az eseménykezelőjébe! A lapka törléséhez egyszerűen ki kell azt keresnünk a lapkák gyűjteményéből. annak ellenőrzésére. stb. ha a lapka kirakása előtt ellenőrizzük. Lapkák és értesítések A Visual Studio erre egy listából felkínálja számunkra azt az eseményt. de az aktuális játszma. letörli: if (ShellTile. A lapkák igazi haszna azonban éppen abban rejlik. amelynek kódját felül szeretnénk írni.QueryString. Egyszerűen védekezhetünk ez ellen a hibalehetőség ellen. hogy a lekérdezéshez használt módszert használhatjuk a lapka létrehozása előtt is.Delete(). if (NavigationContext. Fontos tudni. hogy ennek értéke blue-e. majd leellenőrizzük.ToString() == "/MainPage.ActiveTiles gyűjtemény tartalmaz-e már a létrehozni kívánt URL-lel egy lapkát. amely garantáltan egyedi – ahogyan azt korábban már bemutattam. korábban létrehozott lapkát.10.Background = new SolidColorBrush(Colors.NavigationUri. azaz alkalmazásunk leállása után is működik. Vagyis ha a Kék gombot még egyszer megnyomjuk.NavigationUri. Az alábbi kódrészlet (a C#-ba épített LINQ lekérdezőnyelv segítségével) ellenőrzi.Single(i => i. Ezt a mechanizmust kihasználva a háttérszín-váltásnál sokkal komplexebb belső navigációt is kivitelezhetünk. Nincs más dolgunk. Elsőként megnézzük. A létrehozott lapkákat megnyomva pedig alkalmazásunk újra elindul – a kiválasztott háttérszínnel. és ha létezik. és időzített frissítést használ. hogy a kirakott másodlagos lapkákat törölni szeretnénk.ActiveTiles. repülőút. hogy azok képesek alkalmazásunk futása nélkül is frissülni! A következő fejezetrészben a lapkák Background Agentből való frissítését ismerjük meg.ActiveTiles.xaml?color=blue").ContainsKey("color") && NavigationContext. hogy a ShellTile. Az eseménykezelőn belül a NavigationContext objektum QueryString tulajdonságán keresztül kérhetjük el alkalmazásunk indítási paramétereit. majd meghívni a Delete() metódusát. „Kék törlése” felirattal. hogy a telefon mindkét gomb megnyomására bezárja az alkalmazásunkat.xaml?color=blue") > 0) { ShellTile. Ha egyezést találunk. mint a Tab gomb megnyomásával létrehozni ezt az eseménykezelőt. } Vegyük észre. bővíteni és törölni lapkáinkat. akkor alkalmazásunk hibára fut. DeleteBlueButton névvel. 254 . hogy egy adott URL-ű másodlagos lapkából egyszerre csak egy lehet. Hozzunk létre egy újabb gombot felületünkön.ToString() == "/MainPage.Count(i => i. } Ezt a kódrészletet még egyszer – értelemszerűen – felhasználva tudjuk kezelni a piros szín esetét is.

Ehhez a BackgroundAgentTileUpdateSample projektből fel kell vennünk egy referenciát a ScheduledTaskAgent1 projektre. A következő oldalakon egy példaprogramot készítünk. tudatnunk kell a telefonalkalmazással. A metódus végén már megtalálható a NotifyComplete() hívás. legyen ez egy Windows Phone Application! Projektünk neve legyen BackgroundAgentTileUpdateSample! Az előző fejezetrészhez hasonlóan itt is Windows Phone OS 7. fejezetben.1 verziót (vagy újabbat) válasszunk! A Background Agent kódját külön projektbe kell helyeznünk. így ide kell elhelyeznünk a lapkát frissítő kódunkat. Egy éles alkalmazás ennél természetesen sokkal bonyolultabb logikát is meghívhat a Background Agent-ből. Hozzunk létre egy Windows Phone Scheduled Task Agent típusú projektet! Ennek neve maradhat az alapértelmezett ScheduledTaskAgent1. amely egy Background Agentet regisztrál be. A szolgáltatás teljes leírása megtalálható az 5.cs állományt. így az előző fejezetrészben megismerteket hasznosíthatjuk újra. hogy hol találja a neki rendelt Background Agent-et.5-ben debütált. Készítsünk egy új Visual Studio projektet. Ez jelzi az operációs rendszer számára. A Background Agent futásakor az itt található OnInvoke() metódust hívja meg a futtatókörnyezet. A kód megírásához először is szükségünk van egy sor névtérre. és hagyjuk mindig a saját kódunk után! A lapka frissítésére a ShellTile API-t vehetjük igénybe. és futása leállítható. hogy a Background Agent elvégezte a rábízott feladatokat. Ez a háttérben futva rendszeres időközönként frissíti majd az alkalmazás lapkáját.cs) legtetejére! 255 . amint azt a 10-14 ábra mutatja! 10-14 ábra: A Background Agent projekt hozzáadása Itt ismét találkozunk a projektek listájával. fejezete foglalkozik. és nem kizárólag a lapkák frissítésére való – épp ellenkezőleg.Lapkák frissítése Background Agent-ek segítségével A Background Agent a Windows Phone 7. Részletes ismertetésével a könyv 5. Kattintsunk jobb gombbal a BackgroundAgentTileUpdateSample projekt References mappájára. válasszuk az Add Reference lehetőséget. Ezért ezt a sort ne töröljük ki. Példaalkalmazásunk az aktuális időt írja majd ki a lapkára. számos egyéb rendszeresen végrehajtandó vagy erőforrás-igényes feladat elvégzésére használható. A példaprogram elkészítése során csak a Background Agent funkcionalitásának szükséges részét használjuk ki. A Windows Phone Application projekt létrejötte után kattintsunk jobb gombbal a Solution Explorer ablak legtetején található Solution ’BackgroundAgentTileUpdateSample’ sorra. Írjuk be az alábbiakat a kódfájl (ScheduledAgent. és a megjelenő ablak Projects fülén válasszuk ki a ScheduledTaskAgent1 elemet! A projektfájlok létrejötte után a Visual Studio automatikusan megnyitja számunkra a ScheduledAgent. Miután mindkét projektünket létrehoztuk. és az Add menüből válasszuk a New Project lehetőséget.

Remove(periodicTaskName).catch blokk belsejébe. így a PeriodicTask időzítési módot használjuk. Fontos tudni. külső áramellátás) megléte esetén kap futási jogot. if (periodicTask != null) ScheduledActionService. using System. ugyanis a felhasználó a telefon beállításai között letilthatja a Background Agent-eket. az épp futó Background Agent-ek listájában). Lapkák és értesítések using System. gépeljük be az alábbi kódot az OnInvoke() metódusba (a NotifyComplete() fölé)! Ez semmi újdonságot nem tartalmaz.Linq. létezik-e már az általunk kívánt néven Background Agent.) Ennek elvégzéséhez helyezzük az alábbi sorokat a gomb eseménykezelőjébe: string periodicTaskName = "TileUpdaterSample". tileData. 10 percig. Magától természetesen nem fog lefutni.. Minden Windows Phone alkalmazáshoz legfeljebb egy Background Agent tartozhat.Shell.Update(tileData). letöröljük.Find(periodicTaskName) as PeriodicTask. 256 . így felhasználónknak legalább ilyen gyakorisággal újra kell időzíttetnie – célszerű. ShellTile. hogy időzítése után két héttel a Background Agent automatikusan törlődik a rendszerből. hogy ellenőrizzük. A lapka frissítése jellemzően nem erőforrás-igényes. ha egy éles alkalmazásban erre valamilyen módon emlékeztetjük. melyről egy kivétel formájában értesülünk. Ehhez először egy objektum formájában létrehozzuk és beállítjuk a leírását (ezt látja majd a felhasználó az operációs rendszer beállításai között.Phone. felirata legyen „Background Agent időzítése”. ResourceIntensiveTask időzítési mód: bizonyos külső feltételek (pl. de rendszeresen szeretnénk elvégezni.. PeriodicTask periodicTask = ScheduledActionService. using Microsoft.Phone. Az időzítő az egyes Background Agent-eket nevük alapján azonosítja.Scheduler. Ezután utasítjuk a futtatókörnyezetet a Background Agent időzítésére. Első feladatunk. neve pedig ScheduleBackgroundAgentButton! Miután kihúztuk. Ha igen. ami a Background Agent-ek időzítéséhez szükséges eszközöket tartalmazza! using Microsoft. Térjünk vissza a BackgroundAgentTileUpdateSample projektbe! A Background Agent időzítését egy gomb végzi majd. Ezt mindenképp tegyük egy try. Miután ezzel megvagyunk. ehhez telefonalkalmazásunknak előbb időzítenie kell azt. Ezután következik a tényleges időzítés. a lapka címét frissíti a ShellTile API segítségével: StandardTileData tileData = new StandardTileData(). A Background Agent-et ezzel felprogramoztuk. 30 percenként.First(). Ezt kétféle módon időzíthetjük:   PeriodicTask időzítési mód: A Background Agent rövid ideig (25 másodpercig) kap futási jogot kb.Title = DateTime. (Ez könnyen előfordulhat. Húzzunk ki a kezelőfelületre egy gombot. dupla kattintással lépjünk be a gomb Click eseménykezelőjébe! A kódfájl tetejére helyezzük el az alábbi névteret. ha a felhasználó a kéthetes automatikus törlési időszak alatt újra kéri a Background Agent időzítését.ActiveTiles.Now.ToShortTimeString().10.

amint azt a 10-15 ábra is mutatja. hogy az Agent lefuthasson! Tűzzük ki alkalmazásunkat a kezdőképernyőre! Kisvártatva tanúi leszünk a lapka frissülésének. mert a Marketplace ellenőrzésen valószínűleg meg fog bukni! ScheduledActionService. periodicTask.Lapkák frissítése Background Agent-ek segítségével periodicTask = new PeriodicTask(periodicTaskName). A futtatókörnyezet biztosít egy hívást. a Background Agent működését megszemlélhetjük a telefon beállításai között is.Message).Description = "This is the Tile Updater sample. amellyel a Background Agent lefuttatása néhány másodperc várakozás után kikényszeríthető.LaunchForTest(periodicTaskName. ám a Background Agent-ek kb. de az alkalmazás publikálása előtt feltétlenül töröljük ki. Ezzel tulajdonképpen elkészültünk.FromSeconds(30)). majd az emulátor Windows gombjával lépjünk ki programunkból. lapozzunk az Applications fülre. melyik osztályt kívánjuk az időzített feladat futtatása során használni.". és ezt Background Agent-nek ismerte fel. 10-15 ábra: A Background Agent által frissített lapka Ha szeretnénk. Ezt az operációs rendszer onnan tudja.Show(ex. TimeSpan. Ehhez lépjünk be a telefon beállításai közé (Settings). hogy korábban felvettünk egy referenciát a ScheduledTaskAgent1 projektre. ami nagyon megnehezíti a tesztelésüket. 30 percenként futnak. és nyomjuk meg a Background Tasks lehetőséget (10-16 ábra)! 257 . } Észrevehető.Add(periodicTask). A próbafuttatáshoz érdemes beírni a következő programsort is. hogy a fenti kódban semmilyen módon nem adtuk meg. Az F5 megnyomásával futtassuk alkalmazásunkat! Nyomjuk meg a „Background Agent időzítése” gombot. try { ScheduledActionService. } catch (Exception ex) { MessageBox.

imperatív módon tudtuk frissíteni lapkáinkat. a telefon pedig egyszerűen csak letöltse azt. Használatához (a Background Agent-hez hasonlóan) alkalmazásunk futása közben időzítenünk kell a frissítéseket. A ShellTileSchedule arra ad lehetőséget. Lapkák és értesítések 10-16 ábra: Background Agent-ünk a telefon listájában A Background Agent segítségével alkalmazásunk a leállása után is naprakészen tarthatja lapkáját. hetente vagy havonta)?  Milyen URL-ről töltődjön le a kép? A letöltésre kiválasztott kép kizárólag internetes URL-ről származhat.1 vagy újabb verziót célozva! A ShellTileSchedule beállítását már rögtön az alkalmazás indulásakor elvégezzük. hanem egy kiszolgálón állítjuk elő. A Background Agent nagy előnye. hogy a felhasználó a kezdőképernyőre tűzve tartsa alkalmazásunkat. akkor az időzítést törli a futtatókörnyezet. Ehhez kódunkat helyezzük a MainPage() konstruktorába. Windows Phone OS 7. Bizonyos esetekben azonban kényelmesebb lehet. A képfájl maximum 80 kilobájtos lehet. Időzítés beállítása az elsődleges lapkára Korábban megismerkedtünk a lapkák tulajdonságaival. Lapkák frissítése ShellTileSchedule segítségével Az előző két fejezetrészben megismerkedtünk a ShellTile API-val és a Background Agent-ekkel. Az időzítés beállításához az alábbi paramétereket adhatjuk meg: A frissíteni kívánt lapka (lehet elsődleges vagy valamelyik másodlagos lapka is)   Hányszor történjen meg a frissítés (egyszer. amelyek utána a háttérben futnak majd. fix alkalommal vagy határozatlan ideig)? Milyen gyakran történjen meg a frissítés (óránként. azaz nem használhatunk a telefonon lévő helyi erőforrásokat. A ShellTileSchedule ezek közül kizárólag a lapka elülső felületén található háttérképet tudja frissíteni. Egy folyamatosan frissülő lapka pedig jó ok arra. ha a szükséges tartalmat nem a készüléken. Ha az időzített művelet végrehajtása 3 egymást követő alkalommal sikertelen. hogy a megjelenítendő információt szerveroldalon készítsük elő. 258 . Mindkét módszer segítségével a telefonon futó kódból.10. naponta. szerver igénybevétele nélkül. alkalmazásunk leállását követően is. óránként szeretnénk frissíteni. és letöltése nem tarthat 30 másodpercnél tovább. Írjunk egy rövid példaprogramot. hogy ehhez még külső szerverre sincs szüksége. ami bemutatja a ShellTileSchedule használatát! Az eddigiekhez hasonlóan hozzunk létre egy új Windows Phone Application típusú projektet ShellTileScheduleSample néven. közvetlenül az InitializeComponent() metódushívás után! Lapkánkat határozatlan ideig. a többi tulajdonság ezen az API-n keresztül nem módosítható.

Az Interval tulajdonság adja meg. eredménye a 10-17 ábrához hasonlít majd. határozott alkalommal vagy akár határozatlan ideig futó időzítéseket is.Onetime értéket adtunk meg.Onetime érték esetén pedig csak egyszer.MaxUpdateCount = 0. és onnantól kezdve a megadott beállítások szerint végzi a lapka frissítését. akkor nincs korlát a frissítések számára.Now. schedule. mint 0.png"). Egy éles alkalmazásnál ennek kiszolgálására egy saját szervert használhatunk. de a további webes technológiák is biztosítanak erre lehetőséget. Ezért célszerű. az UpdateRecurrence.Lapkák frissítése ShellTileSchedule segítségével Az időzítés beállításához egy ShellTileSchedule típusú objektumot használunk. ShellTileSchedule schedule = new ShellTileSchedule(). Az UpdateRecurrence. ha a lapka nem csak egyszer frissítendő (lásd Recurrence tulajdonság). schedule. (Ha a Recurrence tulajdonságnál UpdateRecurrence. ha alkalmazásunk minden egyes indításakor újra és újra elvégzi a beállítást. hogy lapkánk milyen gyakorisággal frissüljön.Interval. hogy időzítésünk hányszor fut le.gov/forecasts/graphical/images/conus/MaxT1_conus. schedule.weather. majd a Start() metódus hívásával érvénybe léptetjük az időzítést. Ha 0 vagy annál kisebb.EveryHour. Ez ASP.) A RemoteImageUri tulajdonsággal állíthatjuk be a letölteni kívánt kép címét. A tulajdonság értékét csak akkor veszi számításba a telefon. akkor a lapka a megadott számú alkalommal lesz frissítve.RemoteImageUri = new Uri("http://www. mert az energiatakarékosság érdekében az esedékes frissítéseket összegyűjti és egyszerre hajtja végre a telefon. Ha a tulajdonság értéke nagyobb. hogy erre sokat kell várnunk (akár egy órát is). Lehetséges értékei: EveryHour. Lehet. 259 . schedule. majd lépjünk ki belőle és tűzzük ki a kezdőképernyőre.Start(). schedule. vagy letöltése 30 másodpercnél tovább tart) a telefon törli az időzítést.     Végül a Start() metódushívás kiadja a parancsot az időzítés tényleges elvégzésére. EveryDay.StartTime = DateTime. Beállítjuk a kívánt paramétereket. A fenti tulajdonságok használatával készíthetünk egyszeri alkalommal. Ne feledjük azonban a korábban látott korlátozásokat! Három egymást követő sikertelen frissítési kísérlet után (azaz ha a képfájl nagyobb.NET Web Forms esetén például képeket visszaadó Handler-ek (ASHX fájlok) segítségével oldható meg. Nézzük meg az egyes paraméterek jelentését!  A Recurrence tulajdonság értékétől függ. mint 80 KB.Interval érték esetén többször is. akkor ennek a beállításnak nincs értelme. EveryWeek és EveryMonth. Némi idő elteltével megtörténik a frissítés. Fontos.Interval = UpdateInterval. A MaxUpdateCount segítségével különböztethetjük meg a határozatlan ideig futó és a bizonyos időre szóló időzítéseket. amely egy adott URL-en egy dinamikusan frissülő képet tesz elérhetővé. A kód megírása után indítsuk el alkalmazásunkat. Ezt követően a telefon megvárja a StartTime időpontot. schedule.Recurrence = UpdateRecurrence. A StartTime tulajdonsággal határozhatjuk meg az időzítés kezdő időpontját. hogy ez csak az internetről származhat (azaz helyből nem).

schedule.Start().StartTime = DateTime. az összes többi elem pedig az épp aktuális másodlagos lapka.) Így ha egy másodlagos lapkára szeretnénk időzítést létrehozni. A tile változóba egy ShellTile típusú objektumot vár a telefon. Előfordulhat. Mivel egyszerre csak egy ShellTileSchedule lehet aktív lapkánként. használatukhoz a felhasználónak ki kell tűznie alkalmazásunkat a kezdőképernyőre.RemoteImageUri = new Uri("http://www. schedule. hogy a másodlagos lapkákra mutató referenciákat a ShellTile. ShellTileSchedule schedule = new ShellTileSchedule(). schedule. Amint a bevezetőben arról már szó volt.gov/forecasts/graphical/images/conus/MaxT1_conus.png"). schedule. így szeretnénk azt letörölni. schedule.ActiveTiles gyűjteményben találjuk. majd rögtön le is állítjuk.Recurrence = UpdateRecurrence. Lapkák és értesítések 10-17 ábra: A ShellTileSchedule által frissített lapka Időzítés beállítása egy másodlagos lapkára Hogy állíthatunk be ShellTileSchedule időzítést egy másodlagos lapkára? Az objektum paraméterezése nem változik.Now. (Emlékezzünk vissza. és a lapkákon található információ csak akkor jut el hozzá.Interval = UpdateInterval. ahol az első elem az elsődleges lapka. azaz nem lesz aktív időzítés. A felugró értesítések A fejezetben idáig alaposan megismerkedtünk a lapkákkal és különböző frissítési lehetőségeikkel. csak létrehozásakor át kell neki adnunk a frissíteni kívánt másodlagos lapkát. A lapkák passzívak. az elküldött értesítés mindenképpen megjelenik a telefon kijelzőjének 260 . így az eredeti ShellTileSchedule objektum természetesen már nem elérhető.weather. a lapkákon kívül a felugró értesítések is fontos módjai a felhasználóval való kapcsolattartásnak.10.Stop(). schedule. ha később rájuk is néz. schedule. Ilyenkor egyszerűen újra létrehozzuk és elindítjuk az időzítést.MaxUpdateCount = 0. A felugró értesítések (angolul: toast notification) ezzel szemben aktívak! Bármilyen alkalmazást is futtat a felhasználó. ezzel felülírjuk a korábbi időzítést. fenti példakódunkat így kellene módosítanunk: ShellTileSchedule schedule = new ShellTileSchedule(tile). majd meg kell hívnunk a Stop() metódusát.Interval. a frissen létrehozott példányt pedig leállítjuk. Egy időzítés törléséhez először referenciát kell rá szereznünk. hogy a létrehozott ShellTileSchedule értelmét veszti. hogy az időzítést a programunk egy korábbi futásakor állítottuk be.EveryHour. Időzítés törlése Előfordulhat.

adjunk hozzá erre egy referenciát az első projektből stb. Ha ennek értékét nem adjuk meg. A Background Agent szolgáltatással tetszőleges kódot futtathatunk a háttérben. A lapkáknál már részletesen megismertük a Background Agent-ek készítését. Természetesen óvatosan kell bánnunk az értesítésekkel – ha túl agresszívan. Ennek megfelelően csak Background Agent-ből (illetve a fejezet későbbi részében ismertetett Push Notification szolgáltatás segítségével) van lehetőségünk megjeleníteni egyet! Az értesítések kezeléséhez szükséges kód igen egyszerű. ám összesen kb. majd a telefon Windows gombjának segítségével lépjünk ki az alkalmazásból (ez fontos. majd ezt követi az értesítés tartalma. Így alkalmazásaink – és a felhasználók is – a különféle eseményekről óhatatlanul késéssel értesülnek. különben az értesítés nem lesz látható)! Néhány másodperc elteltével megjelenik az értesítés. lehetősége van letiltani alkalmazásunk értesítéseit.A Push Notification szolgáltatás felső részén. A ShellTileSchedule osztállyal pedig telefonunk időzítetten kérhet adatokat egy szervertől egy lapka frissítéséhez. rányomva pedig egyből a hozzá tartozó alkalmazás indul be. Mértékkel használva viszont hatékonyan hívhatjuk fel alkalmazásunkra a figyelmet. Végül a lapkákhoz hasonlóan az értesítéseknél is használhatjuk a Deep Linking technikát.cs fájl OnInvoke() metódusában helyezzük el a következő kódot: ShellToast toast = new ShellToast(). Viszont mindkét módszer csak kérni tud adatokat (azaz pull irányban működik). Így kommunikálhatunk szerverrel. akkor a lapkáknál leírtakkal azonos módon itt is megtehetjük. 40-50 karakter jelenik meg.Show(). A megjelenő értesítések bal oldalán alkalmazásunk ikonjának kicsinyített változata található. Az ikon melletti félkövér szöveg az értesítés címe. 10-18 ábra: Egy felugró értesítés Az értesítések fontos megkötése. A toast objektumnak van még egy NavigationUri tulajdonsága is. Ez a két szöveg már állítható. indítsuk el az alkalmazásunkat. de az értesítésekhez nem állítható be külön ikon. hiszen csak bizonyos 261 .Title = "Értesítés".Content = "Az üzenet tartalma". toast. A Push Notification szolgáltatás A fejezet eddigi részében megismertük a Background Agent szolgáltatást és a ShellTileSchedule osztályt. Azaz ha fut az alkalmazásunk. azaz írjuk meg a Background Agent-et beregisztráló kódot is! Miután ezzel elkészültünk. Az alkalmazás ikonja természetesen változtatható (erről lásd a korábbi fejezeteket). így egy URI-t is beállíthatunk az értesítés mögötti tartalom eléréséhez (10-18 ábra). Ne feledjük el befejezni a lapkáknál megismert műveleteket. akkor az értesítésre nyomva a felhasználó alkalmazásunk kezdőképernyőjét látja majd megjelenni. Ha viszont szeretnénk használni a Deep Linking lehetőséget. toast. nem tudunk értesítést küldeni.). majd a Scheduled Task Agent projektben található ScheduledAgent. felesleges üzenetekkel bombázzuk a felhasználót. hogy csak alkalmazásunkon kívül jelennek meg. vegyünk fel mellé egy Windows Phone Scheduled Task Agent projektet. toast. a többi kilóg a képernyőről és nem látható. frissíthetünk lapkákat. és megjeleníthetünk értesítéseket. Azaz két módszert is láttunk már a szerveroldali kommunikációra. regisztráljuk be a Background Agent-et. Végezzük el az ott leírt lépéseket (azaz hozzunk létre egy Windows Phone Application projektet.

és a mi alkalmazásunknak nem jut hely. hogy akár 3 percenként küldhetünk egy üzenetet a nap minden órájában. és továbbítja a készülék felé. A Push Notification mechanizmus segítségével az alkalmazásunkat futtató telefont összekapcsolhatjuk egy általunk fenntartott szerveroldali alkalmazással. Ezt az URL-t pedig visszaküldi a Push kliensnek. és hitelesített csatornát kell létrehoznunk. mert az alkalmazásunk előző futásaikor létrehozott csatornát lehetőségünk van újrahasznosítani. A szerveroldali komponens platformfüggetlen elemeket használ (XML formátumú üzeneteket kell küldenie). hogy az ide érkező üzeneteket továbbítja a telefonnak. hanem a szerver üzenhet valamilyen esemény megtörténtekor. Használata azonban az alábbi feltételekhez kötött:  A Push Notification-öket a felhasználónak kimondottan kérnie kell az alkalmazás felületén található valamilyen vezérlőelemmel (opt-in rendszer). A szolgáltatás leírása megtalálható az internetes MSDN könyvtárban. 4. aki visszaadja az alkalmazásuknak. Ez a korlátozás megint csak nem súlyos: napi 500 üzenet azt jelenti. azaz nem alkalmazásunknak kell kérésekkel bombáznia a szervert. akkor felesleges kérésekkel fogyasztják a telefon akkumulátorát.NET nyelven programozzuk majd. A telefon operációs rendszerének részét alkotó Push kliens az interneten át közli ezt a szándékot az MPNS-szel. Telefononként maximum 30 ilyen csatorna lehet. ha sokáig nem történik semmi. Ezt egyszerű használni. A Push Notification szolgáltatás működése A Push Notification szolgáltatás architektúrája 3 elemből áll: az általunk írt telefonalkalmazásból. Ez push irányú forgalom lesz. hogy szeretne push üzeneteket fogadni. Az összekapcsolás után kiszolgálónk bármikor küldhet a telefonnak üzeneteket. fejezetben bővebben esik szó. Az MPNS egy publikus URL-t állít elő. 2.) A fentebb leírt regisztrációs lépések egy csatornát hoznak létre az MPNS és a telefon között. Lapkák és értesítések időközönként kapnak frissítést. az alkalmazást visszautasíthatják a Marketplace-ből. de telefononként (csatornánként) és naponta maximum 500 üzenetet küldhetünk ki. Ha ennél többre van szükségünk. Alkalmazásonként maximum 1 csatorna létezhet. Ha szerverünk ezután bármikor üzenni szeretne a telefonnak. Használata a következőképpen néz ki: 1. Ezt az MPNS kapja meg. használatával ismerkedünk meg. mind az alkalmazás-felhasználók számára. azaz fel kell rá készülnünk. Szerverünk és az MPNS között alapértelmezésként HTTP (titkosítatlan) csatornán folyik a kommunikáció. Ezenkívül lehetőséget kell neki biztosítani az értesítések kikapcsolására is. és vállalja.10. A Push Notification szolgáltatáson keresztül háromféle üzenetet küldhetünk a telefonnak: 262 . akkor egy HTTPS tanúsítványt kell vásárolnunk. Ez a korlátozás szerencsére nem súlyos. Erre tetszőleges kommunikációs forma használható. így tetszőleges szerveroldali technológiával megírható. 3. Érdemes webszolgáltatásokkal megoldani. Ebben a fejezetrészben a Push Notification szolgáltatás tulajdonságaival. Alkalmazásunknak ezt az URL-t közölnie kell a szerverünkkel. Alkalmazásunk jelzi a telefon felé. amikről a 9. (Ha ezeknek a feltételeknek nem teszünk eleget. a szintén általunk írt szerveroldali alkalmazásból és a központi Microsoft Push Notification Service-ből (MPNS). A Microsoft Push Notification Service ingyenes mind a fejlesztők. Ráadásul. hogy a korábban telepített alkalmazások már mindet lefoglalták. akkor erre az URL-re küldi el üzenetét. Ebben a fejezetrészben ASP.    A hitelesített csatornák létrehozására és a hozzájuk kapcsolódó „callback” üzenetküldésre ebben a fejezetben nem térünk ki.

ha pedig fut.Phone. háttérkép. hogy a csatorna jogosult a lapkák frissítésére! A mintakódban láthatóak lesznek az esemény-feliratkozások. és egy szerver. amit éles környezetben egy webszerveren vagy a felhőben tartunk. amit később továbbfejlesztünk majd az értesítések és a raw üzenetek küldésére és fogadására. Ha viszont korábban már megnyitottuk a csatornát. akkor ezt megtesszük. ami beregisztrálja alkalmazásunkat az MPNS felé. Ha a telepített Visual Studio nem teszi lehetővé a webfejlesztést. stb. Ha azt találjuk.xaml. Mivel alkalmazásonként maximum 1 csatornánk lehet az MPNS felé. másrészt közölnünk kell a telefonnal. az üzenetet a telefon operációs rendszerében lévő Push kliens fogadja. A fentiek elvégzéséhez helyezzük az alábbi kódot a MainPage.1 vagy újabb verziót válasszuk! Első lépésként megírjuk azt a kódot.A Push Notification szolgáltatás  Lapkafrissítés: a fejezetben már megismertük a lapkák különféle tulajdonságait – elülső és hátsó felület. akkor töltsük le és telepítsük az ingyenes Visual Web Developer Express verziót! Hozzunk létre egy új Windows Phone Application projektet PushNotificationClientSample néven! Továbbra is a Windows Phone OS 7.cs kódfájl MainPage() konstruktorába: 263 . Ha alkalmazásunk nem fut. Felugró értesítés: a Push Notification-ök segítségével felugró értesítéseket is megjeleníthetünk a felhasználó számára. Az eredeti eseményfeliratkozások az alkalmazáson belül történtek. cím. Egy Push üzenetből a lapka valamennyi tulajdonságát frissíthetjük. akkor kódból elkaphatjuk az üzenetet. A frissítéshez nem kell futnia az alkalmazásunknak. A korábban megismert tulajdonságok itt is használhatók: beállíthatjuk az értesítés címét. és a csatorna lapkafrissítésre való regisztrációja is (BindToShellTile() hívás). mint újra feliratkozni annak eseményeire. hogy alkalmazásunk korábbi futtatásakor regisztrált-e már be csatornát. Nevéhez hűen ebben tetszőleges adatokat (szöveget vagy akár egy bájttömböt) is elküldhetünk a telefonnak. A beregisztrált csatorna egyrészt különféle eseményeket indíthat (például: hiba történt. Az egyszerűség kedvéért ezt már közvetlenül az alkalmazás indulásakor lefuttatjuk. hogy a csatorna még nincs beregisztrálva. „Raw” (nyers) üzenet: Minden más esetre a Raw Notification használható. Ha alkalmazásunk fut. A fejezet hátralévő részében egy példán keresztül megismerjük. amelyekre fel kell iratkoznunk. Lapkák frissítése Push Notification-ök segítségével Ismét egy példaalkalmazást készítünk. hogy miként tudjuk regisztrálni alkalmazásunkat az MPNS-ben. tartalmát. ebben a példában azonban a helyi fejlesztői gépünkről szolgáljuk ki. A webszerver elkészítéséhez erre alkalmas Visual Studio változatra van szükségünk. akkor megjelenik az értesítés. Ha nem fut. akkor megkapja. ami a telefonon fut majd. ezért feltétlenül meg kell vizsgálnunk. Ehhez a HttpNotificationChannel objektumot és annak metódusait használjuk majd. és tetszésünk szerint feldolgozhatjuk. és még egy Deep Linking-re alkalmas URL-t is átadhatunk.Notification. Az alkalmazásnak két szükséges komponense van: egy kliens. akkor nincs más dolgunk. így természetesen az alkalmazás leállásakor azok elvesznek. vagy megváltozott az MPNS által biztosított URL).   A fenti üzenettípusok mindegyikének rögzített formátuma van. éles alkalmazásban ne feledjük ezt valamilyen vezérlőelemhez (például egy gombhoz) kötni! Elsőként írjuk a következő sort a fájl legtetejére: using Microsoft. majd hogyan küldhetjük ki a különféle üzenettípusokat. akkor viszont az üzenet elvész. és ő végzi el a módosítást.

ToString()). void pushChannel_ChannelUriUpdated(object sender. } A fenti kód két eseménykezelőre is hivatkozik. pushChannel. string channelName = "SampleChannel". pushChannel. vagy újrahasznosítja a régit. pushChannel.ChannelUri.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(pushChannel_ErrorOccurred).Debug.létrehozzuk.ToString()).10. amiről a 9. //Még nem létezik . System.Diagnostics. } Ezzel a kliensoldali kódot meg is írtuk – az alkalmazás vagy új csatornát hoz létre. Éles alkalmazásban ezt célszerű közölnünk a webszerverünkkel. ebben a kódban a hibákról üzenetet küldünk a felhasználónak. hogy létezik-e már a csatorna. ha az MPNS megváltoztatja a csatorna URL-jét.ismét feliratkozunk az eseményeire. például egy webszolgáltatáson keresztül. A második (pushChannel_ErrorOccurred) pedig hibakezelésre való. }). Az első (pushChannel_ChannelUriUpdated) akkor kerül meghívásra. és a vágólapon keresztül másoljuk át a szerverre.WriteLine(e. Most az egyszerűség kedvéért mindössze kiíratjuk az URL-t.Open().Diagnostics. Lapkák és értesítések HttpNotificationChannel pushChannel. NotificationChannelUriEventArgs e) { Dispatcher. //Megnézzük.ChannelUri. else { pushChannel. és feliratkozunk az eseményeire. }).ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(pushChannel_ChannelUriUpdated). } //Már létezik .BeginInvoke(() => { MessageBox. fejezetben részletesen olvashatunk.BindToShellTile(). és lekezeli annak különféle eseményeit.Find(channelName). pushChannel = HttpNotificationChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(pushChannel_ChannelUriUpdated). if (pushChannel == null) { pushChannel = new HttpNotificationChannel(channelName). pushChannel.Message).BeginInvoke(() => { System.WriteLine(pushChannel. NotificationChannelErrorEventArgs e) { Dispatcher.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(pushChannel_ErrorOccurred).Show("Hiba történt: " + e. itt mindössze egy erre vonatkozó üzenetet íratunk ki a Visual Studióval. Látszólag hiányzik viszont egy fontos elem: nem küldjük el az URL-t a szerveroldalra! Egy éles alkalmazásban valóban így történne.Debug. Írjuk most meg az alkalmazás szerveroldali komponensét! Ehhez nyissunk egy új Visual Studio projektet! 264 . } void pushChannel_ErrorOccurred(object sender. pushChannel.

Text. Ha valamelyik XML tulajdonságot üresen hagyjuk. a lapkák korábban megismert valamennyi tulajdonságát frissíthetjük. A projekt típusa legyen ASP.aspx oldal a vezérlőelemekkel Következik a szerveroldali kód megírása. akkor új példányt kell indítanunk. a címkébe pedig a visszatérési értéket helyezzük majd el. A telefonnál megszokott módon kattintsunk duplán a Lapkafrissítés küldése gombra! A megnyíló kódfájl tetejére helyezzük el a következő néhány sort: using System. a többi tulajdonságot változatlanul hagyja. kódunk ezért először felépíti ezt az XML struktúrát. egy gombot SendTileButton néven és „Lapkafrissítés küldése” felirattal. Amint a példakódban levő XML-ből látjuk. amit megjelenítünk majd a lapkán! A gombbal kezdeményezzük a küldést. Hozzunk létre az űrlapon két szövegmezőt UrlTextBox és MessageTextBox néven.Text + "</wp:Title>" + "<wp:BackBackgroundImage></wp:BackBackgroundImage>" + 265 . neve PushNotificationServerSample ! A projekt létrejötte után adjunk ahhoz egy új Web Form típusú elemet.aspx néven! A Visual Studio automatikusan megnyitja az űrlap HTML nézetét.IO.0\" encoding=\"utf-8\"?>" + "<wp:Notification xmlns:wp=\"WPNotification\">" + "<wp:Tile>" + "<wp:BackgroundImage></wp:BackgroundImage>" + "<wp:Count></wp:Count>" + "<wp:Title>" + MessageTextBox. mert a telefonos fejlesztésre használt Visual C# Express nem támogatja a webfejlesztést. A második szövegdobozba írjuk üzenetünket. valamint egy címkét ResponseLabel néven! Az első szövegdobozba kerül majd az MPNS által visszaadott URL. ahová üzenetünket küldjük majd. de ha a Visual Studio Express verzióit használjuk. string tileMessage = "<?xml version=\"1. using System. using System. //Előállítjuk az üzenetet.Net. ehhez a Visual Web Developer Express-re van szükségünk.A Push Notification szolgáltatás Ezt létrehozhatjuk a már megnyitott Visual Studio példányban is. Ezután írjuk meg a gomb SendTileButton_Click eseménykezelőjének kódját! Mindhárom értesítési típusnak egy kötött struktúrájú XML üzenetet kell küldenie egy HTTP kérésen keresztül. Default. 10-19 ábra: A Default. A ShellTileSchedule osztállyal ellentétben itt háttérképeket helyi erőforrásból is beállíthatunk – ehhez használjunk relatív URL-t (amire már láttunk példát a fejezet korábbi részeiben)! A példakód az egyszerűség kedvéért kizárólag a lapka címét frissíti a megadott üzenetre. A fentiek elvégzése után az űrlapnak a 10-19 ábrához kell majd hasonlítania.NET Empty Web Application. akkor az nem változik a lapkán.

A X-NotificationClass pedig az üzenet sürgősségét határozza meg – ha 1. Ezzel elkészültünk. hogy lapkafrissítésről. akkor azonnal. Az X-WindowsPhone-Target tulajdonság értéke adja meg.ContentType = "text/xml".Length. akkor legkésőbb 450 másodpercen belül. mint az üzenet tényleges elküldése.GetBytes(tileMessage). ha 11. Ezek után már nincs más hátra. Ha ehhez írunk programot.Add("X-WindowsPhone-Target". ezért érdemes a fentieket körbevenni egy try. és mennyire sürgős. sendNotificationRequest. sendNotificationRequest. string notificationStatus = response. és az eredményül kapott URL-t kiírja a Visual Studio Debug üzenetei közé. using (Stream requestStream = sendNotificationRequest.Headers. a különféle státusz-üzenetek a válasz HTTP fejlécében érkeznek. string deviceConnectionStatus = response..Length). "1").catch blokkal.Text). Lapkák és értesítések "<wp:BackTitle></wp:BackTitle>" + "<wp:BackContent></wp:BackContent>" + "</wp:Tile> " + "</wp:Notification>". "token").0 operációs rendszerben. A HttpWebRequest paraméterezésére is ügyelnünk kell! Egyrészt. ResponseLabel. miután elküldte az üzenetet. notificationMessage.GetResponse(). a HTTP fejrészében be kell állítanunk. Erre a HttpWebRequest osztályt használjuk.Headers["X-NotificationStatus"].ContentLength = notificationMessage.aspx Az előállított XML fájlt egy HTTP kérésen keresztül tudjuk elküldeni az MPNS-nek.Headers. Az MPNS visszajelez. Ha ez nem látszik.Headers["X-DeviceConnectionStatus"]. Másrészt. értesítésről vagy raw üzenetről van szó. de valójában elvégzi az MPNS regisztrációt.Create(UrlTextBox. így a korábban létrehozott XML formátumú szöveget bájttömbbé alakítjuk. HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest. ha 21.Add("X-NotificationClass". sendNotificationRequest. a kérést POST üzenet formájában kell elküldenünk. 0. A fenti kód Windows Phone 7. string notificationChannelStatus = response.microsoft. akkor a View menü Output menüpontjával tegyük láthatóvá (lásd 10-20 ábra)! 266 . Ezeket a fejlesztő felület Output ablakában nézhetjük meg. akkor ezeket hagyjuk ki! Ezekről lásd: http://msdn.5 (Mango) vagy újabb operációs rendszer esetén működőképes.Text = notificationStatus + " | " + deviceConnectionStatus + " | " + notificationChannelStatus. //Létrehozzuk a HTTP kérést. Ezt rögtön ki is íratjuk az erre a célra létrehozott ResponseLabel címkébe.Default.com/enus/library/ff402558(VS.GetRequestStream()) { requestStream.Write(notificationMessage.10. //Elküldjük az üzenetet és kiolvassuk a választ. sendNotificationRequest. hogy az üzenet milyen célt szolgál. akkor pedig legkésőbb 900 másodpercen belül továbbküldi a telefon felé az MPNS. Az üzenetet bájttömb formájában kell majd átküldenünk a hálózaton. Mivel hálózati kódról van szó. byte[] notificationMessage = Encoding.Method = "POST". sendNotificationRequest. } HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.Headers["X-SubscriptionStatus"]. Teszteljük a programot! Indítsuk el mindkét projektet! A Windows Phone alkalmazás látszólag semmit nem csinál. Bizonyos tulajdonságok még nem léteztek a Windows Phone 7.92).

és kattintsunk a Lapkafrissítés küldése gombra! A webalkalmazás összeállítja az XML-t. Értesítések megjelenítése Push Notification-ök segítségével Nézzük. Ennek megfelelően a kliensoldali kódban minimális változtatást kell csak végrehajtanunk. ha az alkalmazás lapkája nem volt kitűzve. Szintén fontos. Mindössze azt kell közölnünk a telefonnal. amint az a 10-21 ábrán látható. Írjuk be a pushChannel. hogy a Push Notification-ök sajnos nem minden karaktert támogatnak.BindToShellToast().BindToShellTile(). Ennek hatására a frissítés gyakorlatilag azonnal megjelenik. A lapkákhoz hasonlóan itt is 267 . Hozzunk létre egy új gombot a webes projektben SendToastButton néven és „Értesítés küldése” felirattal! Dupla kattintással lépjünk be Click eseménykezelőjébe. Végül térjünk vissza a webalkalmazáshoz. sor alá a következő egyetlen sort: pushChannel. elküldjük az URL-t a szervernek. az üzenet elvész. ami rögtön továbbítja azt a telefon felé. ha ékezetes betű van az üzenetben. a Push Notification-öknél ez nincs így – ha az alkalmazás épp nincs kitűzve. hogy míg a ShellTile API-n keresztül elvégzett változtatásokat akkor is elmentette a telefon. hogy a létrehozott csatornán keresztül értesítések is érkezhetnek. és ezeket is kezelje le. Hibát kaphatunk. hogy ez az XML is tartalmazza a felugró értesítések valamennyi lehetséges tulajdonságát. a szerverről pedig XML formátumú kéréseket irányítunk a csatornába. elküldi az MPNS-nek. és illesszük be a weboldalunk felső szövegdobozába! Az alsóba írjunk valamilyen rövid üzenetet! A telefonon lépjünk ki az alkalmazásból. és tűzzük ki a kezdőképernyőre. A szerveroldalon szintén nagyon kevés változtatásra van szükségünk. és egy az egyben másoljuk át a SendTileButton_Click eseménykezelő tartalmát ide! Módosítsuk az XML üzenetet a felugró üzenetek sémájának megfelelően! Láthatjuk. 10-21 ábra: A Push Notification-nel frissített lapka Jó tudni.A Push Notification szolgáltatás 10-20 ábra: Az Output ablak és az MPNS-től visszakapott URL A megjelenő URL-t másoljuk ki. A felugró üzenetet és a lapkafrissítést küldő kód csak az elküldött XML fájl formátumában és néhány paraméter-értékben tér el. hogyan tudunk felugró értesítéseket megjeleníteni Push Notification-ök segítségével! A művelet logikailag szinte teljesen megegyezik a lapkafrissítésekkel – a telefonon beregisztráljuk a csatornát.

Headers. "toast"). sendNotificationRequest.ErrorOccurred += kezdetű sor után: pushChannel. akkor ehhez a ShellToastNotificationReceived eseményre kell feliratkoznunk. és 22 a 900 másodpercen belülit). 10-22 ábra: A megjelenő felugró üzenet Ha az alkalmazás futása közben is szeretnénk kezelni a megérkező értesítéseket. A teszteléshez előbb el kell távolítani a kliens alkalmazást a telefonról.Headers. Ezután módosítsuk a kérés HTTP fejrészét! Meg kell adnunk.Add("X-NotificationClass". így ezúttal egy eseményre kell majd feliratkoznunk. Raw üzenetek fogadása a Push Notification szolgáltatáson keresztül Végül ismerkedjünk meg a Raw üzenetek küldésével! A felugró értesítésekhez hasonlóan nagyon kevés változtatást kell végeznünk már meglévő kódunkon.Text + "</wp:Text1>" + "<wp:Text2></wp:Text2>" + "<wp:Param>/MainPage. hogy ez egy értesítés. A HttpNotificationReceived eseménykezelő törzsében mindössze kiolvassuk és megjelenítjük a kapott üzenetet – egy éles alkalmazás természetesen ennél sokkal bonyolultabb logikát is végrehajthat: 268 . és nem fut le a módosított kódunk. A raw üzenetek csak akkor fogadhatók. sendNotificationRequest. és kattintsunk az Értesítés küldése gombra! Az eredmény a 10-22 ábrához hasonlít majd. Erre azért van szükség. és át kell írnunk a kézbesítés gyorsaságát szabályozó konstanst is (itt 2 jelenti az azonnali kézbesítést. "2").0\" encoding=\"utf-8\"?>" + "<wp:Notification xmlns:wp=\"WPNotification\">" + "<wp:Toast>" + "<wp:Text1>" + MessageTextBox. Miután ezzel elkészültünk. string tileMessage = "<?xml version=\"1. azaz „toast” típusú.0-s operációs rendszert futtató telefonok még nem ismerik mindet az itt szereplő tulajdonságok közül! //Előállítjuk az üzenetet.Add("X-WindowsPhone-Target". mert a 7.10. Távolítsuk el tehát a programot a telefonról. amikor alkalmazásunk fut. ami lapkafrissítéshez is beregisztrálná (a BindToShellToast() hívás). mert korábbi tesztjeink során az már megnyitotta a Push Notification csatornát. 12 a 450 másodpercen belülit. majd másoljuk át az URL-jét a webalkalmazásba. majd indítsuk el a két projektet! A telefonalkalmazásból lépjünk ki (különben az értesítés nem jelenik meg).HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(pushChannel_HttpNotificationReceived). Lapkák és értesítések ügyeljünk. Így ha most elindítjuk. már tesztelhetjük is az alkalmazást. akkor csak újrahasznosítja a csatornát.xaml</wp:Param>" + "</wp:Toast> " + "</wp:Notification>". Helyezzük a következő kódot mindkét pushChannel.

ReadToEnd(). és küldjünk egy raw üzenetet! A várható eredmény a 10-23 ábrán látható. sendNotificationRequest. A felugró üzeneteknél látott módon távolítsuk el az alkalmazást a telefonról.Body)) { string message = reader. hogy az MPNS maximum 1 kilobájtnyi fejléccel és 4 kilobájtnyi törzzsel rendelkező üzeneteket továbbít! //Előállítjuk az üzenetet. majd másoljuk át ide a SendToastButton_Click eseménykezelő törzsét! Ezt ismét csak két helyen kell módosítanunk. Ezek képesek az Azure tárhelyek használatára. //sendNotificationRequest. 450 másodpercen belüli vagy 900 másodpercen belüli kézbesítést jelent.Headers. Elsőként írjuk be az elküldendő üzenetet! Ez raw üzenet esetén bármi lehet – XML.A Push Notification szolgáltatás void pushChannel_HttpNotificationReceived(object sender. vagy az Azure-on keresztüli felhasználó-hitelesítésre. hogy a Windows Azure kifejezetten támogatja a Windows Phone-nal való együttműködést.Text. A Microsoft külön toolkit-et készített Azure Toolkit for Windows Phone 7 néven. 13 vagy 23 lehet – a megszokott módon ez azonnali. Jó hír. kézenfekvő.IO.StreamReader(e. Dispatcher. }). majd indítsuk be a két projektet.BeginInvoke(() => { MessageBox. módosítsuk a HTTP fejléceket! Az X-WindowsPhone-Target fejlécre ezúttal nincs szükségünk – ezt a lenti kódrészletben kommentálással jeleztük. Az X-NotificationClass értéke raw üzenet esetén 3.IO. Másodszor.Headers. hogy a felhőt használjuk erre a célra. másoljuk át az URL-t a webalkalmazásba.Add("X-WindowsPhone-Target".Notification. és ami a leglényegesebb: a Push Notification-ök használatára is. "toast"). 10-23 ábra: A kézbesített raw üzenet Push Notification-önök és a Windows Azure Ha szerverre van szükségünk.Add("X-NotificationClass". lépjünk be Click eseménykezelőjébe. "3"). Architekturális szempontból ugyanazt valósítják 269 . ami kész alkalmazás-sablonokat tartalmaz. Ügyeljünk azonban arra. string tileMessage = MessageTextBox. szöveg vagy akár egy tetszőleges bájttömb is. } } Most módosítsuk a szerveroldalt is! Hozzunk létre egy új gombot SendRawButton néven „Raw üzenet küldése” felirattal. Készen állunk az alkalmazás tesztelésére.Show(message).StreamReader reader = new System. HttpNotificationEventArgs e) { using (System.

a frissítés időzítetten történik. Szervert is igényel. Ezen eszközökkel alkalmazásunk nemcsak addig „él”. de más-más esetben érdemes őket használni. Csak a telefon kell hozzá. érdemes kipróbálni a toolkit-et. hanem leállítása után is képes friss információkat biztosítani. Alkalmazásunknak nem kell futnia. melyekkel a felhasználó figyelmét aktívan irányíthatjuk alkalmazásunkra. Az alábbi táblázatban összehasonlítjuk a lapkák frissítésére használható lehetőségeket. érett kód formájában. amelynek beállítását. Összefoglalás A fejezetben megismertük a lapkák tulajdonságait. a telefon kezdeményezésével működik. Megismertük. Ezek célja ugyan azonos. Érdemes őket használni. Lapkák és értesítések meg. Ha lehetőségünk van az Azure használatára. hogy az értesítések a lapkákhoz hasonlóan Background Agent és Push Notification segítségével is küldhetők. Alkalmazásunknak nem kell futnia. Push Notification Láttuk továbbá a felugró értesítéseket is. 270 . mint a fentebb leírtak. de kész. egyes funkcióinak használatát a 9.10. és láttuk a frissítésükre használható négy módszert. Szolgáltatás ShellTile API Background Agent ShellTileSchedule Jellemzők Csak a telefon kell hozzá. amíg a felhasználó aktívan futtatja. Szervert is igényel. mert segítségükkel sokkal professzionálisabb megjelenést. eseményvezérelt. Alkalmazásunk futása alatt használható. időzített módon. vagyis a szerver kezdeményezi a frissítést. Alkalmazásunknak nem kell futnia. fejezet tárgyalja. interaktívabb élményt biztosíthatunk.

Játékok a Mango világában A most soron következő fejezet témáját tekintve merőben eltér a korábbi fejezetektől. a teljesítménye nem megfelelő sebességorientált magas számítási kapacitást igénylő megoldásokhoz – ide bizony egy grafikus technológiára volt szükség. amely a teljes platformnak csak egy darabja). így a választás a Direct3D lehetett volna. a fejlesztői modell előnyei és hátrányai jól körvonalazódtak. és az arra való áttérés egy . amely magasabb absztrakciójú megoldásokat kínál. és a Windows a grafikus alrendszer támogatásán kívül mást nem nyújt. illetve bemutatni.NET fejlesztő számára sokkal kevésbé megterhelő. PC-re írt játékok esetében két elterjedt grafikai API létezik: OpenGL és DirectX (pontosabban a Direct3D. így sokkal kényelmesebb megoldásra volt szükség. azonban úgy gondoltuk. így nemcsak a tapasztalt játékfejlesztőket kellett megcélozni a technológiai támogatásokkal. A Silverlight mint korszerű alkalmazásépítési platform jó választásnak tűnt. több éve kedvelt és elterjedt technológia. Amikor a platform utódjának fejlesztésébe kezdtek. amely a legújabb technológiákra épít. Miután a teljes . az eszközök közötti különbségekből származó eltérésre szükséges csak odafigyelni a játék fejlesztése során. Azonban hiába a gazdag médiatámogatás. könnyebben tanulható és könnyebben kezelhető. skálázási eltérésekre és néhány. Ezek után megnézzük. Windows Phone – a motorháztető alatt A Windows Mobile fejlesztése során a Microsoft rendkívül sok tapasztalatot halmozott fel. Miután a Microsoft a nyílt OpenGL-t nem használja saját fejlesztéseihez. Ez azt jelenti. pontosan mit is jelent a Silverlight és az XNA hibrid megjelenítési rendszere.11.és kezdő fejlesztőket is. ezzel elméleti és gyakorlati alapot adva azon Olvasóinknak is. és tartalmaz mindent. Azonban a Windows Phone az ipar számára egy újonnan belépő tagot jelentett. A választás az XNA Frameworkre esett. hanem a játékok fejlesztése iránt érdeklődő hobbi. Természetesen.NET Framework számos okból nem vihető át egy mobil eszközre. hogy ezen a téren a Mango frissítés milyen újdonságokat hozott magával. Xbox és most már a Windows Phone is. mint azelőtt volt. mint Windows. amire egy játékprogram esetében szükség lehet (11-1. és mikor tudjuk kihasználni az új lehetőségeket. így a platform felépítésekor két fő szempontot kellett betartani: a megszokott alkalmazásfejlesztési modell alkalmazható legyen általános alkalmazásfejlesztéshez. de az okos telefonok piacán egyre nagyobb teret hódító játékok és grafikus alkalmazások se maradjanak támogatás nélkül. hogy a céleszközök között az alkalmazások átvihetők.NET alapú programozási felülettel rendelkezik. A fejezet első részében megismerkedünk az XNA Framework és a grafikus programozás legfőbb mozzanataival. akik eddig még soha nem találkoztak fejlesztői szempontból számítógépes játékokkal vagy grafikus programozással. ahogy azt megszoktuk. Az XNA a Microsoft játékfejlesztési eszközkészlete és futtatókörnyezete különböző eszközökre. Ők nagy valószínűséggel nem fognak egy komplex grafikus rendszert kitanulni. hogy mindenképpen érdemes adni egy rövid ízelítőt a telefonos játékok fejlesztéséből. ábra):       Átgondolt irány-architektúra a játék számára Grafikai rendszer Bemenetek támogatása magas szinten Audiorendszer Tartalmakat kezelő alrendszer Különböző eszközök 271 . aránylag rövid kiadási ciklusokkal. . egy olyan sokkal átgondoltabb és korszerűbb rendszert szerettek volna alkotni.

Helyette poligonokra (sokszögekre) bontjuk fel az alakzatot. az esetek jelentős részében kötötten egy játékkategórián belül használható jól. Az XNA egy jól átgondolt alapot ad. akkor ahhoz DirectX-re és natív kódra lesz szükségünk. hogy soha nem a legfrissebb natív grafikus platformhoz van igazítva. így a poligonok számának függvényében fog változni az adott modell részletessége is. minden. szkript rendszer. 3 dimenziós térben gondolkozunk. ábra: A Windows Phone Mango fejlesztői platform Nem keverendő össze az XNA Framework egy játékmotorral (game engine)! Sok szempontból úgy tűnhet. A GPU több 272 . Megjelenítéskor a csúcspontokat összekötjük. másodsorban pedig a folyamatosan fejlődő technológiáknak. Fontos megjegyzés az XNA-val kapcsolatban: sokat egyszerűsít a játékfejlesztési folyamaton. Ha nem szeretnénk minden apró részletet saját magunk kifejleszteni a legelejétől fogva. amely elsősorban a fejlődő hardveres erőforrásoknak köszönhető. akkor már előre megjósolható. nem fogjuk minden egyes pontját az adott térbeli testnek kiszámítani. amely külön is letölthető a Microsoft letöltő központjából. Windows Phone telefonokon azonban nincs lehetőségünk natív kódot futtatni. miszerint egy kép lehet pixeleivel számítva – amely az esetleges skálázások során pontatlanságot és darabosságot okoz. mesterséges intelligencia. hogy az XNA mindent tartalmaz. azonban szerves részét képezi a Windows Phone fejlesztői készletnek is. illetve az számos olyan komponenst kínál (fizikai számításokért felelős komponens. a poligonoknak pedig a csúcspontjait tároljuk le. Ha ezt térbe szeretnénk levetíteni. egyszerűbben juthatunk el a kívánt célunkig. A keretrendszer pillanatnyilag a 4. azonban a matematikai számításokat újra és újra végre kell hajtani. Képek reprezentációja során jól ismerjük a két létező analógiát. térben helyezkedik el. Játékok a Mango világában 11-1. Grafikus programozási és XNA alapok A kép kialakítása A mai játékok hónapról hónapra egyre szebb grafikai megvalósításokat sorakoztatnak fel.). Ha a legújabb funkciókat szeretnénk Windows környezetben kihasználni. De milyen komponensekből épül fel egy játék grafikája? Nos. amely az esetek egy jelentős részében – a jól optimalizálhatóság miatt – C++-ban íródik. akkor először a térbeli információk kerülnek be a megjelenítéshez szükséges elemeket tartalmazó csővezetékbe. amit egy játékmotor. azonban gyorsan feldolgozható – és lehet vektoros alapon számítva – amely skálázás esetén is mindig pontos lesz. és a területüket kitöltjük. aminek támogatásával rövidebb idő alatt.11. hogy valamilyen gyorsító megoldásra itt is szükség lesz. ami a mi esetünkben a DirectX. akkor az interneten számos nyílt forráskódú játékmotor fellelhető. amelyek kimondottan XNA-hoz készültek. de ez messze nem igaz. amelyeket az XNA nem. Amikor a grafikus processzor feldolgozza és megjeleníti ezeket a poligonvázakat. amit meg szeretnénk jeleníteni. az annál több számítást fog igényelni.0-s változatánál tart. stb. Egy játékmotor sokkal specifikusabb. azonban ezt azon az áron teszi. Természetesen minél több poligonnal szeretnénk dolgozni.

Az anyagminták egyszerű képfájlok. hogy ha egy fénysugár becsapódik. amik arra vonatkoznak. mintha az adott test felületén helyezkedne el (11-3. ezért nem a poligonok számának növelésével és színezésével finomítjuk a modellt tovább. és számításigényes lehet. és így tovább. akkor azt hogyan verjük vissza és milyen intenzitással. alakja kezd hasonlítani arra. melyeket térben a megfelelő poligonra vetítünk le. ábra). Azon túl. azaz levetíti a képernyő megfelelő pixeleire (11-2. ábrán jól látható. Rendkívül sokat tud a valóságérzet kialakításában segíteni egy jól elkészített fény-árnyék rendszer. A visszaverődéshez egy felületi tulajdonságra van szükségünk. Elhangzott egy fontos fogalom: a fény. ábra). azonban (mint minden más is egy játékban) ez matematikai alapon van megfogalmazva. a keletkezett háromszögeket pedig raszterizálja. Mi kell a fények megjelenítéséhez? Valamilyen fényforrás és az adott térbeli alakzat információja arra vonatkozóan. hanem anyagmintákat (textúrákat fogunk) felhasználni. 11-3. egy másik rétegben tárolhatunk olyan információkat is. de még mindig nem az igazi. ábra: Poligonváz textúra nélkül és textúrával Most már olyan érzetet kelt bennünk. A számítógépes grafika minden területén a való életből merít ötleteket. így azt a hatást keltve. hogy az alapmintázatot megadja. hogy a térben megalkotott delfin alakzat nem igazán valósághű.Grafikus programozási és XNA alapok lépésen keresztül tovább bontja azokat háromszögekre. amit létre szeretnénk hozni. mintha tényleg valamilyen valós objektumot jelenítettünk volna meg egyszerűen a számítógép segítségével. mennyi fényt tud elnyelni az adott test helyenként. hanem több különböző réteg több feladatot tud ellátni. 11-2. ami 273 . A textúrák nemcsak egyetlen rétegben helyezkedhetnek el a modellen. mennyire árnyalt. de részletessége még nagyon messze áll ettől. ábra: Egyszerű poligonváz A 11-2.

ábrán jól megfigyelhető. Egy pixel alapú megvilágítást mutat be a 11-5. mint az adott poligon normálvektora. ha minden egyes pixelre külön határozzuk meg a fények hatását. ha magas poligonszámú vázzal van dolgunk. ehhez azonban pixel alapú manipulációra van szükségünk. 11-5. A normálvektor és a fényvektor skaláris szorzata meghatározza a visszaverődési paramétert. hogy a poligononként meghatározott visszaverődés csak akkor ad szép eredményt. azt közvetlenül a GPU (grafikus processzor) fogja végrehajtani. 11-4. Ennek lehetséges orvosolása. Itt már csak a számítási komplexitás szabhat határt. A beépített – és egyben korlátos – megoldások (Fixed Function Pipeline) megkerülésére aránylag hosszú ideje van lehetőség grafikus processzorra írt árnyaló (shader) kódok segítségével.11. Játékok a Mango világában nem más. ábra: Poligononkénti megvilágítás A 11-4. amit megfogalmazunk. ábra. ábra: Pixel alapú fény egy kis felbontású modellen 274 . amelyet a grafikus technológiák nem segítenek alapértelmezetten.

akkor a felület úgy néz ki. vagy a filmszakadást imitáló sávosítás is. amelyek játékokban valós időben tudnak megvalósítani sugárkövetést. Ez a textúra minden pixelében egy normálvektort ír le. melyekkel valósághű vakító és tompított fényviszonyokat tudunk létrehozni. Ahogy haladunk előre a színtér elemeinek megismerésével. amelyekkel a sebesség illetve a térbeli távolság hatását tudjuk hangsúlyozni. se nem közvetlen szemből). helyettem inkább beszéljenek a képek (11-7. amely megspórolja számunkra azt.a virtuális térbe. az a sebességorientált (inkrementális) képszintézis. melyeknek az útját követjük. Ide tartoznak a különböző elmosások. ami nem más. hogy a térelem minden egyes pixelét számításba vegyük. és 118. mint a kásás. azonban a poligonváz – számítási teljesítmény miatt visszafogott – felbontása még mindig problémát okoz. azonban a tökéletes tükröződések. hogy milyen anyagi tényezőket gyűjtöttek össze. mint a képernyőtér (a képernyő pixelei. Természetesen vannak kezdeményezések megfelelő sebességű algoritmusok előállítására. Ezeket az effektusokat mondatokkal megfogalmazva nehézkes szemléltetni. melyet szintén pixelenként kiértékelve a fénysugár függvényében egy részletes. A buckaleképezés elemei megfigyelhetők a 11-6. törések és megvilágítások reprezentiációjához létezik egy sugárkövetés (ray tracing) nevű megközelítés is. Ha megfelelő szögben nézzük az adott objektumot (se nem túl kis szögben. hanem a filmekben használt speciális effektusok nagy része is ezekre épít. azonban a komplex számítási rendszer miatt a komolyabb megoldások még jó ideig csak a filmekben maradnak. drámai hatások elérése is. hogy a képernyő minden egyes pixeléből sugarakat indítunk – akárcsak a való életben a fotonok . Amit a fejezetben eddig tárgyaltunk. ábrán. és megfigyeljük. ahol a textúrát egy nagyon alacsony poligontartalmú gömbre feszítettük ki. helyette csak a képernyő felbontása szerinti pixelekkel kell számolnunk.Grafikus programozási és XNA alapok Érdekesség: a fény-árnyék rendszerek nemcsak a számítógépes játékokban jelentősek. térbeli felület hatását kelti. egyre finomabbá kezd válni a virtuális térben létrehozott környezetünk. 11-6. azonban szorosan kapcsolódva az eredeti mintához. Erre egy elterjedt megoldást jelent az úgynevezett buckaleképezés (Bump Mapping). Nagyon sok valóságérzetet keltő effektus ezen keresztül valósítható meg. ábra: Buckaleképezés és a normálvektorokat tartalmazó textúra Sajnos a könyv terjedelme (és legfőképpen témakörei) miatt a virtuális objektumok számítógépes grafikai módszereit nincs lehetőségem tovább részletezni. bár minden egyes említett témakör még hosszasan taglalható lenne. amin „keresztül” a teret látjuk). zavaros (zajjal torzított) megjelenítés. Helyette térjünk át a színtér egy másik aspektusára. mintha jóval több poligon segítségével modelleztük volna azt. Ennek a lényege az. Ilyenek például a dinamikus fénykontrasztokat leíró HDR (High Dynamic Range) effektek. amely egy újabb réteg textúrát ad a modellünkhöz. ezzel a matematikailag tökéletes világítást megvalósítva. ábra)! 275 . De ilyen például a sci-fi filmekre jellemző.

Készítsünk belőle sokat. amely mindig a kamera felé néz. Elég sokat barangoltunk az elméleti síkon. hogy az egyes négyzeteknek milyen irányba.11. majd utána a gyakorlatban is megnézzük. ezért makroszkopikusabb elemekkel kell megközelítenünk a problémát. füst és az ősszel hulló falevelek? Ezeknek a modellezése pixel alapon rendkívül körülményes lenne. amely egy esőcsepp mintázatát tartalmazza áttetsző háttérrel! Feszítsük azt ki egy négyszögre. fűzzük fel egy listára. milyen sebességgel és hogyan kell mozogni! A kód gondoskodjon arról is. hogy ha egy elem már nem látható. akkor a helyére pótoljon egy új elemet. mint az eső. tűz. amely még sokkal valósághűbb eredményt ad. ábra: Többszörös effektek képernyőtérben A fenti megoldások segítségével sok minden megvalósítható. A mai modern játékok a részecskerendszert is a GPU segítségével valósítják meg és fizikai szimulációval egészítik ki. Képzeljünk el egy egyszerű kis textúrát. 276 . hogy egy egyszerű kétdimenziós játék megvalósításához milyen elemekre van szükségünk. még egy kitérőt teszünk a játékciklus megismerésével. azonban hol vannak az olyan természetben előforduló jelenségek. Játékok a Mango világában 11-7. amely megmondja. amellyel az egész folyamat újra lejátszódik! Ezt a megközelítést részecskerendszernek hívják. és a legtöbb. ábra: Fénykontrasztos (HDR) effekt 11-8. sok elemből álló és egységes szabály szerint működő jelenség megvalósítható vele. és adjuk át egy olyan metódusnak. és hogyan használjuk őket. hó.

0 kategóriát! Ezen belül egy Windows Phone Game (4. stb. hogyan épül fel egy XNA alkalmazás! Indítsuk el a Visual Studio-t. ezzel nem jön létre külső interakció. elmentjük az állapotot és felszabadítjuk a memóriából a jelentősen erőforrásigényes tartalmakat. a felhasználó másodpercenként 30 alkalommal biztosan nem fogja lenyomni az egérgombot. A program indulása során inicializáljuk a szükséges paramétereket. Ha volt. Nos. a mozgás érzetét keltve. és egészen addig nem végez újabb feladatot. ahol a játék szereplői. azaz a számítások és a bemenetek függvényében a színtér (az a tér. 30-szor kell pillanatfelvételt készítenie. akkor úgy tekintünk a programra. hangok. így magunknak kellene eseményt létrehozni. (11-9. amelyen belül folyamatosan ismétlődni fog a renderelési lépés. 277 . ábra: A játékok végrehajtási modellje Egy XNA program felépítése A hosszas elméleti bevezető után nézzük meg. Egy játéknak a PC esetében másodpercenként körülbelül 60. hogy úgy tekintünk a programra. ahogy az valójában működik is. folyamatosan fut. majd belépünk egy végtelen ciklusba. amíg az előbb felsorolt tevékenységek közül valamelyik be nem következik. dinamikus és statikus tartalmai elhelyezkednek. amíg ki nem lépünk. de hogyan kezeljük a bemenetet. és az adott képkockát megjelenítenie a felhasználó számára. ábra). a mesterséges intelligenciát és még számos más komponensét a játéknak. amelyek nélkül működésképtelen? Ezekhez nincs szükségünk eseményekre! Mindössze a ciklus törzsén belüli sorrendre kell odafigyelnünk. a felhasználó valamilyen interakciót végez a felhasználói felületen vagy a háttérben valamilyen adatszinkronizáció történik. Ha valamilyen tennivalója van a programnak. Az alkalmazás a háttérben egy pillanatra sem áll meg. mobiltelefon esetében kb. ábra) 11-9. így garantáltan másodpercenként legalább 30-szor létrejön a kívánt kép. mint szemlélő kívülről tekintünk) renderelése. hogy volt-e valamilyen bemenet a felhasználó oldaláról – Xbox kontrolleren egy gomb lenyomása. Játékok írása során nem ezt a megközelítést szokták használni.Grafikus programozási és XNA alapok A játékciklus Amikor alkalmazásokat fejlesztünk. betöltjük a tartalmakat (képek. akkor jöhet a képszintézis. hanem az úgynevezett játékciklusos megoldást. Mindezt másodpercenként 30 alkalommal végezzük el. így a folytonosság. Ha a felhasználó a menüben a kilépésre kattint (Windows Phone esetében ezt a szerepet a Vissza gomb kapta). billentyű illetve egérkattintás. majd amikor nincs több feladata. Ez azt jelenti. akkor a ciklusból kilépünk. akkor megáll. és amit.0) típusú projektre lesz szükségünk (11-10. Windows Phone telefon képernyőjének megérintése. ez az eseményvezérelt szemlélet sajátossága. Természetesen ez csak elgondolás szintjén történik így. amely hatására megtörténik a képszintézis (adott képkocka létrehozása – továbbiakban csak renderelésként fogjuk említeni). Először megnézzük. hogy „fut”. akkor kezeljük azt. modellek. Ez eddig tökéletesen működőképes elgondolás. egy olyan környezethez vagyunk hozzászokva. a fizikai szimulációt. majd továbblépünk például a mesterséges intelligencia lépéseinek a számítására. ahol a központi szerepet az események kapják.). és hozzunk létre egy új projektet! Itt a C# nyelvű sablonokat tartalmazó szekción belül válasszuk ki az XNA Game Studio 4. Ha pedig ez is megtörtént.

de a fejezet során megnézzük a működését. ábra: Új XNA projekt létrehozása Visual Studio-ban Minden sablont nem tudunk részletesen megvizsgálni ebben a fejezetben. hogy melyik mire használható:    Windows Phone Game: Ez az alapja a leendő XNA játékunknak. álljon itt egy rövid összefoglalás arról. amelyet az alkalmazás elemeinek dekompozíciójához tudunk felhasználni.  Mielőtt részletesen megnéznénk. A tartalomkezelőről még nem beszéltünk. Az inicializáláshoz szükséges részeket.5 újdonság. alapbeállításokat. Windows Phone Silverlight and XNA Application: A Mangóhoz szorosan kapcsolódó Windows Phone 7. amely lehetővé teszi. a tartalomkezelőt és a játékciklust tartalmazza. Content Pipeline Extension Library: Ezzel a projekttípussal saját fájlformátumunkhoz készíthetünk feldolgozót a tartalomkezelő számára. hogy a projekt milyen részekből épül fel. ábra: Egyszerű XNA sablon emulátoron való futtatása 278 . emulátor segítségével próbáljuk ki az alkalmazást! 11-11.11. Játékok a Mango világában 11-10. hogy az XNA és Silverlight környezeteket együtt használjuk. Windows Phone Game Library: A fordítás során DLL fájl keletkezik belőle.

Framework. az átkódolt állomány mérete jelentősen nagyobb lehet.CornflowerBlue). akkor arra lehetőségünk van a Pipeline Extension projekttípus segítségével. vagy valamilyen saját. public Game1() { graphics = new GraphicsDeviceManager(this).Pressed) this.Back == ButtonState. általunk készített formátumhoz szeretnénk értelmezőt készíteni. A tartalomkezelő kódból való használatát még a későbbiekben látni fogjuk. hogy az XNA számára kezelhető formátumba kerülnek átalakításra. } protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice). és így tovább. a modellek. } protected override void Initialize() { base. akkor láthatjuk.Update(gameTime). amely azt jelenti. Ha a tartalomkezelő nem támogat egy fájlformátumot.Game { GraphicsDeviceManager graphics. mivel a PNG formátumú képfájlunkból a Visual Studio egy bináris képfájlt készít. a zenék. melynek feladata egy helyre összegyűjteni a játékhoz tartozó tartalmakat. TargetElapsedTime = TimeSpan.Buttons.png! Amikor a tartalomkezelőtől ezt az állományt lekérjük majd. SpriteBatch spriteBatch.Clear(Color. a hangok. base. Hiába dolgozunk valamilyen tömörítési algoritmust használó médiaformátummal. amely a Game1. Nézzük meg a tartalmát: public class Game1 : Microsoft. Miért van erre szükség? Az XNA alatt a különböző fájlokat nem fájlokként fogjuk használni. ahol kódunkat fogjuk írni. amelynek a neve xnalogo. melyet az XNA majd értelmezni tud. Az egyik maga a játék.Xna.RootDirectory = „Content”. Content. hogy a XAP fájl méretét jelentősen növelni tudják a képek és zenék. Amikor a játék forráskódját Visual Studio-ban lefordítjuk. mint például a textúrák. hanem a tartalomkezelő rendszer segítségével tudjuk betölteni. És itt felhívom a figyelmet arra.Exit(). } protected override void Draw(GameTime gameTime) { GraphicsDevice.FromSeconds(1).Grafikus programozási és XNA alapok A Visual Studio két projektet készített elő számunkra.GetState(PlayerIndex. a másik viszont egy tartalomkezelő (Content Pipeline) projekt. } protected override void UnloadContent() { } protected override void Update(GameTime gameTime) { if (GamePad. hogy a program teljes feladatát pillanatnyilag a Game1 osztály látja el.FromTicks(333333). mivel az már egy belső formátumra kerül átalakításra. Ha áttérünk a játék kódját tartalmazó projektre. Tekintsünk például egy textúrát. InactiveSleepTime = TimeSpan.cs fájlban található. 279 . olyankor a tartalomfájlok is átdolgozásra kerülnek.Initialize(). és abból egy XAP fájl keletkezik (melyet aztán a telefonra tudunk telepíteni).One). a kiterjesztését az elérési útban már nem fogjuk szerepeltetni.

a státuszsort eltüntetni. graphics. és érdemes is minden esetben betartani. amely az osztályhoz tartozó SpriteBatch példányt hozza létre. OpenGL és Direct3D használata esetében a játékmotor feladata az.Draw(gameTime). azonban nem használja ki a grafikuskártyák adta legkülönfélébb speciális funkciókat. Az XNA keretrendszer egyszerűsíti ennek a folyamatnak a lépéseit. míg a második a memóriából való felszabadításért felel. láthattuk. graphics. ami az XNA és a hardver által támogatott. Ha valamit nem támogat a hardver. Ahhoz. mint amilyennek eredetileg terveztük. Ahogy a nevük is mutatja. és nem is használja a teljes képernyőt. Kétféle profilt használhatunk. hogy biztosak lehetünk. akkor a CPU-nak is átadható a feladat. akkor kerül sorra a Draw meghívása. A másik profil a HiDef. A másodpercenkénti képkockák számát (frames per second) harmincra korlátozza. Ha az Update lefutott. a játék logikáját és minden egyéb számítást. hogy az adott funkciót nem használhatjuk ki. nem érdemes vele próbálkozni. amely a tartalmak kezelésével foglalkozik. 280 . Így csak az marad. Ennek az objektumnak a feladata közvetlen kapcsolatba lépve a grafikus hardverrel. A Draw() és az Update() metódusok a játékciklus részei. hogy az alkalmazás futni fog az adott célhardveren. ábra). Amikor emulátorban lefuttattuk a programot. Itt nincsenek limitációink. hogy a felbontása nem megfelelő.11. és lekérdezni a fejezet korábbi részében tárgyalt profilbeállításokat. hogy mi magunk állítsuk be a felbontást a Windows Phone telefonok által pillanatnyilag egységesen támogatott 480×800 pixeles méretűre. A LoadContent() metódus elején található egy nagyon fontos sor. és ezzel teljes képernyőssé tenni a programot. Itt tudjuk például beállítani a játék felbontását. A konstruktor tartalmaz még két fontos beállítást. } } A GraphicsDeviceManager objektum segít elérni a program számára használható beállításokat.PreferredBackBufferWidth = 480. Játékok a Mango világában base. Az előnye. hogy kiderítse az adott hardver képességeit − sajnos nem rendelkezik minden egyes grafikuskártya ugyanazokkal a képességekkel. és felrajzolja a színterünket pillanatnyi állapotnak megfelelően. Az első a betöltésért.IsFullScreen = true. az Update felel a mögöttes számításokért. hol fogjuk a tartalomkezelő segítségével elérni a játékhoz tartozó fájlokat. hogy az a későbbiekben a 2D-s képeinket (ezek az ún. helyezzük el a következő kódsorokat az osztály konstruktorán belül: graphics = new GraphicsDeviceManager(this). azt szabadon használhatjuk. azonban ennek a sebessége katasztrofális. sprite-ok) kirajzolja. A Reach profil mind a három platformon azonosan működik. Továbbá definiálja. amely a telefonokon futó játékprogramok számára irányelv. amely először törli a rasztertár előző tartalmát.PreferredBackBufferHeight = 800. minden. graphics. amelyre a játéknak szüksége van. A profilbeállítások az XNA projektre kattintva a Properties szekcióban találhatók (11-12. és a játék grafikája már nem lesz olyan szép. Két külön metódusunk van. Itt érdemes kezelnünk a bemeneteket.

akkor ezeket a négyszögeket kell mozgatnunk a képernyő dimenziói között.Begin() és SpriteBatch. 281 . Ha fehértől eltérőt adunk meg. hogy alakzatokkal foglalkozzunk. nem foglalkozunk 3D-s tartalmakkal. Ugyanaz a négyszög. A Draw több paraméterezéssel is elérhető.Clear() metódusa végez el. 2. Itt is tudunk létrehozni mappákat és almappákat. A kirajzolandó textúra objektum. A kirajzolandó textúra objektum. ábra: XNA alkalmazásprofilok Sprite-ok Ahogy azt már a fejezet korábbi részében leszögeztük. Ha a képernyőt töröltük. és ennek egyetlen paramétere a törlési szín megadása. Itt mindig a tartalom Content projekten belüli elérési útjára hivatkozzunk és az adott fájl kiterjesztését hagyjuk le. amely a tartalomvezérlőtől le tudja kérni a szükséges képinformációkat. ezek közül kettő fontos számunkra: Az első paraméterezésben szereplő paraméterek sorrendben: 1. a második kettő pedig a sprite mérete pixelekben kifejezve. A textúrát lehetőségünk van összemosni egy másik színnel. Ha valamilyen interakció történik. A tartalom (jelen esetben ez a textúra) lekérést a Content. amely első két paramétere a sprite pozíciója. akkor jöhet a tényleges rajzolás. Ezek után megkezdhetjük a sprite kirajzolását! Ez mindig képernyő (pontosabban a rasztertár) törlésével kezdődik. ezek a képek egy négyszög területét töltik ki. és azoknak a csúcspontjai alapján hajtsuk végre a renderelést. 2.Grafikus programozási és XNA alapok 11-12. a képernyő összes pixele ezt a színt veszi fel. Egy négyszög. A második paraméterezés: 1. Egy térbeli játék esetében szükséges lenne. Gondoljunk csak bele egy egyszerű 2D-s játék esetében képeket rajzolunk fel. csak a 2D-s játékok fejlesztéséhez szükséges elméleti és gyakorlati anyagokat vesszük sorra. mivel a tartalomkezelő számára ez átalakításra kerül a projekt fordítása során. esetleg automatizálható. Ez mindig a SpriteBatch.Load<T>() generikus metódus segítségével tudjuk elvégezni. azonban most sokkal könnyebb dolgunk lesz. Mivel nincs még képünk.End() metódushívások között történik a Draw metódus hívásával. amelybe típusuktól függően rendezhetjük a fájlokat. és helyezzük el a Content projekten belül! Tipp: a tartalomkezelő (Content) projekten belül mindig érdemes rendet tartani. 3. így keressünk egy tetszőleges PNG vagy JPG fájlt. Hogyan tudunk egy képet megjeleníteni XNA-ban? Textúraként. így a betöltés kódból sokkal strukturáltabb lesz. akkor a textúra pixelei összeszorzásra kerülnek az adott színnel. amelyet a GraphicsDevice. amely az előző paraméterezés esetében is. Ebben a feladatban a Texture2D objektum fog segíteni.

A következő kód egy textúrát rajzol ki két különböző módon: private Texture2D xnaLogo.White ). 1] közötti valós számok segítségével. new Rectangle( 200. ábra szemlélteti. Color. Jelentőségét az ún. spriteBatch. telefonon is kipróbálhatjuk. xnaLogo = Content.Draw( xnaLogo. A sprite horizontális illetve vertikális tükrözésére van lehetőségünk a SpriteEffects osztály használatával. így a mélységi sorrendjüket megváltoztatni szükséges. 11-13. 400. Z-tengely körüli (a képernyő síkjában) való forgatás valós szöggel kifejezve.Zero. spriteBatch.Draw(gameTime). 114 ). SpriteEffects. sprite sheetek létrehozásakor fogjuk látni a fejezet egy későbbi részében. akkor nyugodtan próbáljuk ki emulátorban az alkalmazást (ha van rá lehetőségünk. protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice).Begin().Draw( xnaLogo. spriteBatch. spriteBatch. hogy az adott sprite a többi előtt vagy mögött helyezkedik-e el. Z-Index: ez egy nagyon fontos paraméter! Ezzel adhatjuk meg [0. 0.CornflowerBlue. egy egyszerű kétdimenziós játékban nem szeretnénk. 7. ha egy fűcsomó vagy bokor lenne a játékosunk előtt.0f. Egy újabb négyszög. 230. } Ha a kódot implementáltuk és a megfelelő képfájl a Content projekt része. Color. 45. 230. 8.End(). 400.0f ). 5. 4. amely segítségével a textúrából egy darabot ki tudunk vágni.Load<Texture2D>( @"xna-logo" ). } protected override void Draw(GameTime gameTime) { GraphicsDevice. Játékok a Mango világában 3. null. A program futását a 11-13. Vector2. 0 ).Clear(Color.FlipVertically. Pl.Black). 6. 114 ). ugyanazt az eredményt fogjuk kapni). ezzel mélységi sorrendet tudunk kialakítani. A sprite origójának megadása.11. base. Az összemosási szín. ábra: Két sprite kirajzolása két különböző módon 282 . new Rectangle( 200. Alapesetben ez a képernyő bal felső sarka (0.

Ha nem kérjük az operációs rendszer segítségét. hogy egy tömbben visszakapjuk azokat az (X. Az 11-14. hanem mi magunk szeretnénk feldolgozni minden bemeneti információt. A telefonok azonos időben egyszerre több érintést képesek lekezelni a képernyőjükön keresztül. Ebből saját algoritmussal kell megállapítanunk. amelyek bizonyos érintésmódok hatására aktiválódnak. Ilyen lehet például egy egyszerű. Az érintések kezelésére többféle lehetőségünk is van. ami azt jelenti. mivel az teljesen más egy Xbox és egy PC esetében is. Y) koordinátákat.Grafikus programozási és XNA alapok Bemenetek kezelése Minden egyes XNA által támogatott eszközre külön meg lehetne nézni a bemenetek kezelését. és a programozó számára már események képében kerülnek megvalósításra. Az operációs rendszer beépítve tartalmaz mintákat (gestures). 11-14. ábra a különböző érintésmintákat mutatja be. Azonban a Windows Phone magas szintű támogatást nyújt az érintéspontok kezelésére. vagy egymás után gyorsan végrehajtva két rövid érintés (double tap). így az alkalmazásainkat egy Multi Touch (több érintést kezelő) környezetre kell kialakítanunk. akkor lehetőségünk van a „nyers” érintésadatok lekérésére. ábra: Érintésminták Windows Phone Mangón 283 . pár pillanatig tartó érintés (tap). hogy a program milyen választ szolgáltasson a bemenet hatására. Ebben a fejezetben mi a Windows Phone Mangóra szeretnénk játékokat írni. ahol a képernyőhöz ért a felhasználó. de ez lehet akár egy folyamatos mozgatás is a képernyő felületén (touch and hold).

Ha több minta is engedélyezve van. akkor a Windows Phone logót ábrázoló textúrát elmozdítjuk az érintés irányába.FreeDrag: position = new Point( (int)gesture. a másik pedig a szabad. amelyekkel dolgozni szeretnénk. akkor elkezdjük azokat feldolgozni.IsGestureAvailable tulajdonságának lekérdezése –. Ha a gesztusok engedélyezésre kerültek. ahol felsoroljuk a használni kívánt érintésmintákat. base. xnaLogo = Content. Megkérjük az operációs rendszert. } } base. protected override void Initialize() { TouchPanel.White.ReadGesture(). } 284 .Y . Az egyik az egyszerű érintés. ha pedig a szabadon való mozgatás. private private private private Texture2D xnaLogo. break.177 / 2 ). Az EnableGestures tulajdonságát a GestureType elemeivel kell feltöltenünk. akkor meg kell vizsgálnunk a minta típusát. break. akkor a játékciklusunk Update szekciójában folyamatosan figyelnünk kell.X .149 / 2. Ha voltak interakciók –ennek ellenőrzéséhez nem kell más. (int)gesture.FreeDrag | GestureType. Ezt a TouchPanel.Position.White.ReadGesture() metódusa teszi. wp7Logo = Content.GestureType ) { case GestureType. position = Point.Position. A következő kis mintaalkalmazás két mintát figyel.Tap: clearColor = clearColor == Color. case GestureType. Texture2D wp7Logo. mint a TouchPanel. hogy volt-e valamilyen bemenet. Ezt a TouchPanel objektumon keresztül tudjuk megtenni.Load<Texture2D>( @"wp7-logo" ). Az egyes elemeket logikai “vagy” művelet segítségével tudjuk felsorolni.Load<Texture2D>( @"xna-logo" ). switch ( gesture. Ha egyszerű érintés törént.Black : Color. hogy szolgáltassa vissza számunkra azt a érintésmintát.EnabledGestures = GestureType. } protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice).IsGestureAvailable ) { GestureSample gesture = TouchPanel. } protected override void Update(GameTime gameTime) { while ( TouchPanel. amelyiket legutoljára észlelt. Játékok a Mango világában Az érintésminták feldolgozása az XNA alkalmazásokban nagyon könnyen elvégezhető! Első dolgunk engedélyezni a program számára azokat a gesztusokat.Tap.Initialize(). akkor megváltoztatjuk a program háttérszínét. Color clearColor = Color.Zero.White ? Color. folyamatos mozgatás a képernyő felületén.Update(gameTime). Point position.11.

a belül található objektumok között lehetetlen az ütközés. hogy teljesen megöli. hogy tudjuk.End(). pl. stb. akkor velük már nem is 285 . 230. hogy B szereplő valamelyik poligonjával ütközött-e. } Az érintések hatásait a 11-15. spriteBatch. téglatest. hogy ha egy lövöldözős játékban nem kezeljük le a lövedék becsapódását. így sokszögek sokszöggel való ütközését (metszését) kell kezelnünk. ha az objektum köré valami sokkal egyszerűbb térgeometriai alakzatot vonunk. ezért különböző struktúrákat és eljárásokat szoktak még bevezetni. ezért más módszerre lesz szükségünk! Sokkal jobb megoldás az. 114 ).Draw( wp7Logo.Grafikus programozási és XNA alapok protected override void Draw(GameTime gameTime) { GraphicsDevice. new Rectangle( position. a golyó szabadon elrepülhet a végtelenbe. ábrán láthatjuk. position. akkor sokkal kevesebb számítással jutunk eredményre. és levontuk a következtetést: egy grafikus alkalmazásban minden matematikai alapra vezethető vissza. Ez a játékélményt nemcsak. Gondoljunk csak bele. Miután összetett alakzatokról beszélünk. ábra: Az érintések hatása a mintaalkalmazásban Ütközések detektálása Az ütközések észlelése.White ).Y.Clear( clearColor ). akkor is az A szereplő összes poligonjára meg kell vizsgálnunk. 256.White ). spriteBatch. Ha csak két szereplőt nézünk.X. azaz a játék objektumainak egymással való ütköztetése minden játékban nagyon fontos szerepet tölt be.Draw( xnaLogo. de a felhasználó szempontjából hibásnak tünteti fel a programunkat – amely teljesen jogos következtetés! Hogyan történik az ütközések kezelése? Először nézzük meg ezt általánosítva! A fejezet korábbi részében alaposan kiveséztük a poligonvázak felépítését. new Rectangle( 200. Ez még kevés objektum esetén is jelentősen vissza tudja fogni a teljesítményt.Begin(). 102 ). Color. és ha két cella olyan helyzetben van egymáshoz képest. gömb. Viszont sok objektum esetében még ez is lassuláshoz vezethet. 400. spriteBatch. spriteBatch. Color. Például a BSP vagy a Quad fa a teret cellákra osztja fel. base. Ha ezeknek az ütközését figyeljük. 11-15.Draw(gameTime).

Négyszögekkel fogjuk körülvenni az alakzatokat. new Rectangle( position. ahol eltekintünk a különböző forgatásoktól. és ennek függvényében haladunk tovább a játékban. Az Update() metóduson belül folyamatosan figyeljük. hogy pontosan melyik esetről is van szó.11.Draw( wp7Logo. és a képernyő megérintésével például lehetőségünk van fékezni. Ha két négyszög akármilyen formában is metszi egymást. position. if ( IsCollision() ) logoColor = Color. 256. Ha az előbbiről van szó. . fontos megkülönböztetnünk.Update(gameTime). 114 ).Y. amikor magát a virtuális objektumot animáljuk. base. hogy metszik-e egymást. 102 ). position. private Color logoColor = Color. 400.. mennyire forgatjuk el. Axis Aligned Bounding Volume-nak hívják. akkor a meglévő objektumot mozgatjuk a térben különböző szabályok alapján. } Animációk Amikor számítógépes játékokban animációról beszélünk. és a kódban kell meghatároznunk.. Amikor a telefon mozgatásának segítségével egy autót kormányozunk. és ebből valamilyen valósághű 286 .White. else logoColor = Color. Meghatározhatunk görbéket (utakat). különböző módokon kombinálva és továbbfejlesztve azokat.. Azokat a befogó alakzatokat. amin az objektum végighaladhat. és ha igen. az adott geometriának a pontjait körülményes lenne külön-külön transzformálni. az autós példánál maradva. akkor az egyik objektumot átszínezzük.. nagyítjuk fel. részletes leírásokat lehet találni Wikipedián. így jóval egyszerűbb esetekre kell csak felkészülnünk.. A mai játékok jelentős hányada is ezeket a megközelítéseket használja. vagy mennyire kicsinyítjük le.X.. hogy volt-e ütközés. akár egyes pontjaiban más animációkkal kombinálva folytatódhat tovább a cselekmény. akkor programozottan. Játékok a Mango világában számolunk. Az IsCollision() metódus a két befogó négyszöget megnézi. és annak is a könnyebben kezelhető formájával. és az ennek megfelelő logikai értéket dobja vissza. } protected override void Update(GameTime gameTime) { . protected bool IsCollision() { Rectangle xna = new Rectangle( 200. Egy másik eset az.White.X.Intersects( wp7 ). akkor ütközés történt. 102 ).Y. az autónak több tengely körül forognak a kerekei vagy akár kinyílhatnak az ajtói. 256. Szerencsére mi kétdimenziós környezetben dolgozunk. return xna. } protected override void Draw(GameTime gameTime) { . Viszont a második esetben nem tudjuk kódból (legalábbis csak nagyon nehézkesen) létrehozni az előbb említett lépéseket.Yellow. Rectangle wp7 = new Rectangle( position. logoColor ). amik a sík/térbeli forgatásokra is fel vannak készítve. 230. kódból kell az animációt létrehoznunk. hogy az alakzatot merre toljuk el térben. spriteBatch.

Helyette a sprite sheet nevezetű megoldást fogjuk használni. amelyet úgy dolgozunk fel. 287 . amíg a végére nem érünk az adott animációnak. gyorsan megjeleníteni. Egy másodperc animációhoz tegyük fel. hogy egy térd mekkora szögben és merrefelé tud hajlani. hogy szükség lenne 30 képkockára. mivel a fizikai motor szintén felhasználhatja a csontokat rugalmas testek fizikai hatásainak modellezéséhez. akkor a poligonváznak hogyan kell ahhoz alkalmazkodnia és deformálódnia. akkor az animáció lehetne a képek egymás után váltakozása adott sebességgel. 11-16. Az animáció összes lépése egy adott képfájlban kerül eltárolásra. transzformálódnia a térben. A 11-17. akkor a poligonmodellel összeköti és definiálja az anyagtulajdonságokat. ábrán egy futónak az animációját bemutató sprite sheet látható. hogy sorra vesszük a kép X × Y méretű részeit. A térbeli animálásnak rengeteg aspektusa létezik. ízületi részekkel összeköti őket. stb) szokták végrehajtani. ábra mutatja be. hogy ha a csontozat mozog. A grafikus szakember a csontokat animálja. Ha ez megvan. akkor a következő sorban folytatjuk a „kis képek” kivagdosását. ábra: Csontozásos animáció – Unreal Engine Két dimenzióban azonban nincsenek olyan poligonok. Továbbá a csontozásos rendszer segít a játéktérben való adaptációban is. Maya. Ha egy soron végigértünk. amelyek a program komplexitását jelentősen növelni tudják. amelyen a híres Unreal Engine játékmotor karakteranimálása látható. „csontozáson” alapuló karakter animációkat alkalmaz.Grafikus programozási és XNA alapok mozgást előállítani. amely megszabja például. azok kezelését jelentősen túlbonyolítanánk. ráadásul feleslegesen. amelyeket animálni lehetne akármelyik módszert is használva. ezért ezt valamilyen modellező alkalmazás segítségével (3D Studio Max. A csontozásos animációt az 11-16. Adott egy ötlet: ha a karaktereket sprite-ként jelenítjük meg. 30 külön képfájlban tárolva a képeket. Rhino 3D. Ezek a tulajdonságok azt írják le. Ehhez 30 különböző képet kell egymás után. ezt kiegészítve ízületekkel és a csontok bőrhöz (skin) való igazításával. A modern játékok jelentős része – megint csak a valós életre visszavezetve – ún.

Az egyik a frissítésért felel (Update). mint a felhők. akkor a valóságban eltelt idő mérése nem lesz elegendő. hogy a fenti kép egy 6 × 5 = 30 képkockás animációt tartalmaz. de nem lehet minden animációnak azonos a sebessége. a másik pedig a kirajzolásért (Draw). ábra: Egy futó animációjának leírása sprite sheettel Látható. akkor a későbbiekben nem kell a metódusokról saját magunknak gondoskodnunk. 288 . ha a játék nem futtatható valamilyen eszközön megfelelő sebességgel. oszlop)? Texture – Az a Texture2D objektumpéldány. a játékciklus megfelelő helyein meghívásra fognak kerülni. hogy az adott animációt milyen sebességgel játssza le. Y) koordinátái. amelyen szabályozható. Nézzük. Az osztály tetszés és igény szerint tovább bővíthető. ha például egy autó ugyanolyan sebességgel haladna. oszlopban)? CurrentFrame – Éppen melyik képet jelenítjük meg (sor. SheetSize – Hány képkockát tartalmaz a sprite sheet (sorban. de a fenti tulajdonságok megvalósításával a program legtöbb esetben már így is jól használhatónak fog bizonyulni. A telefonon egy játék 30 FPS-szel fut. Ennek feladata a játékban eltelt idő mérése. Rotation – Z-tengely körüli elforgatás mértéke szögben mérve. magasság). A frissítést megvalósító metódus paraméterül kap egy GameTime objektumpéldányt. A következőkben egy olyan sprite sheet osztályt fogunk készíteni. az teljesen furcsa hatást keltene. milyen tulajdonságokra lesz szükségünk az osztályban:        FrameSize – Egyetlen képkocka mérete (szélesség. Játékok a Mango világában 11-17. FrameRate – Az animáció sebessége (képkocka per másodperc). Miért van erre szükség? Gondoljunk csak bele. Position – A kirajzolandó sprite (X. Ha az osztályt a GameComponent ősosztályból származtatjuk. amely a sprite sheetet tartalmazza. Két metódust kell létrehoznunk.11.

FrameRate = speed.Y * CurrentFrame. x++.White. new Rectangle( Position. FrameSize. akkor a CurrentFrame tulajdonságot megfelelően növeljük. eltelt-e már annyi idő. set.X. Texture = tex. Rotation. Texture2D tex. y++. A második paraméter feladata megmondani az XNA-nak.Grafikus programozási és XNA alapok szükségünk lesz egy olyan időmérési módszerre is. ha igen.Draw( Texture. } public Point Position { get. } public void Draw( SpriteBatch spriteBatch ) { spriteBatch. Itt kell megadnunk. set.X ) { x = 0.X.Y. Color. set. FrameSize. A rajzolásért felelős kódunk a már ismert SpriteBatch. } public SpriteSheet( Game game. if ( y >= SheetSize. } public Texture2D Texture { get.None. } public Point CurrentFrame { get.X.X * CurrentFrame.Y.ElapsedGameTime.0f ). FrameSize. set. A metóduson belül megnézzük. } public float Rotation { get. Point frameSize. Vector2.Y ) 289 . int y = CurrentFrame. SheetSize = sheetSize.X. Y) pozícióba rajzolja fel a textúrát és mekkora méretekkel. set. } public Point SheetSize { get.Milliseconds.X.Y ). hogy a következő képkockára mutasson.Zero. FrameSize. public class SpriteSheet : GameComponent { public Point FrameSize { get. A harmadik paraméter már egy kicsit izgalmasabb. hogy mekkora darabját rajzolja ki az eredeti sheet-nek. 0. set. if ( x >= SheetSize. A Draw() metódus többi paraméterét a fejezet korábbi részében már átbeszéltük. new Rectangle( FrameSize.Zero. Point sheetSize. int x = CurrentFrame. if ( timeSinceLastRender > ( 1000 / FrameRate ) ) { timeSinceLastRender -= 1000 / FrameRate.Y. Itt sorszám × képkocka_szélesség és oszlopszám × képkocka_magasság értékekkel kell számolnunk. amely a játékunk „lassult” végrehajtási sebességéhez igazodik.Draw() metódust hívja egy más paraméterezési móddal. } private int timeSinceLastRender = 0. Számunkra itt a második és a harmadik paraméterek a fontosak. } public override void Update(GameTime gameTime) { timeSinceLastRender += gameTime. FrameSize. public int FrameRate { get. hogy melyik (X. int speed ) : base( game ) { CurrentFrame = Point. FrameSize = frameSize. Position. set. ami az FPS számunknak megfelelő. SpriteEffects. mint amit a fejezet korábbi részében használtunk.Y ).

20 ). ennek következtében az Update() metóduson belül az XNA automatikusan hívni fogja az objektumhoz tartozó Update() metódust.Draw(gameTime). } CurrentFrame = new Point( x.296 ) / 2 ). Az emulátoron való futtatás eredményét a 11-18.Begin(). ábra: A sprite animáció egy pillanatfelvétele 290 .Position = new Point( ( 480 .Update(gameTime).240 ) / 2. 5 ). } } Ha az osztály készen van. private SpriteSheet walk. new Point( 6. akkor a Game1. majd a játék komponensei közé felvesszük az objektumpéldányt. Játékok a Mango világában y = 0. } base.End().Draw( spriteBatch ). protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice).Clear( clearColor ). new Point( 240. } 11-18. 296 ). Components.cs fájlban használjuk is fel! Hozzunk létre egy új adattagot. y ). ( 800 .11. spriteBatch. } protected override void Draw(GameTime gameTime) { GraphicsDevice. base.Load<Texture2D>( "walk" ).Add( walk ). walk. amely az újonnan létrehozott osztály egy példánya! A LoadContent() metóduson belül szükséges inicializálnunk. walk. A pozícióját a képernyő közepére kiszámítva adjuk meg. Content. spriteBatch. ábra illusztrálja. walk = new SpriteSheet( this.

és ezenkívül számos egyéb is megtalálható az állapotgráfban. miközben nem ütközik se saját testébe. így például egy Silverlightot használó programban nem jeleníthettünk meg semmilyen XNA tartalmat. textúrázott poligonmodelleket is meg tudunk jeleníteni. stb. azaz Silverlight alkalmazásokban akár háromdimenziós. hogy lekezeljük a bemenetet. Azonban figyelnünk kell arra. amely jelen esetben csak egy érintés a telefon képernyőjén! Ha az érintés koordinátái az adott gomb által takart síkrészbe tartoznak. a különböző játékélmény-elemek kialakítása már a kedves Olvasó feladata. A Mango egyik nagy újdonsága. pl: menü megjelenítése. amelyeket nem játékalkalmazásokban már megszoktunk. hogy a pályán véletlenszerűen megjelenő eleségeket összegyűjtse. A pályán másra nem is nagyon lesz szükségünk. mentés megjelenítése. egy Snake játékot fogunk írni. ahol a szereplőnk apró blokkokból épül fel. illetve egy apró pontot ábrázoló textúrát fogunk a kígyó szegmensekhez felhasználni. Azonban a két technológia fúziója kérdéseket vet fel! Az egyik játékciklust használ. melyet Silverlight segítségével valósítunk meg. és a játékos feladata úgy irányítani a kígyót. Ez a leírás csak a játék alapjait fogja bemutatni. A játékot bonyolítja. hogy valahol ne ütközzön. hogy az XNA és Silverlight együttműködését gyakorlatban is megismerjük. amíg a Silverlight vektoralapon számított vezérlőkkel látja el ezt a feladatot. a pontszámítás. A felrajzolás ugyanúgy a játékciklusban történik. Ezt úgy képzeljük el. Hogyan tudjuk a különböző tartalmakat megjeleníteni? Ezekre a kérdésekre kapunk válaszokat ebben a részben.XNA és Silverlight integráció XNA és Silverlight integráció A Windows Phone 7 első verziója még élesen szétválasztotta az XNA és a Silverlight által képviselt két külön világot. azonban ezeknek az elkészítése körülményesebb sokkal. Hogyan tudjuk a kettőt közös nevezőre hozni? Az XNA pixelalapú tartalmakat rajzol ki. ha nincs a segítségünkre a Silverlight. A pálya hátterét a 11-19 ábrán látható 480×800 pixel felbontású textúra fogja adni. akkor végrehajtunk valamilyen eseményt. se a pályát határoló falakba. amely az egyes alkalmazásoldalak között tud minket átvinni. Mivel a játékciklus másodpercenként harmincszor lejátszódik. Valószínűleg mindenki jól ismeri a klasszikus kígyós játékot. hogy képes hibrid renderelésre. szövegmezőket még magunknak kell implementálnunk. 291 . ahol maga a játék irányítása csak egyetlen állapotot jelent. hogy a gombot csak egyszer tekintsük lenyomottnak. Érdekesség: természetesen XNA-ban is készülnek különböző menürendszerek és „vezérlők”. játék vége állapot. A játékot mint egy nagy állapotgépet kell elképzelnünk. akkor a gombokat. listadobozokat. hogy minden egyes eleségdarabka felszedése után a kígyó hosszabb lesz. Silverlight és XNA együtt a gyakorlatban Ahhoz. így a gombnyomás is harmincszor hajtódna végre. és nincsen navigációs rendszerünk. míg a másik egy eseményvezérelt környezetet valósít meg. még egy elemet leszámítva: a szüneteltetés gomb. teljes mértékben a kreativitására bízom. így nehezebb lesz elkerülni. Így ha sikeresen ki is alakítunk egy menürendszert.

xaml fájlt. hogy a fő projekt tartalmazza a Silverlight alkalmazásokban jól megszokott MainPage. Y) koordinátákkal Direction: az aktuális irány. a másik viszont újdonság. Miután a projektet létrehoztuk. Az egyik az XNA tartalomkezelője. amely hivatkozik a Content projektre. Játékok a Mango világában 11-19 ábra: a Snake játék háttértextúrája Hozzunk létre egy új projektet. a neve pedig Snake. Továbbá bővült a projektünk az eddigiekhez képest egy GamePage. Készült még két projekt. amerre haladnia kell (irányvektorként tekintsünk rá) PrevDirection: akkor fogjuk felhasználni. A játék jelentős részét itt fogjuk megírni. amely a kígyónak a szegmenseit tárolja.xaml fájllal is. és a tartalma a következő osztálydefiníció a megfelelő tulajdonságokkal: 292 . Minden egyes szegmensről tudnunk kell a következő információkat:     Position: a szegmens pozíciója a játék felületén (X. amikor a kígyó kanyarodik valamerre Texture: a kígyószegmens textúrája Hozzunk is létre egy új osztályt a SnakeLib projekten belül.11. a mögöttes kód viszont az XNA-val való együttműködésre fel lett készítve. szükségünk lesz egy osztályra. melynek deklaratív része teljes mértékben üres. melynek neve SnakeBlock. ennek a típusa most Windows Phone Silverlight and XNA Application legyen. ahogy a 11-20 ábrán is látható! 11-20 ábra: új projekt létrehozása a játékhoz Látható. amellyel már találkoztunk a fejezet során. Egy XNA könyvtár. amely a felhasználói felületünknek az alapját jelenti. hogy elkészítsük benne az XNA komponenseinket. továbbá alkalmas arra.

1 ).Y . Először is szükséges egy lista.Y * 3 * 16 ) } ).Y * 2 * 16 ) } ).contentMgr = cm. private readonly Vector2 baseDir = new Vector2( 0. } } Ha megvagyunk a szegmens osztállyal.baseDir. és ehhez tároljuk le az utolsó frissítés időpontját! A konstruktor feltölti kezdeti értékkel az adattagokat. set. Ezt is a SnakeLib nevezetű XNA projekten belül. amely magát a kígyót és a viselkedéséhez szükséges elemeknek egy nagy részét tartalmazza.X. nem visszük túlzásba az objektum-dekompozíciót).PrevDirection = snake[ 0 ]. private DateTime lastTime = DateTime. Állítsuk majd be mondjuk fél másodpercenkénti frissítésre.Y * 1 * 16 ) } ). Position = new Vector2( basePos. } // megállítható lesz a játék Silverlight UI-ról public SnakeObject( ContentManager cm ) { this. } public Vector2 Direction { get.Add( new SnakeBlock { Direction = baseDir. } public Vector2 PrevDirection { get. a ContentManager létező példányát is át kell majd adni konstruktoron keresztül és letárolni azt. akkor készítenünk kell még egy másik osztályt is (ígérem. amitől teljesen irányíthatatlanná válik. Position = new Vector2( basePos. egy kezdeti irány. snake. public bool IsPaused { get.baseDir. basePos.Direction. Ha nem korlátozzuk valamilyen módon. private set. } public Texture2D Texture { get.Add( new SnakeBlock { Direction = baseDir. set.és pozícióvektor. basePos.XNA és Silverlight integráció public class SnakeBlock { public Vector2 Position { get. és létrehozza az első öt szegmenst a kezdeti irány és a pozíció függvényében: public class SnakeObject { public List<SnakeBlock> snake { get.Y . set.Now. snake.X. } } 293 .X. } private ContentManager contentMgr. Position = basePos } ). set.16 ) / 2 ).Y * 4 * 16 ) } ).Y . snake[ 0 ]. basePos. basePos. akkor másodpercenként 30szor lesz léptetve a játékos. set. ( 800 . Position = new Vector2( basePos. A sebesség sem közömbös tényező.baseDir.16 ) / 2. snake = new List<SnakeBlock>().Add( new SnakeBlock { Direction = baseDir.X. Miután a textúrákat az osztály magának fogja lekérni. snake. Position = new Vector2( basePos. private readonly Vector2 basePos = new Vector2( ( 480 . amely a szegmenseket sorolja fel (kezdetben legyen ötelemű). snake.baseDir.Add( new SnakeBlock { Direction = baseDir. snake.Y .Add( new SnakeBlock { Direction = baseDir.

(int)block.Load<Texture2D>( @"Textures/sprite" ). nincs más hátra. a legegyszerűbb paraméterezési móddal fogjuk meghívni a SpriteBatch. hanem iterációnként mindig csak egy szegmens. mindegy. } Betöltöttük a textúrákat. SpriteBatch spriteBatch ) { foreach ( SnakeBlock block in snake ) spriteBatch. public void Update(GameTime gameTime) { if ( IsPaused ) return. Arkusztangens segítségével kiszámoljuk a mozdulatból származó irányvektorhoz tartozó szöget. Vector2 dir = snake[ 0 ]. 16.Position. while ( TouchPanel. gesture.X. és ennek függvényében előállítjuk a kígyó új irányát. Ezt nekünk valódi szögre kell átváltanunk.11. amelyet egy segédfüggvény végez (GetAngle). Ez egy kicsit nagyobb falat lesz. Ehhez a Direction és a PrevDirection tulajdonságokat fogjuk felhasználni.Y ). Játékok a Mango világában Következő feladatunk a megfelelő textúra betöltése a szegmensek számára. a rá következő pedig majd egy másik iterációban.ReadGesture(). Mivel az érintésminta csak azt tudja visszaadni. Amikor az új irányt meghatároztuk. A feladat egyetlen Texture2D példánnyal is megoldható lett volna. azonban szerettem volna egy automatizált megoldást mutatni ciklus segítségével. A kígyó irányításához.Position. azt fogjuk nézni. if ( 45 <= angle && angle < 135 ) { if ( dir.Delta. ezt mindenképpen le kell kezelnünk. mint azt előre gondolnánk. így az irányvektort magunknak kell meghatároznunk. A frissítésnek van még egy második része is.Delta.Flick ) { double angle = GetAngle( gesture.Texture = contentMgr. irányt mutató mozdulata merre mutat. amely jól használható olyan esetekben. public void LoadContent() { foreach ( SnakeBlock block in snake ) block. mint a frissítést végző Update() metódust megvalósítani. hogy a kígyó összes szegmense egyszerre mozduljon el az új irányba. ami fél másodpercenként a kígyót továbblépteti a felületen. Először is a képernyőn gesztusok segítségével tud navigálni a felhasználó. if ( gesture. hogy a határozott. -1 ).Y <= 0 ) dir = new Vector2( 0. amely a szegmensek között mindig egy elcsúsztatást fog jelenteni. mely tartományba mutatott az irányvektor. new Rectangle( (int)block. akkor megnézzük. nem azt szerettük volna elérni. } 294 . Color. amikor több objektum textúráit töltjük be. public void Draw( GameTime time.IsGestureAvailable ) { GestureSample gesture = TouchPanel. 16 ).White ).GestureType == GestureType. hogy hol ér a képernyőhöz. melyet radiánban mérve kapunk vissza.Draw( block. } A fejezet példáinak a végigolvasása (esetleg végigpróbálása) után a felrajzolás nem okozhat problémát. fel tudjuk rajzolni a szegmenseket.Y.Draw() metódust. Ha a szög megvan.Texture.Direction. hogy vízszintesen és függőlegesen mekkora változás történt.X. Minden egyes blokk ugyanazt a textúrát fogja kapni.

if ( num < 0. beleütközött-e a kígyó a falba vagy a saját testébe. } else if ( 225 <= angle && angle < 315 ) { if ( dir.1 ]. dir2.Y >= 0 ) dir = new Vector2( 0. deltaX ). így a függőlegesen mért értéket invertálnunk kell.Atan2( -deltaY. } snake[ 0 ].Now . } } Mivel az érintésminta nem tudott szöget meghatározni. 0 ).Direction.Y * 16 ).PrevDirection = snake[ i ].PrevDirection. double deltaY ) { double num = Math.X >= 0 ) dir = new Vector2( 1. snake[ i ]. ezért 2 × pí. lastTime = DateTime.1 ]. de a játékunk mit sem érne ütközésdetektáció nélkül.Position += new Vector2( snake[ i . 1 ).Count. snake[ i . } else { if ( dir. A képernyő és a játékunk koordinátarendszere egymáshoz képest el van forgatva.28318530717959.PrevDirection = snake[ 0 ].X <= 0 ) dir = new Vector2( -1. } } if ( ( DateTime.28318530717959 + num. i < snake.Direction.X * 16. ezt magunknak kell megtennünk.Direction. Ha előállt a megfelelő érték.TotalMilliseconds >= 500 ) { var dir2 = snake[ 0 ]. } snake[ 0 ].1 ].X * 16. ezért át kell váltanunk valós szögmértékbe. snake[ 0 ]. azaz 360 fokos forgatással számoljuk ki az adott szöget.lastTime ). 295 . snake[ 0 ]. } return num * 360.PrevDirection.0 / 6. for ( int i = 1. public static double GetAngle( double deltaX. snake[ i ].Direction. ++i ) { snake[ i ].Direction = dir. akkor az még radiánban van.PrevDirection = snake[ 0 ].Position += new Vector2( dir2. hogy eldöntse. ha igen. Két külön metódust fogunk bevezetni.XNA és Silverlight integráció else if ( 135 <= angle && angle < 225 ) { if ( dir. } Majdnem készen vagyunk a kígyót leíró osztállyal. 0 ). Az elsőnek annyi a feladata. akkor a megfelelő logikai értéket adja vissza.Now.Y * 16 ).Direction = snake[ i .0 ) { num = 6. Továbbá negatív szögekkel nem szeretnénk számolni.PrevDirection.

így a következő néhány sor kód semmilyen meglepetést nem tartogat. } return false. Továbbá létrehoztam a Click eseményvezérlőt is. for ( int i = 1. A korábbi fejezetek során részletesen láttuk. a kígyó feje érintkezett-e a pályán elszórt kinccsel.GamePage" xmlns="http://schemas. akkor adjon hozzá a kígyó testének legvégéhez egy új szegmenst. Játékok a Mango világában A másik metódus feladata pedig az.Intersects( block ) ) { var prev = snake[ snake. } A kígyót leíró osztállyal készen vagyunk. 16 ). 16 ).X * 16. Texture = prev.Direction. -prev.Position.microsoft.Y. ha igen.Y >= 784 ) return true. Rectangle snakeHead = new Rectangle( (int)snake[ 0 ].Position.Position.Position. hogy megnézze.Direction. 16 ). (int)newBlock.Controls.Shell.com/expression/blend/2008" xmlns:mc="http://schemas. (int)snake[ 0 ].Texture } ). } return false.X.Intersects( snakeBody ) ) return true. 16 ). 16. i++ ) { Rectangle snakeBody = new Rectangle( (int)snake[ i ]. } public bool DetectCollisionWithNewBlock( SnakeBlock newBlock ) { Rectangle snakeHead = new Rectangle( (int)snake[ 0 ]. A GamePage. hogy történik ez.Y.Y * 16 ). if ( snakePosition.X >= 464 ) return true. if ( snakeHead. Direction = prev.microsoft. és a képernyő jobb felső sarkába igazítottam.Phone" xmlns:d="http://schemas.11. <phone:PhoneApplicationPage x:Class="Snake.Count. i < snake. if ( snakeHead. 16.X.Direction. 16.X <= 16 || snakePosition. snake.1 ].com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Position.microsoft.Position.assembly=Microsoft.Position.X. return true.Phone.openxmlformats. A gombnak explicit méretezést adtam. Rectangle block = new Rectangle( (int)newBlock.Position. (int)snake[ i ]. és azoknak a metszésviszonyát figyeljük. if ( snakePosition.Phone.X.Count .Phone" xmlns:shell="clr-namespace:Microsoft.Add( new SnakeBlock { Position = prev.Y <= 16 || snakePosition.xaml fájlban létre kell hoznunk a szüneteltetés gombot.Y.Y.Position + new Vector2( -prev. Az ütközésvizsgálathoz megint csak jól közelített befoglaló négyszögeket használunk. public bool DetectCollision() { var snakePosition = snake[ 0 ].assembly=Microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas. (int)snake[ 0 ]. 16.org/markup-compatibility/2006" FontFamily="{StaticResource PhoneFontFamilyNormal}" 296 .Position.

297 . LayoutUpdated += new EventHandler(GamePage_LayoutUpdated). amikor a felület frissül. amelynek funkcióját a későbbiekben részletesen megismerjük majd.GraphicsDevice. Szükségünk lesz egy új objektumpéldányára a kígyó osztályunknak. amellyel az eleséget fogjuk elszórni a pályán. private private private private private private private private ContentManager contentManager. timer. GameTimer timer. amely minden egyes alkalommal le fog játszódni. protected override void OnNavigatedTo(NavigationEventArgs e) { SharedGraphicsDeviceManager.UpdateInterval = TimeSpan. contentManager = (Application. public GamePage() { InitializeComponent(). Az osztály konstruktorában engedélyeznünk kell az érintésminták használatát. kelleni fog egy háttér textúra és egy véletlen szám generátor. hogy ide ne kelljen a későbbiekben visszatérnünk. ami a mi esetünkben semmi mást nem jelent. és fel kell iratkoznunk az oldal LayoutUpdated eseményére is. UIElementRenderer uiRenderer.EnabledGestures = GestureType. ha deklaráljuk. SpriteBatch spriteBatch. elhelyeztem egy UIElementRenderer adattagot is. timer. és onnan térünk át a játékoldalra).IsVisible="False"> <Grid x:Name="LayoutRoot"> <Button Width="140" Height="100" HorizontalAlignment="Right" VerticalAlignment="Top" Click="Button_Click">Pause</Button> </Grid> </phone:PhoneApplicationPage> Mögöttes kódban több új adattagot is létre kell hoznunk.Current as App). SnakeObject snake. akkor be kell töltenünk a tartalmakat. SnakeBlock newBlock. snake = new SnakeObject( contentManager ). Random rand = new Random().Content.Draw += OnDraw.Current. timer.FromTicks(333333).xaml-lel indul az alkalmazás. a tartalomkezelő felhasználásával inicializálnunk kell a kígyó objektumpéldányunkat.XNA és Silverlight integráció FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" mc:Ignorable="d" d:DesignHeight="800" d:DesignWidth="480" shell:SystemTray.SetSharingMode(true). mint a textúrák lekérését a tartalomkezelőtől. Ahhoz. TouchPanel. egyelőre elég. Texture2D background. Itt történik meg az első felszedhető szegmens (ha az eleség név tetszetősebb. timer = new GameTimer(). akkor hívhatjuk így is) inicializálása is.Update += OnUpdate.Flick. } Amikor az oldalra navigálunk (először a MainPage.

mivel tartalma egészen egyszerű lesz. amikor az elszórt szegmenst összeszedjük.11. Az egyik a szüneteltetés gomb Click eseményvezérlője. amely egyelőre nem fog megjelenni. A sima ütközés lekezelését az Olvasóra bízom. timer. if ( snake. } void GamePage_LayoutUpdated(object sender. Nagyon egyszerű feladat! Semmi mást nem kell tennünk.IsPaused. } } Mielőtt a rajzolást is megvalósítanánk.ActualHeight > 0 ) uiRenderer = new UIElementRenderer( LayoutRoot.ActualWidth > 0 && LayoutRoot. akkor a textúrába renderelt Silverlight tartalmat is egy egyszerű Sprite-ként felrajzoljuk. hogy renderelje le a Silverlight tartalmat. mivel a kígyó osztály ütközésdetektáló metódusa az előző elemet automatikusan a kígyó testéhez fogja fűzni. EventArgs e) { if ( uiRenderer == null || LayoutRoot.GraphicsDevice).Update( null ). A játékciklus két komponensét el kell készítenünk.Current. hogy az is kirajzolásra kerüljön. GameTimerEventArgs e) { snake. mint generálni a helyére egy másikat. Először érdemes a frissítést végző Update() metódust létrehozni. snake. Ahhoz.Next() % 480. private void Button_Click(object sender.LoadContent(). newBlock = new SnakeBlock { Position = new Vector2( rand.Next() % 800 ). RoutedEventArgs e) { snake. private void OnUpdate(object sender.Load<Texture2D>( "Textures/sprite" ) }. és a Silverlight alapon definiált felület automatikusan nem kerül megjelenítésre. amelyhez a tartalmat folyamatosan frissítenünk kell. Játékok a Mango világában spriteBatch = new SpriteBatch(SharedGraphicsDeviceManager. Nagyon fontos megfelelő sorrendben dolgoznunk. melynek feladata a színtér felrajzolása. base. Az utóbbit miért is hoztuk létre? Az XNA tartalom elsőbbséget élvez a kirajzolás során. Utána felrajzoljuk a háttér textúrát és a kígyót.Next() % 800 ). (int)LayoutRoot.ActualWidth. rand. a másik pedig a LayoutUpdated eseményvezérlő.Start(). 298 . még két dolog hiányzik.Load<Texture2D>( "Textures/Background" ).ActualHeight ).IsPaused = !snake. (int)LayoutRoot. background = contentManager. rand. amíg az eleség összeszedéséért felelős ütköztetést még együtt elkészítjük.OnNavigatedTo(e).DetectCollision() ) . Texture = contentManager.DetectCollisionWithNewBlock( newBlock ) ) { newBlock.Next() % 480. } És a végére maradt a rajzolást végző OnDraw() metódusunk létrehozása. Először is megkérjük a környezetet. textúrát kell belőle készítenünk. az ütközések két különböző típusát fogja figyelni. } Két nagyon fontos része van vissza a játéknak.Position = new Vector2( rand. // ezt a részt az olvasó kreatívitására bízom if ( snake. Miután ezek is megjelenítésre kerültek.

spriteBatch. uiRenderer. (int)newBlock.Begin(). 480. snake. és betekintést nyertünk a számítógépes (vagy mondhatnám inkább okostelefonokra tervezett?) játékok 299 . Color. sehol nincsenek már a projektben szintaktikai hibák.Draw( newBlock.Clear(Color.Position. spriteBatch.Framework.White ).X. 800 ). spriteBatch. spriteBatch ).Draw( uiRenderer.Texture. } Ha készen vagyunk.Black).End(). és futtassuk emulátor segítségével! A 11-21 ábrán látható eredményt kell kapnunk.Rectangle( (int)newBlock. spriteBatch.Draw( background. 16 ). spriteBatch.Current.Texture. Határozott mozdulatokkal irányítható a kígyó. spriteBatch. és a Pause gomb lenyomásának hatására a játék szüneteltetésre kerül. 16. Color. Vector2. 0. illetve újraaktiválódik.Xna.Xna. new Microsoft.Rectangle( 0.White ). new Microsoft. spriteBatch.White ).End(). GameTimerEventArgs e) { SharedGraphicsDeviceManager.XNA és Silverlight integráció private void OnDraw(object sender. Color. 11-21 ábra: A Snake játék futás közben Összefoglalás Ebben a fejezetben megismerkedtünk a Windows Phone platformot alkotó technológiák felépítésével.GraphicsDevice.Zero. akkor fordítsuk le.Begin().Render().Position.Framework.Y.Draw( null.

Éppen csak a felszínt érintve áttekintettük a számítógépes grafika elméleti hátterét és ennek kapcsán a játékokat alkotó grafikus megoldásokat is. Megismerkedtünk az XNA Framework alapvető használatával. 300 . Az utóbbira építve elkészítettük egy Snake játéknak az alapjait is. melyet az Olvasó tetszése szerint tovább bővíthet.11. illetve láttuk a Mangóban újdonságként bevezetett hibrid renderelési rendszer működését és használatát is. Játékok a Mango világában fejlesztésébe.

és bárki publikálhat. Készüléken történő hibakeresés és regisztráció Könyvünk eddigi fejezeteiben az alkalmazások fejlesztésénél csak az emulátorra koncentráltunk.12. ha elkészítünk egy alkalmazást. Megnehezíti azonban a dolgunkat. és ingyenesen publikálhatunk. nyomon követhetik azok népszerűségét. cégek esetén olykor 3-4 napot is igénybe vehet. Azok lehetnek ingyenesek vagy díjkötelesek. a Marketplace-szel. mert felmérhetjük. ha aktív státuszú középiskolai vagy felsőoktatási hallgatók vagyunk. Diákként (akkor válasszuk ezt a lehetőséget. frissíthetik azokat. hanem már csak az a fejlesztő férhet a 301 . Az AppHub a http://create. mert az emulátor és a fizikai készülék között komoly eltérések lehetnek a teljesítményt illetően. ha a fejlesztő egy cég. mielőtt publikálnánk azt. ami három fejlesztői készülék használatát (developer unlock) tartalmazza és a piactérre való publikálás lehetőségét. A Windows Phone 7-hez tartozik egy piactér. üres lenne alkalmazások nélkül. Marketplace Ebben a fejezetben megismerkedhetünk a Windows Phone 7 ökoszisztémájának központi szereplőjével. mint a Windows Mobile esetében. aki megfelel a Marketplace feltételeinek. Ebben az esetben a DreamSpark program –http://dreamspark. és követhetik az értékesítésükből befolyt összegeket is. Ebben a részben a következő témákat nézzük át:          Mi az a Marketplace? Készüléken történő hibakeresés Készülék regisztráció Publikálás Screenshot készítés Marketplace Test Kit Képek és ikonok Marketplace Task-ek Trial Mode APPHUB Az AppHub a Microsoft Windows Phone 7 fejlesztői menedzsment oldala. hogy a Windows Phone 7 -nél már nemcsak egy egyszerű fájl másolásából áll a telepítés. vagy szervezet) 2.msdn. A telefon és a rajta lévő operációs rendszer bármennyire is jó. másfelől azért. ahonnan alkalmazásokat tölthetünk le.com – keretein belül a 99 USD éves díjat nem kell kifizetnünk. a vállalat tényleg az általa megadott országban tevékenykedik. Az AppHubra háromféle regisztrációtípus létezik: 1. ahol a fejlesztők kezelhetik az alkalmazásaikat. hogy használhatóság szempontjából milyen az alkalmazásunk. akár díjköteles alkalmazásokat is!) A regisztrációnál szükségünk lesz egy Windows Live ID-ra. Egyfelől ez azért hasznos. Cég nevében (akkor használatos. Cégek esetében a regisztrációt követően egy GeoTrust nevű cég fogja felvenni a kapcsolatot annak érdekében. célszerű azt kipróbálni egy fizikai készüléken is. A fejlesztői regisztráció éves díja jelenleg 99 USD. A regisztráció magánszemélyek esetén 1-2 napot. viszont az alkalmazásainkat célszerű kipróbálni egy fizikai készüléken is. Magánszemély (akkor alkalmazzuk. illetve fejlesztőként publikálhatjuk saját alkalmazásainkat.com címen érhető el. Ezért minden esetben. ha egy egyszerű magánszemélyről van szó) 3. cégek és a magánszemélyek esetén egy bankszámlára is. hogy ellenőrizze.

Ahhoz. akkor automatikusan el fog indulni a Zune szoftver (ha ez valamilyen oknál fogva nem történne meg. akkor ezen az oldalon tudjuk eltávolítani a zárolás feloldását is. adjuk meg a Live ID-nkat – azt. ha a képernyőzár fel van oldva! 12-2 ábra: Windows Phone Developer Registration Tool Az AppHub-on a saját fejlesztői fiókunk devices menüpontja alatt láthatjuk a zárolás alól feloldott készülékeink listáját. a telefonunk fejlesztői zárolása feloldásra került (12-2 ábra). majd ezt követően el kell indítanunk a Windows Phone Developer Registration tool nevezetű alkalmazást (ez az alkalmazás a Windows Phone 7 SDK része). akkor a developer unlock is eltűnik. indítsuk el manuálisan!). Ha a regisztrációt elvégeztük. kattintsunk az Unregister gombra! Ha minden rendben zajlott. 12-1 ábra: Zune szoftver Fontos! Csak úgy tudjuk unlockolni a készüléket. ilyenkor ezt a folyamatot meg kell ismételnünk! 302 . hogy legyen egy ilyen előfizetésünk. amelyikkel korábban a Marketlace-re regisztráltunk –.net) telepítve kell lennie! Amikor összekötöttük a Windows Phone 7-et a géppel (12-1 ábra). hogy a Zune szoftvernek (www. Marketplace készülékhez. aki rendelkezik fejlesztői fiókkal (developer account).12.zune. Miután elindítottuk. hogy ha a készülékünket frissítettük vagy reseteltük. Figyeljünk arra. regisztrálnunk kell magunkat a Marketplace-en. ha esetleg lecserélnénk a jelenlegi készülékünket egy újabbra. Abban az esetben. USB kábellel kössük össze a készülékünket a számítógépünkkel! Figyeljünk arra. majd ha ez megtörtént.

Készüléken történő hibakeresés és regisztráció 12-3 ábra: AppHub a feloldott fejlesztői zárolású készülékek listájával Ha minden rendben zajlott. hogy melyik eszköz a cél (target) – a készülék vagy az emulátor –. 12-4 ábra: Készülékre történő publikáció Figyelnünk kell arra is. amelynek kezünkben van az XAP fájlja. mind Expression Blendből egyszerűen megoldható. Ehhez mindössze a Visual Studio-ban kell a kimenetet átállítani Windows Phone Emulator-ról Windows Phone Device-ra. akkor az adott alkalmazás megjelenik a készülék vagy az emulátor alkalmazásai között. ha csak egyszerűen telepíteni szeretnénk egy már lefordított alkalmazást. hibát tudunk keresni az alkalmazásban. majd kikeressük a telepítendő XAP fájlt. Az alkalmazás felépítése nagyon egyszerű: először megmondjuk. hogy a művelet során a telefon képernyője nem lehet zárolva! 303 . és megnyomjuk a Deploy gombot (12-5 ábra). ahogy az emulátornál. a debugger rögtön elindul és ugyanúgy. Itt is fontos megjegyezni. Ha minden rendben zajlott. Ez mind Visual Studio-ból. és ott tudunk hibát keresni (12-4 ábra). akkor „Access is denied” hibát kapnánk. akkor már lehetőségünk van az alkalmazásunkat a fizikai készülékünkön is tesztelni. Alkalmazások telepítése Abban az esetben. hogy az alkalmazás Visual Studio-ból történő telepítésekor is fel kell oldani a képernyőzárat! Ha ezt nem tennénk meg. akkor ezt az Application Deployment Tool-lal tehetjük meg. Ezt követően az F5-öt megnyomása után már a készülékre kerül fel az alkalmazás. Abban az esetben. ami szintén a Windows Phone 7 SDK része. ha a fejlesztői környezetből publikáljuk a készülékre az alkalmazást.

304 .12. egy Live ID-re lesz szükségünk. nem kell évente megújítanunk. azaz nem kapunk hozzáférést a telefon mélyebb részeihez. Fontos kiemelni. Ha ennél többre lenne szükségünk. Marketplace 12-5 ábra: Az Application Deployment Tool A készülékre maximum tíz alkalmazást tudunk feltelepíteni a feloldott fejlesztői zár birtokában. vagy hogy az adott országból elérhető-e a Marketplace. hogy használni tudjuk. A 9 USD-t egyszer kell kifizetnünk. mint a Marketplace esetén.chevronwp7. 9 USD-be kerül telefononként. függetlenül attól. ChevronWP7 A Microsoft támogatásával elindult a http://labs. általunk telepített alkalmazást el kell távolítanunk. Ezzel a feloldással is csak maximum 10 alkalmazást telepíthetünk a készülékre (diákok 3 alkalmazást). Ezzel a feloldással csak a telefonra tudunk alkalmazásokat telepíteni. a Marketplace-re nincs jogunk azokat feltölteni! Ahhoz. mégis hasznos lehet. általában felesleges ezt a szolgáltatást megrendelnünk. 12-6 ábra: Chevronwp7 labs Ha van Marketplace előfizetésünk. ahol a hobbifejlesztők feloldhatják telefonjuk zárolását. interop unlock. hogy milyen régióba tartoznak. akkor egy előző. hogy ez nem ún. Bár ez a szolgáltatás nem ingyenes.com/ oldal (12-6 ábra).

Az alkalmazások verziózása tetszőleges. Az alkalmazásunk nem befolyásolhatja a telefonunk megfelelő működését. milyen információt kell és lehet ezen az oldalon megadnunk (12-8 ábra):   App name for App Hub: Az alkalmazás neve.msdn.) Requires technical exception: Ha ezt az opciót megjelöljük. például tesztelési célból.Publikálás Publikálás Ha kész az alkalmazásunk. és a bejelentkezés után kattinsunk a Submit for Windows Phone gombra (12-7 ábra)! 12-7 ábra: AppHub oldal − Submit for Windows Phone A következő ablak az Upload. amivel az alkalmazásunkat mindenki számára elérhetővé tesszük. (Kezdhetjük akár 5. Az alkalmazásunkban nem lehet rosszindulatú kód (Maleware). mely csak az AppHubon fog megjelenni. Itt kell feltöltenünk az alkalmazásunkat. Ezeket az alábbi 4 pontban foglalhatjuk össze: 1. a másik lehetőség pedig a Private beta test. Nézzük meg lépésről lépésre. Ennek a névnek egyedinek kell lennie! Distribute to: Két menüelem közül választhatunk. 4.0-val is. ha csak meghatározott személyeknek szeretnénk az alkalmazást elérhetővé tenni. hogy mit nem tehet az alkalmazásunk. az alkalmazásunknak több funkcionális és formai követelménynek meg kell felelnie. mivel az alkalmazásunk valamilyen speciális oknál fogva nem felel meg a „Windows Phone 7    305 . hogy publikáljuk. hogy kell egy már elkészült alkalmazást publikálni a piactéren! Ehhez öt egyszerű lépést kell elvégezni. 3. ami akkor lehet hasznos. Application version number: Itt határozhatjuk meg az alkalmazásunk verzióját.com. Az alkalmazásnak hatékonyan kell használni a telefon erőforrásait. itt az ideje publikálni a Marketplace-en! Ahhoz. és egyedi nevet is itt kell választanunk a számára! Nézzük meg részletesen. de a fentieken kívül elég sok feltételt kell még teljesítenünk ahhoz. Ez meglehetősen általános leírás arról. hogy az a piactéren megtalálható legyen! A következő néhány lépésben bemutatjuk a publikálás folyamatát. az első a Public Marketplace. Browse to Upload a file: Itt kell feltöltenünk az XAP fájlunkat. akkor felmentést kérünk. Az alkalmazásnak válaszképesnek kell lennie. Látogassunk el az AppHub-ra: http://create. 2.

App name: Ez a mező automatikusan töltődik ki. Legal URL: Egy olyan URL cím. Short Description: Itt az alkalmazásunk rövid leírását kell megadnunk. Ezt a mezőt kötelező kitölteni. Ezt a mezőt kötelező kitölteni. és kötelező kitölteni. Marketplace Application Certification Requirements” által támasztott követelményeknek. akkor minden nyelvhez külön-külön leírást kell adnunk! Nézzük át. hogy az alkalmazás milyen kategóriába és alkategóriába (Subcategory) tartozik. Email address: Egy olyan e-mail cím. amely az alkalmazásunkkal kapcsolatos licencekre. milyen funkciói vannak. amivel a felhasználók kapcsolatba léphetnek az alkalmazás fejlesztőivel. Keywords: Meghatározhatunk maximum 5 kulcsszót. ez maximum 2000 karakter lehet. hogy milyen tulajdonságokat lehet és kell kitöltenünk!    Kategória: Itt választhatjuk ki. Ezt kötelező kitölteni. hogy az alkalmazásunk mire való. például az alkalmazás-támogatási csoporttal. illetve egyéb dokumentációra mutat. Ez is opcionális. Fontos megjegyezni.     306 . amivel a felhasználók könnyebben megtalálhatják az alkalmazásunkat. Detailed Description: A programunk részletes leírását adhatjuk meg. Az alkalmazásunk elbírálása ilyenkor egyedi. Ezt az információt az XAP fájlból nyeri ki a rendszer. Itt írhatjuk le részletesen. hogy ha többnyelvű az alkalmazás. de ajánlott a kitöltése. mint egy átlagos alkalmazás esetén. kitöltése opcionális. és a hozzá tartozó képeket. Ez maximum 25 karakter lehet. kattintsunk a Next gombra! Néhány másodperc múlva betöltődik a Describe oldal (12-9 ábra). 12-8 ábra: Alkalmazás feltöltéséhez szükséges információ az AppHubon Ha az oldal adatait kitöltöttük. és jóval hosszabb ideig tart. ikonokat is itt adhatjuk meg. ennek segítségével hívhatjuk fel legelőször az alkalmazásunkra a felhasználók figyelmét.12.

mit is lehet megadni (12-10 ábra)! A képek ajánlott felbontása 96DPI. ha az alkalmazásunk részletes nézetét vizsgáljuk. Ezek a képek nem lehetnek transzparensek!     Large mobile app Tile (173x173 Fájl): Egy png fájl.  307 . ha a Zune szoftverből böngészik a piacteret. most már csak az alkalmazásunkkal kapcsolatos képeket és ikonokat kell feltöltenünk. a vásárlók ezt az ikont látják meg először a piactéren. kötelező megadni. featured app). Ebben az esetben ez a kép jelenik meg háttérképként. Background art (1000x800 PNG fájl): Ez a kép akkor látható. ha az alkalmazásunk ki van emelve a Marketplace-en (ún. Large PC app Tile (200x200 PNG fájl): Ezt az ikont látják a felhasználók. A kép megadása kötelező. amelyek az alkalmazásunkat működés közben mutatják be. Opcionálisan választható a megadása. Fontos megjegyezni. Ezeket mindenképpen érdemes megadnunk. Screenshots( 480x800 PNG fájlok): Minimum egy. A screenshotok készítéséről a következő alfejezetben olvashatunk. maximum nyolc képet adhatunk meg. mert a felhasználók sokszor ezek alapján döntenek. amikor az alkalmazásunkat betöltik. Nézzük meg sorban. Ezt a képet láthatjuk a Zune-ból is. hogy ezeket a képeket nem szabad grafikai szoftverrel módosítani. amikor egy katalógusban vagy egy keresési listában böngésznek. Small mobile app Tile (99x99 Fájl): Ezt a képet a felhasználók akkor látják.Publikálás 12-9 ábra: A Describe fül alatt adjuk meg az alkalmazásunk leírását Az alapadatokat ezzel meg is adtuk.

hogy mely országban vagy régióban publikáljuk az alkalmazásunkat. Természetesen ingyenesen is feltölthetünk alkalmazásokat.12. vagy egyesével megadhatjuk. Marketplace 12-10 ábra: Itt adhatjuk meg az alkalmazásunkhoz tartozó képeket és képernyőmentéseket Ha a Describe oldalon minden lényeges információt kitöltöttünk. illetve mit tilt le az alkalmazás funkcionalitásából.   308 . Az ár 0. Itt tudjuk beállítani azt. A fejlesztőnek kell meghatároznia. az nálunk 0. amit engedélyez. Az ár meghatározásánál vegyük figyelembe.7 centben realizálódik. hogy a teljes ár 70%-át kapjuk meg (bizonyos országoknál a helyi adókat is be kell fizetnünk). hogy az alkalmazásunkat az összes olyan országban elérhetővé tesszük-e. A Trial mód használatával a fejezetünk későbbi részében ismerkedhetünk meg.00” értéket válasszuk! WorldWide distribution: Kiválaszthatjuk. ilyenkor a „0. akkor kattintsunk a Next gombra! Néhány pillanat múlva betöltődik a Price ablak. hogy az alkalmazásunk mely piacokon legyen elérhető és hogy mennyiért.99 USD és 499. hogy a trial módban mi az. Set Price tier: Itt határozhatjuk meg az alkalmazásunk árát. Ezen az oldalon a következő dolgokat állíthatjuk be (12-11 ábra):  Enable trials to be downloaded: Meghatározhatjuk. hogy az alkalmazásunkat trial (próba) módban engedélyezzük-e letölteni. ahonnan a Marketplace elérhető.tehát ha egy alkalmazást mi például 1 USD-ért szeretnénk eladni.99 USD között lehet.

) Ezt akkor használjuk. deep linkre. Itt néhány teszteléssel kapcsolatos adatot adhatunk meg (12-12 ábra):   Test notes or instructions: A mező kitöltése opcionális.  I will publish it manually after it has beed certified: A sikeres ellenőrzés után saját magunk kézzel kell. but make itt hidden: Hasonlóan az előző beállításhoz. 309 . de ha esetleg 4-5 nap lenne. ha átmegy a teszteken. (pl: egy cég számára készítünk egyedi fejlesztést). akkor sem kell aggódnunk. ekkor a soron következő köszöntő képernyő fogad. As soon as it’s certified: Ez egy automatikus folyamat. és ezt követően bármikor visszatérhetünk az oldalra az alkalmazást publikálni. Publishing options: Azt határozhatjuk meg. mellyel az alkalmazásunkat rögtön publikálják a Marketplace-re. akikkel mi megosztjuk az alkalmazás elérhetőségét (ehhez szükségünk lesz egy ún. de csak azok a felhasználók érhetik el. hogy engedélyezzük a piactérre kerülést. akkor kattintsunk a Next gombra! Ezt követően a Test ablakra jutunk. itt is azonnal a Marketplace-re kerül az alkalmazás. Akkor kell kitöltenünk. Az elfogadás folyamata néhány napot igénybe vehet: általában 1-2 nap. amint sikeresen átment az ellenőrzéseken. ha az alkalmazásunkat csak egy szűk réteg fogja használni. Ezt a funkciót „my dashboard” menüpont alatt érhetjük el.Publikálás 12-11 ábra: Price oldal – az alkalmazásunk árát és piacterületét határozhatjuk meg Ha kitöltöttük a megfelelő adatokat. Menthetjük a folyamatot. As soon as it’s certified.   Ha ezzel is készen vagyunk. kattintsunk a Submit gombra. hogy mikor kerüljön az alkalmazás a piactérre. ha az alkalmazásunk tesztelését végző személlyel speciális információt szeretnénk megosztani.  None: Ezzel a beállitással nem lehet publikálni az alkalmazást.

1 SDK-ja óta ez a funkció már az emulátor mellett is megtalálható (12-13 ábra). 12-13 ábra: Screnshot készítése Nézzük meg használat közben! Indítsuk el az alkalmazást. de a legtöbbjük használata legtöbbször kényelmetlen. de a Windows Phone 7. Marketplace 12-12 ábra: Az alkalmazás beküldése Screenshot készítés Az alkalmazásunk feltöltése során a Marketplace megköveteli. majd a nagyítási beállításokat (nagyító ikon) állítsuk 100%-ra. A neten persze találhatunk erre is jó néhány eszközt. OneNote. A méretnek pontosnak kell lennie. hogy legalább egy 480x800-as képernyőkép legyen az alkalmazásunkról mellékelve. akkor indítsuk el az 310 . és a képet nem szabad módosítanunk semmilyen grafikai eszközzel! A képernyőkép készítéséhez persze elég sokféle eszközt tudunk felhasználni: például Snipping tool. és kapcsoljuk ki a Frame rate számlálókat is! Ha ez megtörtént.12.

amivel megvizsgálhatjuk. Ha nem adjuk meg ezeket a képeket. 311 . Mit is árul el ez az eszköz alkalmazásunkról?              Megfelelőek-e a képek és a képernyőképek a követelményeknek? Megfelelő-e az XAP fájl mérte (maximum: 225 MB)? Elég gyorsan indul-e az alkalmazásunk? Nem használ-e túl sok memóriát? Rendeltetésszerűen működik-e a Back gomb? Nem használ-e olyan API-t. Application Details Automated Tests Monitored Tests Manual Test A Test Kit felhasználói felületén négy fül található. ahol különböző teszteket futtathatunk le: Nézzük meg. az alapbeállítás szerint a Bin\Release mappában található XAP-ra mutat. ami nem engedélyezett egy Backround Agenttel? Nincs-e váratlan hiba. ha bezárjuk az alkalmazást? Stb. Ezenkívül ezen a fülön adhatjuk meg az alkalmazások piactérre feltöltendő képeit és képernyőképeit. hogy az alkalmazásunk megfelel-e a Marketplace követelményeinek. ami nem engedélyezett a számunkra? Használ-e olyan API-t. és ezen kattintsunk a Capture gombra! Ezt követően már csak el kell mentenünk ezt a képet a „Save…” gomb segítségével.1 SDK –val érkezett egy hasznos eszköz (Marketplace Test Kit) is. és navigáljunk arra az oldalra. Az Applicaton package mezőbe az XAP fájl útvonala található. akkor a tesztünk sikertelen lesz. ikonokat és képernyőképeket. mire alkalmasak ezek a tesztek! Application Details Az Application Details fülön (12-15 ábra) adhatjuk meg az ellenőrzés során használt. az alkalmazásunkhoz tartozó képeket.Publikálás alkalmazást. Windows Phone Marketplace Test Kit A Windows Phone 7. majd az emulátor jobb felső sarkában található menüben válasszuk ki az Additional Tool ablakot (12-14 ábra)! 12-14 ábra: Additional Tool A megjelenő ablakban válasszuk ki a Screenshot fület. A tesztek lefuttatásához egy Release konfigurációval történő fordításra is szükségünk van. amiről a screenshotokat szeretnénk elkészíteni.

Marketplace 12-15 ábra: Application Details (Marketplace Test Kit) Automated Tests Az Automated Tests fülön (12-16 ábra) az általános kritériumokat tudjuk tesztelni. Ha lefuttatjuk a tesztet. 12-16 ábra: Automated Tests (Marketplace Test Kit) Monitored Tests Ezen a fülön (12-17 ábra) mérhetjük meg az alkalmazásunk teljesítményét és válaszképességét.12. Az Application Details alatt megadott képeket is itt teszteljük. A teszt közben a program által felkínált lehető legtöbb felhasználói esetet hajtsuk végre az alkalmazáson! 312 . például az alkalmazás méretét és képeit. A teszt során az alkalmazást egy fizikai készüléken kell kipróbálnunk. akkor a teszt megmondja. hogy az alkalmazásunk számára milyen Capability beállításokat (képességeket) kell meghatároznunk a WPAppManifest. tehát csak a fejlesztői zárolás feloldásával ellátott készüléken tudjuk ezt megtenni.xml fájlban.

a Background. ha az alkalmazást a felhasználó kirakja a főképernyőre.jpg. ha nem teljesültek. egy 62x62 pixeles kép. ha az alkalmazásunk nagyon gyorsan be tud töltődni.Publikálás 12-17 ábra: Monitored Tests (Marketplace Test Kit) Manual Test A tesztnek van egy manuális része is. A Test Descriptionban leírt feltételeknek teljesülniük kell. ha például egy transzparens kép miatt visszadobják az alkalmazást. amely egy 480x800 pixeles kép. itt minden egyes tesztet végre kell hajtanunk. akkor Failedre (12-18 ábra)! 12-18: Manual Tests (Marketplace Test Kit) Ha ezeket a teszteket minden publikálás előtt elvégezzük. illetve visszalépéskor láthat a felhasználó. Ikonok Egy Windows Phone 7 –es solution úgy épül fel. Figyeljünk oda. felesleges a SplashScreenImage. hogy minden kép Build Action tulajdonsága Content értékű legyen! Ha saját képet adunk 313 . hogy három speciális képfájl található benne:    az ApplicationIcon. Ezt azért használjuk. akkor a felhasználó ne nyomja meg rögtön a Back gombot. amely a fő képernyő csempéi között jelenik meg. hogy ha lassan töltődik be valamiért az alkalmazás. akkor egyszerűen a Result oszlop értékét állítsuk át Passedra. Abban az esetben. ezenkívül van még egy SplashScreenImage.png. Célszerű ezeket a képeket mindig testreszabni. akkor nagy valószínűséggel semmilyen probléma nem lesz a piactér publikálási folyamata során sem. hisz kellemetlen. és az alkalmazások listájában fog látszódni. Ha ezek teljesültek.png egy nagyobb. amely az alkalmazás ikonja. Célszerű minden kész alkalmazásnál lefuttatni ezeket a teszteket! Időt spórolhatunk vele. amit az alkalmazásunk indulásakor. 173x173 pixeles kép.

File Méret (Pixel) Fájl típus PNG Project File Példa Small app icon 62 x 62 ApplicationIcon. a beállításokat a WMAppManifest.png Large app tile Background. Az alkalmazásunkból elindíthatjuk a Marketplace alkalmazást. Ebben a részben áttekinthetjük. hogy mi legyen az alkalmazás címe (Title).0" Genre="apps.xaml"/> </Tasks> <Tokens> <PrimaryToken TokenID="MarketPlaceSampleToken" TaskName="_default"> <TemplateType5> <BackgroundImageURI IsRelative="true" IsResource="false">Background.12.xml fájlban testreszabhatjuk. akkor láthatjuk. sőt azt is. milyen legyen a háttere (Background) vagy éppen az ApplicationIcon neve és elérhetősége.png</BackgroundImageURI> <Count>0</Count> <Title>MarketPlace Sample</Title> </TemplateType5> </PrimaryToken> </Tokens> </App> </Deployment> Ha jól megnézzük ezt a fájlt. hogy melyik lapot töltse be az alkalmazás indulásakor. melyek ezek.com/windowsphone/2009/deployment" AppPlatformVersion="7. akkor annak szintén a Content értéket kell felvennie! Persze nem muszáj ezeket a neveket használnunk.png 173x173 PNG <Deployment xmlns="http://schemas. Ehhez négy taszk áll a rendelkezésünkre:   MarketplaceHubTask MarketplaceDetailTask 314 . Leírhatjuk.normal" Author="Turóczy Attila" Description="Sample description" Publisher="Livesoft"> <IconPath IsRelative="true" IsResource="false">ApplicationIcon.1"> <App xmlns="" ProductID="{1b0f2313-d341-4b64-b7b7-88caa0ed57b1}" Title="MarketPlace Sample" RuntimeType="Silverlight" Version="1. hogy itt az alkalmazásunkkal kapcsolatban speciális tulajdonságokat adhatunk meg.png</IconPath> <Capabilities> <Capability Name="ID_CAP_CONTACTS"/> <Capability Name="ID_CAP_APPOINTMENTS"/> </Capabilities> <Tasks> <DefaultTask Name ="_default" NavigationPage="MainPage. és hogyan is használhatjuk fel azokat.0. de még nem néztük meg közelebbről a piactérre jellemzőeket.0. Marketplace Task Az előző fejezetekben már foglalkoztunk a launcherekkel. Marketplace az alkalmazáshoz.microsoft.

azt a MarkerplaceDetailTaskkal tehetjük meg (12-20 ábra). 12-19 ábra: Marketplace Hub Ha viszont egy meghatározott alkalmazás Marketplace oldalát szeretnénk betölteni. Ezzel a launcherrel például megtehetjük azt. hubTask. Kezdjük a legegyszerűbb taszkkal. Itt meg kell adnunk a hivatkozni kívánt alkalmazás egyedi azonosítóját. akkor a kiválasztott program részletes nézete töltődik be.Applications. a Content Type értékével pedig meghatározhatjuk. a MarketplaceHubTaskkal (12-19 ábra)! Ezzel egyszerűen megnyithatjuk a Marketplace alkalmazást (Marketplace Hubot). és közvetlenül erről az oldalról le is töltheti a felhasználó az alkalmazást. detailTask. 315 . képernyőképeit. leírását. hubTask. detailTask. ahol láthatjuk az alkalmazás logóját.Show().ContentIdentifier = "078656ae-9f35-45bb-84b8-2f9270bbdd67".Applications. hogy az ingyenes próba változatban folyamatosan reklámozzuk az általunk írt alkalmazásokat. és amikor betöltődik. hogy melyik típust szeretnénk megjeleníteni: MarketplaceHubTask hubTask = new MarketplaceHubTask().Marketplace Task   MarketplaceReviewTask MarketplaceSearchTask Alapvetően két különböző helyen tudunk keresni: az alkalmazások és a zenék között – ezt a ContentType tulajdonságnál tudjuk megadni.ContentType = MarketplaceContentType.Show(). MarketplaceDetailTask detailTask = new MarketplaceDetailTask().ContentType = MarketplaceContentType. detailTask.

Phone. akkor a feltöltött alkalmazásunkat szabadon letölthetik a felhasználók anélkül. var isInTrialMode = license. hogy figyeljük. Reklámokat és figyelemfelkeltő üzeneteket is elhelyezhetünk az alkalmazásban. Ennek a taszknak nincs speciális paramétere. ha az alkalmazásunk publikálva van. ha megveszi a felhasználó az alkalmazást.Show(). és fizikai készülékről indítjuk el az alábbi kódot: MarketplaceReviewTask reviewTask = new MarketplaceReviewTask(). utána leállítjuk. és a mi dolgunk. és abban alkalmazásokat. Ezt a funkciót nem tudjuk kipróbálni az emulátorban.LicenseInformation().12. hogy az alkalmazáslicenc IsTrial értéke true lesz. vagy figyelmeztetjük a felhasználót a vásárlásra. Például megtehetjük azt. Akár a saját magunk által készített alkalmazásokra is rákereshetünk. nem tehetjük meg például. zenéket vagy podcastokat keressünk. jelezve a felhasználónak. ugyanis az IsTrial metódus eredetileg false értékkel tér vissza. és ezt bekapcsoljuk. Marketplace 12-20 ábra: Marketplace Details Task Nagyon fontos. egyszerűen csak megnyithatjuk az adott alkalmazás Review oldalát. Annyiban különbözik ez a verzió a teljestől. MarketplaceSearchTask searchTask = new MarketplaceSearchTask(). hogy milyen módon korlátozzuk az alkalmazás funkcióit. hogy előre meghatározott értékelést adjunk meg.ContentType = MarketplaceContentType. hogy megnyissuk a Marketplace kereső ablakát. Ha van. hogy minél több felhasználó értékelje az alkalmazásunkat (előnye: előrébb kerül a Top listában)! Ezt elősegíthetjük a MarketplaceReviewTask használatával. hogy az IsTrial értéket megfelelően beállítja.Applications. searchTask. akkor maximum háromszor indíthatja el a felhasználó az alkalmazást.Show(). ezért fejlesztési időben ezt szimulálnunk kell. és ha az igaz. reviewTask. az IsTrial értéke false lesz. vagy időhöz köthetjük. Abban az esetben. csak akkor tudjuk használni. meghatározhatjuk azt.Marketplace. searchTask. hogy annak van-e próba (trial) üzemmódja. Trial Mode Amikor alkalmazásunkat a piactérre publikáljuk. a Marketplace csak annyiban nyújt segítséget. ami lehetőséget biztosít arra. A korlátozások kialakítása és kreatív megoldása a mi feladatunk. A trial mód szimulálása fejlesztési időben viszonylag problémás.IsTrial(). az IsTrial értéket.SearchTerms = "Auto". Az utolsó Marketplace-hez kötődő taszk a MarketplaceSearchTask. var license = new Microsoft. hogy célszerű lenne megvásárolnia azt. Ennek kezelésére a DEBUG 316 . hogy megvennék azt. searchTask.

Ahhoz. Azt is megvizsgáltuk. Megnéztük azt. Ha DEBUG módban indítjuk az alkalmazást. hogyan tudunk publikálni a Marketplace-re. #else return true.Összefoglalás szimbólumot tudjuk felhasználni: ha Realease módban fordítjuk le az alkalmazást.LicenseInformation(). és hogy hogyan kell próbamódú alkalmazást készíteni. hogyan tudjuk a készülékünk fejlesztői zárolását feloldani. 317 . #endif } } } Itt megvizsgáljuk. hogy milyen módban fut az alkalmazás. akkor ez a szimbólum eltűnik: public class ApplicationLicense { public bool IsInTrialMode { get { #if !DEBUG var license = new Microsoft. hogy milyen Marketplace taszkok állnak a rendelkezésünkre. 12-21 ábra: Release és Debug mód közötti váltás A feltételeket persze szabadon módosíthatjuk. hogy módosítsuk a fordítási módot. a Visual Studio Toolbar-ján kell beállítanunk.Phone. hogy az alkalmazás nem DEBUG módban indul-e. a nekünk tetsző módon. akkor az IsTrial metódustól kérdezzük le. akkor mindig true értéket fogja visszaadni az IsInTrialMode tulajdonság.IsTrial(). a Windows Phone egyik központi szereplőjével.Marketplace. hogy milyen módon szeretnénk fordítani (12-21 ábra). és milyen feltételeket kell alkalmazásunknak teljesítenie ehhez. return license. Ha nem. Összefoglalás Ebben a fejezetben megismerkedtünk a Marketplace-szel. Ebben az esetben az false értékkel tér vissza.

.

Ami a GPU-t illeti. de egy érintőképernyőn ez már igen zavaró lehet. Lassú betöltődés: Az alkalmazás indítása után senki nem szereti. és a mobil platformoktól is az asztali vagy webfejlesztéskor megszokott produktivitást (termelékenységet) várjuk el. hogy milyen finom (silky smooth) animációkkal kényeztet el minket. magasabb szintű eszközöket használjunk a fejlesztés során – legtöbbször már nem törődünk bitekkel. hogy „ööö… lassú”. bájtokkal és memóriakezeléssel – az adatbázisokat és sokszor még a vezérlési folyamatot is grafikus eszközökkel hozzuk létre. sőt. De ha belegondolunk abba. hogy fejlettebb. Nézzük tehát. amíg az ténylegesen használható nem lesz. nagyobb felbontással. egy 600 MHZ-en futó Pentium III-al állítható párba (1999-ből). A telefon akkumulátora egy asztali gépet csak pár percig tudna ellátni árammal. A teljesítmény növelése lehetővé teszi. Egy kétéves Intel Core 2 processzor kb. ha sokat kell várni addig. a telefon ereje igencsak kevésnek tűnik. Az asztali gépen valószínűleg észre se vennénk 300ms késleltetést a kattintás és a szoftver reakciója között. mint ahogy a felhasználók sem. A felhasználók mára elvárnak egy bizonyos szintű felhasználói élményt – ami 2000-ben még jó volt. gazdagabb grafikával. A fejlesztői élmény is rengeteget változott – főleg a Microsoft világban. De hát mihez kezdtünk ezzel az elképesztő számítási erővel? Nos. hogy a Windows Phone felhasználók elvárásai igen magasak – az egyik legfeltűnőbb és legtöbbet emlegetett pozitívum a platformmal kapcsolatban. A CPU egymagos. Kisebb csoda. szintén az elmúlt évezred végéről származó grafikus kártya. A kliens-szerver kommunikáció immár a keretrendszer része.NET keretrendszer negyedik generációját használjuk. Sőt. és ha odébb lökjük őket. a Snapdragon processzor körülbelül azt a teljesítményt nyújtja. 30-szor múlja ezt felül. Az érintőképernyő közvetlen modellel váltja fel az egér közvetett interakciós modelljét – most már a saját ujjunkkal érintjük meg és mozgatjuk a képernyőn megjelenő dolgokat! Ez nagyszerű. Immár a . egyre jobban tudnak minket szolgálni – rövidebb várakozási idővel. már üzleti alkalmazásoknál is megjelenő animációkkal. Teljesítmény Egy asztali vagy akár laptop számítógéphez hasonlítva a telefon igencsak gyenge teljesítménnyel bír. 2010-re már nem elfogadható. hogy mikortól zavarja egy animáció darabossága. hogy a mai felhasználók megnövekedett igényeit kell fejlesztőként kielégítenünk. Mi. az OS meg is öli azt. milyen jelenségek tartoznak a teljesítmény-gondok témakörébe:  Akadozó animációk: Mindenkinek más az ingerküszöbe. splash screen az alkalmazásban. nem kell minden egyes projektnél újra feltalálnunk a kereket. ami tíz éve csak az asztalon fért el. Ez a mobil fejlesztés egyik legnagyobb kihívása. a fejlesztők ugyanannyira nem kívánunk tíz évet visszalépni az időben. ha a betöltődés 5 másodpercnél tovább tart és nincs ún. hogy a Windows Phone 7 platform Silverlight implementációja hogyan segít szembeszállni ezzel a kihívással! A tipikus teljesítmény-problémákról Míg az átlagember sokszor csak annyit tud mondani.  319 . nem várnak még pár tized másodpercet mielőtt elkezdenének mozogni. a fejlesztőknek ennél pontosabban kell ismerni a tüneteket ahhoz. (Splash screen-nel 20 másodpercünk van az első képernyő megjelenéséig). És a való világban a fizikai tárgyak nem 5-10 fps-el (frame per second – képkocka per másodperc) mozognak. de emiatt a „dolgoknak” a való világbeli tárgyakhoz hasonlóan kell reagálniuk. és hiába fut 1GHz-en. Az érintőképernyők megjelenésével az elvárások tovább nőttek. leginkább a felhasználói élmény javítására fordítottuk! Ahogy a számítógépek egyre gyorsabbak lettek. Abban viszont biztosak lehetünk. több segítséggel a munkához. hogy a problémákat kezelni tudja. Lássuk. mint egy.13. akadozása. számítási teljesítményben kb. hogy a zsebünkben hordozhatjuk azt.

A CPU feladata még a XAML értelmezése. Azonban a teljesítmény-problémák orvoslásához már jó. csillagok… Illusztrációként készítsünk egy egyszerű programot – ezen fogjuk megvizsgálni a fenti teljesítményproblémákat. Videó dekódolás – a Windows Phone-on a videó dekódolást és átméretezést dedikált hardver végzi – ez jó hír. A GPU hasonlóan működik.cs -be írjuk be az alábbiakat: 320 . A mozgatás is ennek segítségével történik (a pozíció változtatása után a következő képkockában (frame-ben) újra egymásra helyeződnek a textúrák. egy gomb) textúra? Ezt a folyamatot renderelésnek vagy raszterizálásnak hívják. De hogy lesz egy vezérlőből (pl. több millió darabot másodpercenként. amire nem ideális. mennyi idő alatt jön meg a válasz? Ha nincs semmi visszajelzés. vagy a videó dekódolás. (Komolyabb 3D alkalmazást inkább XNA-val készítsünk). inkább 2. Visual Studio-ban hozzunk létre egy új C# nyelvű Windows Phone alkalmazást CpuAndGpu néven.13. hogy újra meg újra megnyomjuk a gombot. így elkerülhető a pixelesedés. utasítások és azokból szőtt algoritmusok végrehajtására. a layout (elrendezés) számítása. de van pár dolog. ábra). seek bar megjelenítésére. és a javításuk módját. a vezérlők létrehozása. azt gondolva. feliratok elhelyezésére. és természetesen a programunk futtatása is. mint ahogy a SurfCube 3D Browserben is történt (lásd 13-14. Ez nem igazi 3D. A CPU (processzor) egy remek kis jószág. Perspektivikus torzítás – a textúra elforgatása 3D-ben. mert a CPU önmagában nem lenne elég erős nagyfelbontású videók lejátszására. A GPU segít levenni a CPU válláról a terhet az alábbi műveletek esetén:  Kompozíció – két vagy több. hogy nem érzékelte a telefon az érintést! Görgetés közben üres területek jelennek meg (blanking): Egy hosszú listát gyorsan végigpörgetve üres területeket látunk – a kirajzolás nem tud lépést tartani a görgetéssel. bittérképeket manipulál. mivel nem testekről csak lapos textúrákról beszélünk . Az általunk írt program a CPU-n fut. egymás fedő vagy félig átlátszó textúra (bittérkép) egymásra helyezése. Négyszögletes vágás – a textúrákból a GPU is képes vágást készíteni (clip). mint a nagytestvérei az asztali gépeken – háromszögeket képes a térben elhelyezni és megjeleníteni. és a CPU végzi. és a MainPage. amennyiben a vágó geometria téglalap alakú. A program az első lépésben egy csillagmezőt jelenít meg. hogy a GPU textúrákat. mert a Microsoft nemes egyszerűséggel visszadobja a túl sok memóriát használó alkalmazásokat…   A CPU és a GPU feladata A CPU általános feladatokra alkalmas processzor – képes matematikai műveletek elvégzésére.de megfelelő használatával mégiscsak megteremthető a 3D illúziója. A GPU képes átméretezéskor az éleket elmosni.      Figyelmes olvasóknak feltűnhetett.5D. Ilyenek például a grafikai műveletek.xaml. hogy a Silverlight motor a GPU-t dolgoztatja. még az is lehet. Forgatás – egy bittérkép elforgatása Átméretezés – nagyítás vagy kicsinyítés. stb). Ezért a telefonokban egy GPU (grafikus processzor) is található. Elfogy a memória: Sokszor a felhasználó csak az alkalmazás lefagyását vagy hirtelen kilépését tapasztalja. Szerencsére Windows Phone fejlesztőként nekünk nem kell a GPU-val ilyen alacsony szinten foglalkozni – sőt. Fejlesztőként legkésőbb a Marketplace ellenőrzés során találkozunk ezzel a jelenséggel. Így viszont marad ideje egyéb feladatokra (pl. Teljesítmény  Hosszú válaszidő (reszponzivitás): Ha megnyomtunk egy gombot a programban. Csillagok. ha tudunk pár dolgot a GPU-ról. a legtöbbször észre sem vesszük.

Margin = new Thickness(x. ellipse.Left.HorizontalAlignment = HorizontalAlignment. System. System. 0). Microsoft. ellipse.jpg fájlt.Top. i < numOfStars.White). stopwatch. ellipse. 0.Fill = new SolidColorBrush(Colors. CreateStarField(100). Loaded += OnLoaded. double size = x. A program működése igen egyszerű.Diagnostics. // Constructor public MainPage() { stopwatch = new Stopwatch(). ellipse.Add(ellipse).Show("Startup time: " + stopwatch.Width = size.Controls. A Loaded eseménykezelőjében (ami a MainPage megjelenése után kerül meghívásra) egy MessageBox-ban kiírjuk az induláshoz szükséges időt.ElapsedMilliseconds + " ms").Width.Windows. majd az általunk írt CreateStarField metódus a paraméterként kapott numOfStarts számú véletlen elhelyezkedésű és méretű csillagot jelenít meg a képernyőn.Height = ellipse. } public void CreateStarField(int numOfStars) { Random x = new Random().Next(456). ellipse. a 13-1 ábrán látható eredményt kapjuk. System.Csillagok. A MainPage osztály létrehozása után elindítunk egy stoppert. RoutedEventArgs routedEventArgs) { MessageBox.Phone. ami az indulás óta eltelt ezredmásodperceket méri. i++) { Ellipse ellipse = new Ellipse(). InitializeComponent(). Ha elindítjuk a programot az emulátorban.NextDouble()*3.VerticalAlignment = VerticalAlignment. } } } } A Solution Explorer-ben töröljük ki a SplashScreen.Children.Windows.Windows. 321 . ellipse.Next(607). } private void OnLoaded(object sender. x.Media.Start().Shapes. for (int i = 0. A stopper elindítása után az InitializeComponent függvény a XAML-ben leírtakat értelmezi. namespace CpuAndGpu { public partial class MainPage : PhoneApplicationPage { private Stopwatch stopwatch. csillagok… using using using using using using System. System. ContentPanel.

indítsuk el ott is! Egy első generációs LG Optimus 7 telefonon 558 ms alatt indul el az alkalmazás. ha nem csak 100. 388 ms A programnak azonban a telefonon kell futnia. De mi történik. ábra grafikonján: 13-2 ábra: csillagok kirajzolási ideje emulátoron és telefonon 322 . Teljesítmény 13-1 ábra: 100 csillag.13. hanem akár több ezer csillagot szeretnénk megjeleníteni? A mérések eredménye jól látszik a 13-2.

HorizontalAlignment = HorizontalAlignment.Fill = new SolidColorBrush(Colors.Width = size.Top. Talán nem tűnik soknak ez a csillagonkénti 0. ellipse.NET optimalizáló technológiák és a józan ész a Windows Phone fejlesztés során is segítenek. mint a szélességét (ami egy véletlen érték) . hogy a csillagokat tartalmazó elem egy Grid. Ha ezt a sort lecseréljük arra.Left tulajdonság állításával kerüljenek a csillagok elhelyezésre: public void CreateStarField(int numOfStars) { Random x = new Random(numOfStars).Row="1" Margin="12.Lassú betöltődés kezelése A 20000 csillagos értéket telefonon már meg sem tudtuk mérni. // ellipse. mint maga a telefon.Next(456)).0. // ellipse. akkor a telefonon 5000 csillag már 4202 ms alatt megjelenik (szemben az eredetileg mért 4300al). ellipse. és így az operációs rendszer „megölte” azt.Add(ellipse). Nézzük. A fenti kísérletből két fontos tanulságot vonhatunk le.t. a rendelkezésre álló terület változásait jól kezelő.0"></Grid>--> <Canvas x:Name="ContentPanel" Grid. egy Canvas-ra: <!--<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12.Margin = new Thickness(x. hogy ellipse.Next(607). hogy margók helyett a Canvas. 0. mivel az alkalmazás nem indult el 20 másodpercen belül.Width. hogy hogyan viselkedik az emulátorban! Bár az emulátor rendkívül pontos. de egy sok ezerszer végrehajtott ciklus közepén még az ilyen apróságok is számíthatnak. Cseréljük hát ki a Grid-et egy jóval egyszerűbb társára.Height = size. A Grid igen rugalmas. ezt mégiscsak egy asztali gép processzorán és videokártyáján teszi.White).12. láthatjuk. // ellipse.NextDouble()*3. (double)x. (double)x. és ugyanazt az OS-t futtatja. x. hogy nem minden egyes csillagnál egy újabb Dependency Property get-et végrehajtani. ContentPanel.LeftProperty. ellipse. Ne vonjunk le következtetéseket az alkalmazás teljesítményére vonatkozóan abból. i < numOfStars. és a teljesítményt arra hangoljuk be! A hagyományos .SetValue(Canvas.Children. } } 323 . mint a telefoné. Minden esetben ellenőrizzük az alkalmazás futását egy fizikai eszközön is.Top és Canvas. hogy a csillagok kirajzolásakor van lehetőség még a gyorsításra. Ennek az oka.Next(607)).Next(456). i++) { Ellipse ellipse = new Ellipse().Height = ellipse.TopProperty. ellipse.  Az emulátor performancia-karakterisztikája teljesen más.de ezt a ellipse. double size = x.0.SetValue(Canvas.VerticalAlignment = VerticalAlignment. for (int i = 0.xaml .  Lassú betöltődés kezelése A fenti csillagos alkalmazásnál egyértelműen probléma.Height = size. hogy lehet ezen javítani! Az elrendezés (layout) költségeinek csökkentése Figyelmesebben megnézve a MainPage.0"></Canvas> Módosítsuk a kódot is.12.Left. és sok mindenre jól használható konténer – ugyanakkor ez a komplexitás nyilván nincs ingyen. 0). sorral érjük el. Az ellipszis magasságát ugyanarra az értékre állítjuk. hogy lassan töltődik be a telefonon.2 ms. ellipse. Tapasztalt fejlesztők számára feltűnhet.

MessageBox.</Button> </Canvas> A gomb megnyomására a gomb inverzbe vált. ha arra valóban szükség van. ha a betöltődés után rajzolnánk csak ki a csillagokat? Mozgassuk át a CreateStarField metódust a konstruktorból az OnLoaded eseménykezelőbe: private void OnLoaded(object sender.ElapsedMilliseconds + " ms").cs-ben elhelyezünk egy gombot: <Canvas x:Name="ContentPanel" Grid. mivel a UI szál a csillagokkal van elfoglalva.jpg nem tartozik az ízléses kategóriába! A Marketplace előírások meg is követelik a Splash Screen használatát. Splash Screen A Splash Screen a program indítását követően megjelenő egész képernyős ábra.13. Ezt az érzést szubjektív teljesítménynek hívjuk. hogy az alkalmazás szinte azonnal elindul. } Ha így elindítjuk az alkalmazást a telefonon. Splash Screent igen könnyű az alkalmazásba építeni – helyezzünk el egy SplashScreenImage. Ez azonban ne tévesszen meg senkit – az alkalmazás a csillagok rajzolása során nem reagálna az inputra. amíg az első képernyő meg nem jelenik..12. Ennek az oka az. a WP7 alkalmazássablonban található SplashScreen.Row="1" Margin="12. RoutedEventArgs routedEventArgs) { CreateStarField(5000). mivel valami történik a kijelzőn. Háttérszálak alkalmazása Tegyük hát át a csillagokat egy háttérszálra! Ehhez az OnLoaded eseménykezelőbe kell belenyúlni. hogy a stopperes üzenet megjelenésekor még nem látszanak a csillagok. ha a MainPage. mint az üres kijelzőt.és minél kevesebb dolgot kell ehhez a CPU-nak végeznie. a fejléc-szöveg villámgyorsan megjelenik. Figyelem. ami el van foglalva a csillagok rajzolásával.ZIndex="1">I am not doing anything. a gyerekek számának megváltozása a vizuális fa teljes vagy részleges újraméretezését vonja maga után . A Splash Screen addig látszódik. két dolgot vehetünk észre. a felhasználónak sokkal jobb érzés egy ízléses rajzot bámulnia. a Grid-es 4100 ms helyett 3093 ms-ot mértünk! Általában tehát elmondhatjuk. Az egyik. viszont az üzenet 3093 helyett már csak 2876 ms-ot mutat. A Splash Screen nem gyorsít a beöltődésen – ugyanakkor.. Mi lenne. a csillagok csak a MessageBox lezárása után jelennek meg. ha az alkalmazás indulása 5 másodpercnél több időt vesz igénybe. BGCreateStars metódust létrehozni: 324 .Show("Startup time: " + stopwatch. hogy a tényleges rajzolás ekkor még nem történt meg. hogy a felhasználó – amíg nem vesz a kezébe stopperórát – gyorsabbnak is fogja érezni a betöltődést. így csak a csillagok kirajzolása után fog a gomb az érintésre reagálni. és a felhasználói élményt jelentősen lehet javítani hozzáértő módon alkalmazott trükkökkel (lásd később). annál gyorsabb lesz az alkalmazásunk. Azonban ez a raszterizálás az UI szálon történik. Teljesítmény 5000 csillaggal futtatva az alkalmazást. hogy csak akkor használjunk bonyolult layout rendszereket.jpg fájlt a WP7 projekt gyökérkönyvtárában és állítsuk a Build Action tulajdonságot a Content értékre! Inicializációs teendők elhalasztása A fenti példaprogramban a betöltést jelentősen lassítja a csillagok kirajzolása.xaml. Minden átméretezés. ha az indulást nem tudjuk 1-2 másodperc alá szorítani.0. A Splash Screen másik előnye. illetve egy új. Ezt könnyen ellenőrizhetjük. A másik jelenség az.0"> <Button Canvas.

és a tulajdonságait beállítani: a Build Action legyen Content.BeginInvoke(() => CreateStarField(10)). // // } CreateStarField(5000). } } A BGCreateStars 500-szor lefuttatja a CreateStarField metódust 10 csillaggal.ElapsedMilliseconds + " ms"). mintha az alkalmazás egyesével rajzolgatná őket. és tegyük be a ContentPanel háttérképének (13-3.png néven). a Copy to Output Directory pedig Copy if newer. így nincs értelme.cs tartalmát teljes egészében visszaállíthatjuk az eredetire (a konstruktorban egy InitializeComponent hívás marad csak). szinte olyan. i < 500. a program azonnal reagál a gombnyomásra. Előre elvégzett munka Ez mind szép.xaml. t.ben pedig a ContentPanelt a következőre cseréljük: 325 . A MainPage. starsBG.Name = "Stars".BeginInvoke híváson keresztül kell elérni a CreateStarField metódust.png A MainPage.Show("Startup time: " + stopwatch.Start().Lassú betöltődés kezelése private void OnLoaded(object sender. a betöltődés után azonnal? Ebben az esetben is van megoldás – egyszerűen készítsünk egy screenshotot a kívánt csillagmezőről. MessageBox. 13-3 ábra: A starsBG. A fentiek alapján módosított alkalmazásból kivettük a MessageBox hívását is. A programot futtatva már igen kellemes felhasználói élményben van részünk: az indulási idő minimális.Sleep(30). private void BGCreateStars() { for (int i = 0. ábra). és minden futás után pihen 30 ms-ot. t. mert az még a csillagok kirajzolása előtt megjelenne. de mi van. Ezért az UIDispatcher. RoutedEventArgs routedEventArgs) { Thread t = new Thread(BGCreateStars). Ehhez a projektben el kell helyezni a fájlt (pl.xaml . A csillagok pedig szépen lassan jelennek meg. Thread. A CreateStarField azonban az UI szálon kell. ha nekünk a teljes csillagmezőre van szükségünk. mert az UI-t manipulálja. i++) { UIDispatcher. hogy fusson.

13. Teljesítmény

<Canvas x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Canvas.Background> <ImageBrush Stretch="None" ImageSource="/starsBG.png"/> </Canvas.Background> <Button Canvas.ZIndex="1">I am not doing anything...</Button> </Canvas>

Tádááám! Az alkalmazás fél másodpercen belül elindul még 5000 csillaggal is! Ha mégis szükségünk lenne a véletlenszerű csillagmezőre, egyszerűen készítsünk 10 különböző képet, és azok egyikét állítsuk be kódból háttérnek.

Kis összefoglalás
A fenti alapelvek persze „valódi” alkalmazásoknál is használhatók. Az iniciális teendők elhalasztására jó példa a SurfCube 3D Browser alkalmazás 4.0 változata. Mivel az app indulása túllépte az 5-6 másodpercet, egyre több felhasználó panaszkodott. Volt, aki egyenesen azt gondolta, hogy a Splash Screen az ő bosszantásukra van ott, és csak azért tettük oda, mert tetszett nekünk a logó. Ezt mind el is fogadta volna, de az már felháborította, hogy az alkalmazás megvásárlása után is túl sokáig volt látható a Splash Screen! A SurfCube 4.0-ban ezért a kocka oldalait már eleve „Collapsed” állapotban töltjük be. Az első forgatáskor váltunk át innen „Visible”-re. Ez kicsit kényelmetlen talán (bár némi loading… felirattal és animációkkal ellensúlyoztuk a dolgot), de lehetővé tette, hogy az indulás 3.5 másodpercre rövidüljön. A másik dolog, ami sokat segíthet, ha a ritkán használt funkciókat külön assembly-be tesszük. Ekkor, amíg az assembly-re nem történik hivatkozás a kódban, azt nem tölti be az operációs rendszer. Az előre elvégzett munkára pedig jó példa a „Névnap” alkalmazásom. Itt egy SQL CE adatbázis tartalmazza a névnapokat. Ez az adatbázis egy szöveges fájl alapján, az első futtatás során jön létre – a lapkák és az alkalmazás későbbi futása már az SQL CE-t használják. Még jobb megoldás ilyen esetben, ha a (csak olvasásra szánt) SQL adatbázist már a fejlesztés során a XAP fájlba helyezzük, így a legelső futás is gyors lehet.

Akadozó animációk okai, megoldása
Windows Phone Silverlightban többféle módon lehet animációt létrehozni. Kezdjük a legritkábban használatos, de a teljesítmény szempontjából a legkritikusabb megoldással – az ún. procedurális animációval! Az animációval azt akarjuk szimulálni, hogy mit lát egy részeg, sokszemű űrhajós, akivel szembe jön a csillagos űrben egy TIE figther. Ehhez először is elkészítettem egy TIEFighter.xaml user controlt. Ennek kódját felesleges lenne ide bemásolnom – elérhető a könyvhöz tartozó letölthető anyagok között (13-4 ábra).

13-4 ábra: a TIEFighter.xaml Expression Blend-ben

326

Akadozó animációk okai, megoldása A procedurális animáció lényege, hogy minden képkockában (frame) újraszámoljuk az objektumok helyzetét. A teljes kód a fejezethez mellékelt kódban elérhető, itt csak a lényeget emelném ki. Ahhoz, hogy a ProceduralAnim példa induljon el, a Properties/WMAppManifest.xml fájlban a DefaultTask NavigationPage értékét módosítani kell:
<DefaultTask Name ="_default" NavigationPage="ProceduralAnim.xaml"/>

Maga az animáció a ProceduralAnim.xaml.cs fájlban, a CompositionTargetOnRendering eseménykezelőben történik. Ez a CompositionTarget osztály Rendering eseménye, amely minden alkalommal lefut, amikor az UI szál egy új képkocka rajzolására készül. Az eseménykezelő a következőképpen néz ki:
private int frameCount = 0; private void CompositionTargetOnRendering(object sender, EventArgs eventArgs) { if (frameCount >= 100) frameCount = 0; for (int i = 0; i < Ties.Count; i++) { var tieFighter = Ties[i]; CompositeTransform tr = (CompositeTransform) tieFighter.RenderTransform; tieFighter.Opacity = frameCount/100.0; double scale = 1 + frameCount/100.0; tr.ScaleX = scale; tr.ScaleY = scale; tr.Rotation = frameCount / (i+1.0); } frameCount++; }

A Ties egy TIEFighter objektumokat tartalmazó lista. A fenti függvény nem csinál mást, mint végigmegy az összes TIE Fighter-en, és mindegyiknek átállítja az átlátszóságát, méretét és elforgatását. A 13-5 ábra mutatja, hogy három TIE Fighter esetén (vagyis ha a részeg űrhajósnak három szeme van nyitva) milyen animációt láthatunk.

13-5. ábra: három TIE fighter animációja Az ábrák jobboldalán látható számok az ún. frame rate counter-ek – érdemes itt kitérni rájuk. 327

13. Teljesítmény

Frame Rate Counters
Az App.xaml.cs fájlban a konstruktorban a következő sorokat találhatjuk:
// Show graphics profiling information while debugging. if (System.Diagnostics.Debugger.IsAttached) { // Display the current frame rate counters. Application.Current.Host.Settings.EnableFrameRateCounter = true; // Show the areas of the app that are being redrawn in each frame. //Application.Current.Host.Settings.EnableRedrawRegions = true; // Enable non-production analysis visualization mode, // which shows areas of a page that are handed off to GPU with a colored overlay. //Application.Current.Host.Settings.EnableCacheVisualization = true; // Disable the application idle detection by setting the UserIdleDetectionMode property of the // application's PhoneApplicationService object to Disabled. // Caution:Use this under debug mode only. Application that disables user idle detection will continue to run // and consume battery power when the user is not using the phone. PhoneApplicationService.Current.UserIdleDetectionMode = IdleDetectionMode.Disabled; }

Láthatjuk, hogy még két eszköz áll rendelkezésre a grafikai teljesítmény analizálásához - a redraw regions (újrarajzolt területek) és a cache visualization (cache vizualizáció). Ezekről később lesz szó. A fenti sorok határára, ha egy alkalmazást debug módban indítjuk (F5-el), a képernyő oldalán megjelenik néhány számláló (ezeket hívjuk Frame Rate Counter-eknek), amint az a 13-6 ábrán is látható.

13-6. ábra - Frame Rate Counters Mit is jelentenek ezek a számok? Az egyes Frame Rate Counterek jelentését az alábbi táblázat foglalja össze, amely a számokat balról jobbra sorolja fel: Counter Composition szál frame rate Magyarázat Azt mutatja meg, hogy másodpercenként hányszor kerül a képernyő frissítésre. Ha ez a szám 60-nál (egyes eszközökön 50nél) kisebb, az animációk veszítenek folyamatosságukból. Ha 30 alá csökken, a felhasználók is észreveszik a problémát, és a szám pirosra vált. Az UI szál az, ahol a raszterizáció (renderelés) történik, és ahol az általunk írt kód fut (hacsak nem indítunk új szálat). Ezért, az alacsony UI szál frame rate azt jelenti, hogy az alkalmazás nem

UI szál frame rate

328

Akadozó animációk okai, megoldása

Counter

Magyarázat válaszol időben az inputra. Előfordulhat, hogy ekkor a Composition szálon és a GPU-n továbbra is folyamatosan futnak az animációk, de a felhasználói élményt igencsak rosszul érinti, ha az UI szálat leterheljük. Azt mutatja, hogy a textúrák mennyi videó- és rendszermemóriát használnak Az explicit felületek számát mutatja, amellyel a GPU dolgozik. Ha egy FrameworkElement példányon a CacheMode tulajdonságot BitmapCache értékre állítjuk, vagy a Composition szálon futtatunk egy animációt, a számláló értéke megnő. A GPU által használt implicit felületek számát mutatja (lásd később) A GPU-k egyik legfontosabb teljesítmény-mutatója a Fill Rate. A GPU-k egy másodperc alatt csak bizonyos számú pixelt tudnak megrajzolni. A Windows Phone 7 esetén a kijelző 800x480 pixelt tartalmaz, és ezt egy első generációs hardver GPU-ja képkockánként kb. 2.5-szer tudja megtölteni. A Fill Rate 1-es értéke azt jelenti, hogy a GPU egy képernyőnyi pixelt rajzol fel frame-eknént. Ha ez a szám 2.5 fölé emelkedik, a GPU szűk keresztmetszetté válik. Ha a számláló 3 fölötti értéket mutat, pirossá válik, mert az animációk elvesztik folyamatosságukat a frame rate csökkenésével. Figyeljünk oda arra, hogy ha az alkalmazásnak megadunk egy háttérszínt, ez önmagában 1-el növeli a Fill Rate-et, mert a GPU-nak először ezt a hátteret kell megrajzolnia. Ezért célszerű a hátteret átlátszónak hagyni, ha a rendszer témáját használjuk.

Textúra-memória használata Explicit felületek (surface) száma

Implicit felületek (surface) száma Fill Rate

A fentiek alapján látható, hogy három vadászgéppel az emulátor kb. 15 FPS-el tudja futtatni az UI szálat. (A telefonom12-13 fps-t mutat). A problémát nem a magas Fill Rate okozza, mivel az fixen 1. A telefon még 1 TIE esetén is könnyen lemegy 20-30 FPS környékére. Mi lehet ennek az oka?

Redraw Regions
Ha bekapcsoljuk a Redraw Region opciót, hozzáértő szem számára rögtön nyilvánvalóvá válik a probléma. A 13-8 ábrán látható, hogy mit okoz a bekapcsolása.

329

13. Teljesítmény

13-8. ábra: Redraw Regions A Silverlight a nagyobb sebesség érdekében spórol a rajzolással. Így csak azokat a területeket rajzolja újra, amelyek változnak két képkocka között. A Redraw Region ezeket az újrarajzolt területeket minden egyes frame esetén különböző színnel megfesti (ez némi CPU időbe telik, így ne végezzünk FPS méréseket, ezzel az opcióval). Az ábrán jól látszik, hogy a képernyő jelentős részét újra kellett rajzolni, ahogy a TIE Fighter elhalad a csillagok fölött és a kezelőszervek alatt. Ráadásul maga a TIE Fighter is újrarajzolásra kerül, mivel folyamatosan változik a mérete és az elforgatása. Ezt a raszterizálást minden frame-ben a CPU végzi – így nem csoda, ha nem képes másodpercenként 20-25-nél többször új képkockát készíteni. Korábban említettem, hogy a GPU sok olyan feladatot képes hatékonyan ellátni, amire itt is szükség van. Kompozíció, forgatás, átméretezés, stb… hát akkor:

Használjuk a GPU-t!
Az Enable GPU Acceleration gomb bekapcsolásával a helyzet drámaian megváltozik. A Redraw Region abbahagyja az őrült villódzást. 3 vadászgép esetén a telefon még érezhető lassulás nélkül animál. Még tíz TIE Fighternél sem esik 20 FPS alá a sebesség. Ugyanakkor az emulátor egy erős videokártyával mindennemű lassulás nélkül elvisel tíz vadászgépet, de hát az a videokártya ugye egész más kategória, a Call Of Duty MW 3-ra van méretezve… Mi is történik ilyenkor?

330

Akadozó animációk okai, megoldása

private void enableGPU_Click(object sender, RoutedEventArgs e) { foreach (var fighter in Ties) fighter.CacheMode = GetTIECacheMode(); } private CacheMode GetTIECacheMode() { bool enabled = enableGPU.IsChecked.Value; return enabled ? new BitmapCache() : null; }

A TIEFighter vezérlők CacheMode tulajdonságát állítjuk attól függően, hogy a GPU gyorsítást a felhasználó be- vagy kikapcsolta éppen. Kikapcsolt esetben null értéket kap, míg bekapcsolva a BitmapCache osztály egy új példányát. A BitmapCache kifejezés mindent el is mond arról, hogy mit jelent a GPU gyorsítás. Azt jelenti, hogy az adott UIElement raszterizált változata a GPU-ban eltárolásra kerül (cache). Ezután a GPU végzi az így tárolt textúra mozgatását, átlátszóságának változtatását, a többi textúra alá- vagy fölé helyezését, forgatását, átméretezését, perspektivikus torzítását, vagy akár négyszögletes vágását (clipping). Amennyiben az így eltárolt elem textúrája változik (pl. más színe lesz), akkor a Silverlight Runtime automatikusan frissíti a GPU textúra-memóriájában az elemhez tartozó képet. Ez persze azt is jelenti, hogy bizonyos animációk gyorsabban futnak, mint mások. A CPU animálja pl. a nem téglalap alakú vágásokat, a szín-animációkat, a layout-ot, gradienseket, stb. Ha ilyen animációkat használunk, tegyük azt inkább kis méretben – így a CPU-nak nem kell annyi pixelt átszámolnia, és így fenntartható a magas FPS érték. A GPU működésének nyomon követésére még egy opció szolgál, ismerjük meg most ezt!

Cache vizualizáció
A cache vizualizáció opciót bekapcsolva a 13-9 ábrán látható eredményt kapjuk.

13-9: ábra: cache vizualizáció és GPU gyorsítás

331

hogy ennek a gombnak az eseménykezelőjében egyszerűen csak meghívjuk a CreateStarField metódust 6000-es számmal.6 képernyőnyi pixelt rajzol ki. Érdemes megjegyezni.  A cache vizualizáció megmutatja a feleslegesen használt GPU textúrákat. az UI szál szóhoz sem jut: a gomb „benyomva” marad jóval az elengedése után is (1310 ábra). De akármennyi trükközést csinálunk is. hogy az animáció tökéletesen folyamatos. és a 2-es érték mutatja a számlálók között. amit a GPU megjelenít. hogy minden vadászgép saját GPU textúrát kapott.xaml fájlban található – sőt néhány Easing-gel megbolondítva sokkal természetesebb eredményt kapunk. A fejezet elején leírtakból tudhatjuk. hogy a GPU minden frame-ben 11.5 fölött elkezd csökkenni a frame rate. Compositor és Input szálak A StoryBoardAnim. mivel az UI szál a csillagok kirajzolásával van elfoglalva.xaml oldal nem tartalmaz csillagokat. A Fill Rate 11. és félig átlátszóvá tesz minden textúrát. Teljesítmény A cache vizualizáció kékkel fest meg. mivel előttük és mögöttük cache-elt textúrák találhatók. A magas fill rate-et természetesen a sok (és egyre növekvő méretű) vadászgép okozza. a Silverlight futtatókörnyezete automatikusan bekapcsolja a GPU-t. egy jelentős részük kimegy a képernyőről. A legtöbbször nem is kell ezen gondolkozni. így lehetővé válik azok kiküszöbölése. és 3.5 környékén már bántóan elkezd akadozni az animáció. A Fill Rate az új generációs telefonokban az erősebb GPU-nak hála már magasabb értéknél kezd lassítani – azonban még jó darabig figyelembe kell vennünk az első generációs telefonok sebességét. Érdemes újra végigvenni a Frame Rate Counter-eket:    UI és Composition thread FPS – ezek jóval magasabbak a telefonon tapasztalhatónál. előbb-utóbb elérjük a hardver teljesítőképességének a határát – 50 teljes méretű vadászgépet már egyik telefon sem fog élvezhető sebességgel mozgatni. hogy ez a megközelítés hosszú másodpercekre teljesen lefoglalja az UI szálat. a telefon szépen be is pirosította nekünk. Fill Rate – A probléma forrása itt keresendő. így nem engedhetjük meg magunknak az ellustulást. 332 . Könnyen ellenőrizhetjük ezt az állítást az Enable GPU Vis opció bekapcsolásával – jól látható. Ezeket a felületeket implicit surface-nek nevezzük.xml fájlban a DefaultTask-ot: <DefaultTask Name ="_default" NavigationPage="StoryBoardAnim. bár esetünkben ezen sokat javít az. nem hagytunk időt arra. StoryBoard-ok segítségével.13. ez ám a kényelem! UI. Ez igen magas szám − az első generációs telefonokon már 2. Beépített animációk és a GPU A fenti animáció persze jóval egyszerűbben reprodukálható Blend-ben. hogy bár nem adtuk meg a háttérképnek és a kezelőszerveknek a BitmapCache értéket.xaml"/> Ha így elindítjuk az alkalmazást. nem vészes Textúrák száma – a GPU jelenleg 12 textúrával dolgozik. egy a háttéré és egy a kezelőszerveké. És valóban. Ebből 10 a TIE Fighter-eké (mindegyikre jut egy). amennyiben StoryBoard animációt használunk procedurális helyett. Használt textúra memória – 8 Mbyte. Az eredmény a StoryBoardAnim. hogy mely felületeket tárolja a GPU. hogy a nem benyomott állapotot kirajzolja. hogy mire megnőnek. A kódot megvizsgálva azonban láthatjuk. Valóban. azokat a Silverlight automatikusan a GPU-n tárolja. Ha ezt megnyomjuk. Így nyomon követhető az. Ez csak GPU használatával lehetséges – amit mi sehol nem kapcsoltuk be. Van azonban egy „Add 6000 stars” gomb a képernyőn. feltűnhet. még öt TIE Fighterrel is. A futtatáshoz a már ismert módon írjuk át a WMAppManifest.6 értéke azt jelenti. Semmi háttérszál és egyéb varázslat. pár másodperccel később megjelenik a 6000 csillag. mivel a screenshot emulátoron készült.

Ugyanakkor az animáció egy pillanatra sem lassult le a nagy csillaggyártás közben! Ennek az az oka. Ennek oka. Ha hosszú számítást kell végeznünk. használjunk háttérszálakat. rossz válaszidejű szituációt megoldja. A legfeltűnőbb probléma a listák görgetésekor jelentkezett – a görgetett lista animációja folyamatos volt. A jó hír.Hosszú válaszidő kezelése 13-10 ábra . és így csak későn észlelte az érintés eseményt. vegyük elő az alkalmazás-indítás optimalizálásánál leírtakat. hogy a fentiekben bemutatott technikák a gyorsabb alkalmazás betöltésre és a folyamatosabb animációk elérésére a legtöbb esetben segíthetnek itt is. Ez mindaddig így van. Az elkerülhetetlen várakozást pedig könnyebbé tehetjük. amíg olyan animációkat alkalmazunk. de újabb érintésre (pl. amikhez nincs szükség arra. 333 . A Mangoban egy új. hogy ez igen kellemetlen felhasználói élményt okozott. ha a felhasználót tájékoztatjuk a folyamat állásáról (lásd a szubjektív teljesítmény résznél). Mondanom sem kell. Hosszú válaszidő kezelése A hosszú válaszidőnek számos oka lehet. amit a Mangóban (WP7. Ez és néhány további hangolás a WP7 első kiadásában tapasztalható legtöbb. Ha bonyolult UI-t kell megjelenítenünk. hogy az animációk egy külön szálon. ha a gördülés megállításához megérintettük a kijelzőt) néha csak másodpercnyi késleltetéssel reagált. még a gomb is benyomva maradt. harmadik szál is bevezetésre került az input kezelésére. a Compositor szálon futnak (és a GPU-n kerülnek megjelenítésre). hogy az elemeket újraraszterezze az UI szál.5) szerencsére már javítottak a külön szálon futó input-kezelés bevezetésével.A UI szálat teljesen blokkolja a 6000 csillag kirajzolása. hogy a UI szál (amely Mango előtt az inputot is kezelte) el volt foglalva a folyamatosan érkező elemek raszterizálásával. (A mozgatáshoz és forgatáshoz használt RenderTransform a layout után kerül alkalmazásra. esetleg az elrendezés (layout) változása miatt a vizuális fát újra kelljen számolni. akár a BackgroundWorker osztály segítségével is. így az elrendezést nem befolyásolja).

ahol érdemes a kód karbantarthatóságából áldozni. azt nyugodtan megteheted holnap is (lásd a folyamatos csillag kirajzolás az első példákban a gyorsabb alkalmazás-indulás érdekében). Adatbázis használatakor definiáljuk a Version oszlopot. Canvas-t Grid helyett. hacsak nincs szükségünk a png átlátszóságára (vagy vonalas grafikákon a jóval kisebb fájlméretre). de szinten minden esetben érdemes megfontolni a használatát (talán az egyetlen kivétel a Panorama háttere – a Panorama vezérlőt csak a kép betöltődése után érdemes megjeleníteni). és lehetőleg ugyanitt kommunikáljunk a felhővel is. és többek között a fentebb már említett Input szálnak köszönhetően nagyságrendeket javult az interaktivitása. Egyszerűsítsük a layoutot . amikor üres elemek jelennek meg. gyorsabb lesz annak indulása. mivel a layout és raszterizáció nem képes lépést tartani a gyors görgetéssel.13. Amit ma megtehetsz. ahol lehet! Listákban a DataTemplate-eknél ez különösen hasznos lehet. a könnyű. Lássunk tehát néhány ilyen tippet a részletes példák mellőzésével:       A Pivot vezérlő gyorsabb. A legfontosabb annak megértése. plusz munkát befektetni a szemmel látható eredmény érdekében. hogy ilyen drasztikus változtatásokra van szükség! Az UI szálat hagyjuk szabadon – a hosszabb műveleteket háttérszálon végezzük. amivel a teljesítményt javítani lehet. ha már nincs rá szükség – még akkor is. Ne kezdjünk el azonban megszabadulni minden adatkötéstől. Az alkalmazásunkat daraboljuk több DLL-re. A képek dekódolása alapértelmezésben az UI szálon történik. A CreateOptions="BackgroundCreation" beállításával ez háttérszálra tehető. az adatkötés rezsije. mint a png-é. Ez a funkció a leghasznosabb listáknál (pl. Ugyanakkor egy hosszú listában az elemek kirajzolását akár 30ms-al is hasznos lehet megrövidíteni annak érdekében. Ha a képeket nem Resource-ként. ritka. mint a Panorama. kapcsoljuk ki ezt a beállítást. Szerencsére a Mangóban számos javításon esett át a listakezelés. így megrövidítve a betöltési időt! Az adatkötés lassabb. deklaratív UI leírás ára a XAML interpretálásának költsége.5 alatt! Ha határozatlan ProgressBar-t (IsIndeterminate=True) alkalmazunk. hogy semmi nincs ingyen – a Grid fejlett layout képességeinek ára. 334 . és használjunk előre fordított lekérdezéseket (compiled queries). A teljesítmény-optimalizálás művészete abban áll. Használjunk jpg-t. implementáljuk az INotifyPropertyChange interfészt az entitásokban. Teljesítmény Általános tippek Számos további tipp található a neten. hogy sokat kell számolni az elemek elhelyezésén.        Listák Mérvadó vélemények szerint a Windows Phone 7. mint a tulajdonságot közvetlen állítása (pl. esetleg a Silverlight for Windows Phone Toolkitból a PerformanceProgressBar vezérlőt használjuk. „blanking” – vagyis. FirstNameTextbox. Nincs értelme például órákat ölni abba. A jpg dekódolása gyorsabb. a Fill Rate-et 2. ami Supermant legyengítette) a listák teljesítménye volt. ha a Mango-ban megjelent SystemTray.FirstName).0 kriptonitja (a zöld ásvány. Facebook ismerősök listázása).használjunk StackPanel-t.Text = Person. A ScrollViewerben (és listákban) az animációkhoz hasonlóan automatikusan GPU cacheelésre kerülnek az elemek. ha a vezérlő nem látszik a képernyőn! Még jobb. hogy az alkalmazás indulása 200 ms-al gyorsabb legyen.ProgressIndicator -t (bár ez csak a képernyő tetején jelenik meg). hanem Content-ként helyezzük az alkalmazásba. A Compositor szálat lehetőleg tartsuk 60 fps körül. hogy a görgetés közben kevesebb legyen az ún. hogy meg kell találni azokat a pontokat.

sok szöveg. Szubjektív teljesítmény Szubjektív teljesítmény alatt az alkalmazás sebességének az érzetét értjük. szemben a valódi. Összetett. ezért üres pixelek jelennek meg). amikor olyan gyorsan pörög egy lista. Egy olyan listát. De ha rendeltetésszerűen használjuk a listákat és odafigyelünk a Fill Rate-re.Összetett ItemTemplate Amikor kipróbáltam a telefonon. hogy a könyvhöz készítettem egy „állatorvosi lovat”. kép (13-11 ábra). 13-11 ábra . mint a valóságos. Nemegyszer a szubjektív teljesítmény fontosabb a felhasználónak. ritkán fogunk problémába ütközni. mérhető sebességgel. „Blanking” sem volt tapasztalható (az a jelenség. Természetesen a Mangóban is lehet rosszul teljesítő listákat készíteni.Szubjektív teljesítmény Olyannyira így van ez. nehezen számolható elrendezés. aminek az ItemTemplate-je tele van „teljesítménygyilkos” elemekkel. Egy-két lassú ValueConverter vagy hatalmas képek picire lekicsinyítve. jött a meglepetés – nem volt tapasztalható semmi probléma! Az animáció 60 fps-el döngetett. hogy az UI szálnak az újabb elemeket nincs ideje kirajzolni. a lista azonnal reagált a mozdulatokra. 335 . esetleg némi gradiens a háttérben már gondot okozhatnak.

13-12 ábra: a tilt (bedöntés) effektus segíti a visszajelzést A hatás létrehozásához a Silverlight for Windows Phone Toolkit-ban található TiltEffect osztályt használhatjuk (lásd még http://www. hogy a telefon „vette” az érintést. ezt a kis pluszmunkát mindenképpen megéri. Ráadásul elmúlik az a bizonytalan érzés. hogy az interakció közvetlensége miatt a teljesítmény-elvárások nagyobbak egy érintőképernyős alkalmazással szemben. Ha a program azonnal reagál.windowsphonegeek. 336 . Tilt effektus A tilt (bedöntés) effektus elsősorban a visszajelzést segíti. elengedés után pedig visszaugranak a helyükre. Teljesítmény Már a fejezet elején is volt arról szó. Akár egyetlen kódsorral az egész PhoneApplicationPage-re engedélyezhetjük az effektust. és jelzi. esetleg egy kis animációval szórakoztat.13. hogy „megnyomtam? Nyomjam meg még egyszer?” – ami a taktilis visszajelzés hiánya miatt amúgy is gyakori az érintőképernyők használóinál. A bedöntés működése jól látható a Start képernyőn (13-12 ábra). Ez a Metro nyelv egyik jellegzetes eleme – az aktiválható elemek az érintés helyétől függően 3D-ben bedőlnek. mint egy egeres-billentyűzetes programnál. hogy vette az utasításunkat. amíg dolgozik.com/articles/Silverlight-for-WP7Toolkit-TiltEffect-in-depth). Használatával már a lenyomás pillanatában tudathatjuk a felhasználóval. sokkal gyorsabbnak érezzük.

ha a kérdéses másodperc alatt történik valami a képernyőn. a SystemTray.vagy egy másodperces számítást is azonnalinak lát a felhasználó. Például egy lapozás vagy fade animáció közben megtörténhet a betöltendő oldal layout-számítása és raszterizálása. hogy hol tart a számítási folyamatban (engedéllyel használva) Köztes animációk Akár egy fél. mert a másik két megoldással szemben túlságosan lefoglalja az UI szálat.Szubjektív teljesítmény A folyamat jelzése Hosszan tartó folyamatoknál (pl. Hosszan tartó folyamatoknál fontos még. ha GPU-optimalizáltan tudjuk őket végrehajtani. vagy egy animáció (pl. Erre bevált módszer a ProgressBar használata. ábra). A figyelem elterelésével leplezzük a lényeget és átverjük az érzékeket.ProgressIndicator -t. egy könyvjelző kiválasztása után a kockát vissza kell forgatni az első oldalára. Jó példa lehet erre a SurfCube böngészőben a könyvjelzőre való navigálás. megőrizve ezzel az UI szál válaszképességét. hogy az alkalmazás dolgozik.ami még rosszabb. egy kör forgatása). a könyvjelző lenyomásáról csak pár tized másodperc késéssel 337 . egy szerver válaszára várunk) a ProgressBar használata kerülendő. szerverre várakozás. hogy a munkát háttérszálon végezzük. 13-13 ábra: a Pictures Lab képszerkesztő program saját design-nal jelzi. Ha tudjuk. pörgő kör. Azonban. Azonban a böngésző vezérlő a CPU-t lefoglalja (főleg navigáció elején). ahol a böngésző található. a Toolkit-ből a PerformanceProgressBar vezérlőt. és így a visszaforgató animáció nem látszódik . amennyiben az a GPU-n fut. Határozatlan esetben használhatunk még saját animációt is (pl. főleg. Amikor a lassabb gyorsabb(-nak tűnik) A szubjektív teljesítmény optimalizálása némileg hasonlít egy bűvészmutatványhoz. A WP7 animációi ideálisak erre a célra. ha a folyamat időtartama bizonytalan (pl. hosszas számítások) érdemes a felhasználónak jelezni. Az objektív gyorsaság érdekében a könyvjelző megérintése után azonnal elindítottuk a betöltődést és a forgatást. és így az animáció végén az új információ azonnal megjelenhet (vagy beúszhat). mozgó pöttyök) megjelenítése. vagy saját megoldást. érdemes határozott folyamatjelzőt választanunk. mint ahogy a Pictures Lab készítője tette (1313 ábra). Mivel a könyvjelzők a kocka tetején helyezkednek el (13-14. hogy a folyamatban nagyjából hol tartunk. Erre használhatjuk akár a ProgressBar-t.

90 Mbyte-ot használhat a program. de az azonnali reakció miatt a felhasználók egyértelműen (de tévesen) úgy érezték. Teljesítmény értesül a felhasználó. mert a Marketplace az alkalmazás befogadásakor igen szigorúan ellenőrzi a memória használatát. 13-14 ábra: a SurfCube visszafordul az első oldalra a könyvjelző kiválasztása után. Természetesen a Silverlight-ban és a . hogy az alkalmazás sokat gyorsult. nagyobb memóriával rendelkező készülékeken ennél többet is.13. és a böngészőt most már csak a forgatás animáció befejeztével irányítjuk át az új címre. Így a teljes oldal-betöltődési idő (az érintéstől számítva) ugyan néhány tized másodperccel megnőtt. és csak a fordulás után kezdi meg az oldal betöltését (engedéllyel használva) Memória-optimalizálás A memória takarékos használata a szűkös erőforrások mellett már csak azért is fontos. A szabály az. Érdemes azonban áttekinteni néhány platform-specifikus területet.NET-ben megszokott optimalizáló fogások Windows Phone-on is működnek. Ezért változtattunk a működésen. 338 . hogy 256 Mbyte-os telefonon max.

gördíthető listát tartalmaz. Amennyiben az alkalmazást debuggerrel futtatjuk. A már messzire elgörgetett elemek ugyan törlődnek a memóriából. és a ListBox vezérlőben ez az alapértelmezett működés). ha egy 100x100-as thumbnail-t jelenítünk meg. Ha ez nem lehetséges. A képeknél ezért (és a letöltési. így ennek hatása elhanyagolható. Szerencsére Peter Torr készített egy MemoryDiagnosticsHelper osztályt (http://blogs.aspx). a MemoryDiagnosticsHelper még egy Debug. A pontosabb mérés érdekében váltsunk Release konfigurációba. Próbáljuk ki a fejezet első mintapéldáján.DecodeJpeg(sourceStream.Start(TimeSpan.Assertel is jelzi. mivel az emulátor – a már említett okok miatt – hamis eredményt fog adni. Nyilvánvaló tehát. miközben csak a MemoryDiagnosticsHelper bekapcsolása okozta a gondot. Hiába csak 100Kbyte-os egy 800x480 pixeles fénykép jpg formában – a telefonnak minden egyes pixellel kell számolnia.msdn. így az 800x480x4 byte-ot (több. Könnyen elképzelhető. de a szerverről 500x500-as képet kapunk. lassabbak lehetnek a számítások. láthatjuk. ahol minden elem egy vagy több további. már igen komoly memóriát felemészthet. A legnagyobb memória-falók természetesen a képek.FromMilliseconds(500). nomeg a dekódolási sebesség érdekében is) érdemes a képeket a végleges méretükben kezelni. hogy 500 csillag esetén kb. Az alapértelmezett Panorama alkalmazás például 28 Mbyte memóriát eszik. Optimalizálás Ha a fenti kódot a fejezet elején található példaprogramba beírjuk. hogy a vizuális fa mérete befolyásolja a memória-használatot.com/b/ptorr/archive/2010/10/30/that-memory-thing-i-promisedyou. Egy lista esetén a látható elemeken kívül még néhány további is renderelésre kerül. amely pont ebben segít. majd a Launch Application megnyomása után 339 . 100). true). és a pixeljei a memóriában tárolódnak. hogy egy sokelemes panoráma. Egy Panorama háttere ennek többszöröse is lehet. Windows Phone Performance Analysis Egy bonyolultabb alkalmazásban nem egyszerű megtalálni a teljesítmény-problémák okát. A MemoryDiagnosticsHelper – ami a fenti példában 500 ms-onként fut és a Garbage Collector-t minden alkalommal működteti – hátrányosan befolyásolja az alkalmazás teljesítményét: akadozhatnak az animációk. Szerencsére a Windows Phone SDK része a Windows Phone Performance Analysis (WPPA) eszköz.5 Mbyte) foglal a memóriában. ha a szerveren készítünk 100x100-asat is. de a helyükre a görgetés során új elemek kerülnek (ezt hívjuk virtualizációnak. 9Mbyte-ot foglal az alkalmazás. 100. anélkül. hogy több ezer vagy tízezer elem található a fában. aminek segítségével folyamatosan megjeleníthető az alkalmazásunk memóriahasználata. Jómagam is jó néhány felesleges órát eltöltöttem korábban folyamatosan működő animációk akadozása után nyomozva. akkor legjobb. Ráadásul a megjelenített vezérlők szintén bitmap formában vannak jelen. Miután a MemoryDiagnosticsHelper. mint 1. egyetlen sorral elindítható: MemoryDiagnosticsHelper. hogy képek lennének a listákban. akkor a kép dekódolásakor már a végső méretet adjuk meg: PictureDecoder. Tehát. majd a Visual Studio Debug menüjében található „Start Windows Phone Performance Analysis” menüponttal indítsuk el a WPPA-t! A 13-15 ábrán látható képernyő jelenik meg. hogy túlléptük a 90 Mbyte-os limitet. de szerencsére viszonylag ritka. az 5000 csillagot kirajzoló programon! A tesztelést minden esetben a fizikai eszközön végezzük.cs fájlt hozzáadtuk az alkalmazáshoz.Windows Phone Performance Analysis A memória foglalás kijelzése Sajnos a fentebb már részletezett teljesítmény-mérő eszközök között nem szerepel a használt memória kijelzése. míg 5000-nél 16-ot.

Alatta a Frame Rate azt mutatja. A zöld szín az UI szálat. majd a Select All-t a grafikonon). ezért nincs itt sok értékelhető adat. az esetenként megjelenő lila pedig a az alkalmazás nem UI szálait (beleértve a Compositor és a háttér-szálakat). Mit jelent mindez? 13-16 ábra: Az analízis eredménye A felső skála a másodpercekben mért időt mutatja. a szürke a rendszer-szálat jelenti. 340 . A CPU-használatot mutató grafikonon a fehér szín azt jelzi. amikor a CPU nem csinál semmit. Teljesítmény elindul az alkalmazás a telefonon. majd állítsuk le az adatgyűjtést! 13-15 ábra: A Windows Phone Performance Analysis indítóképernyője Némi számolás után a 13-16 ábrán látható eredményt kapjuk (nyomjunk egy jobb gombot. Várjuk meg.13. Jellemzően 30 és 60 közötti értékeket szeretünk itt látni. amíg megjelennek a csillagok. hogy egy másodperc alatt a képernyő hányszor került újrarajzolásra. Mivel a csillagok kirajzolása után az alkalmazás nem csinál semmit.

képkocka megrajzolásához milyen függvényhívásokat hajtott végre a rendszer. majd a Frames szövegtől jobbra található kis háromszögre kattintva válasszuk a Functions menüpontot. lila – nem CPU) és képbetöltések találhatók – ezek ebben az alkalmazásban nem fordulnak elő. hogy a 4.Windows Phone Performance Analysis A memória-használat grafikonja egyértelmű. képkocka elkészítéséhez szükséges függvényhívások De mi a helyzet az ellipszisek megrajzolásával? Ehhez a Frames melletti háromszögből válasszuk az Element Types lehetőséget. csökkenő sorrendbe rendezhetjük a hívásokat. mi került egy másodpercbe a 4-es képkocka kiszámításánál! Ehhez válasszuk ki a 4-es kockát. hogy az alkalmazás a futása során 5 képkockát készített (0-tól számozva). Ezt több mint 1 másodpercig rajzolta a telefon (Duration és CPU time). az exclusive pedig. amikor az ellipsziseket kirajzoltuk. Ha fent kijelölünk egy legalább fél másodperces időtávot. hogy csak a függvény saját idejét számítjuk. 13-18 ábra: A 4. megtekinthetjük a frame-eket. ekkor a 13-17 ábrán látható eredményt kapjuk! 13-17 ábra: Az alkalmazás első 5 képkockájának adatai Látható. Legvégül pedig a Garbage Collector eseményei. illetve a CPU-használatot. ha a Visual Tree for Frame 4 opciót választjuk (13-19 ábra). 341 . és láthatjuk az 5000 ellipszist. Alatta a program által indított StoryBoard-ok (piros – CPU. Az Inclusive azt jelenti. Az Inclusive samples-re kétszer kattintva. Nézzük meg. Ha a Performance Warnings melletti kis nyilacskára kattintunk. Látható még az adott frame Fill Rate-je és a textúrák száma is. ami nem feltétlenül a rajzolással van összefüggésben. Például az első sorban azt jelzi. az alsó részben a tipikus teljesítményproblémákra hívja fel a figyelmünket a program. Ezt az időt rövidíthettük le. Ebből az ötödik (utolsó) kocka az. hogy az adott függvényből hívott további függvények is beleszámítanak. Láthatjuk. Még látványosabb. amikor Grid helyett Canvas-t használtunk. hogy magas CPU használatot mért az UI szálon – olyan CPU használatot. Először válasszuk ki a Frames-t. és a 13-18 ábrán látható eredményből le is vonhatjuk a következtetést: a legtöbb időt a MeasureOverride és ArrangeOverride – tehát az elrendezéshez szükséges feladatok veszik el.

Ennyire lassan rajzolna szöveget a futtatókörnyezet? A PageTitle viszont csak 5 ms.Functions nézethez navigálunk (13-20 ábra). éles szeműek észrevehették. hogy az első szöveg kirajzolásánál a környezetnek még a TextBox osztályt is be kellett töltenie és értelmezni.CPU Usage . hogy a 4-es kockát a program indítása után 6. Talán meglepő lehet. képkocka vizuális fája és az egyes elemek megrajzolásához szükséges idő Itt fában kibontva látható. A jelenség oka. hogy az ApplicationTitle TextBox kezelése egy tized másodpercbe került. majd a Performance Warnings . Teljesítmény 13-19 ábra: A 4. ha a diagramon kijelöljük a 3-as és 4-es képkocka közötti területet. Visszatérve a képkockákra (13-17 ábra). 342 .13. hogy melyik elemmel mennyit foglalkozott a telefon. csak magára az elrendezésre és a rajzolásra. Mi történt vajon a 3-as kocka vége és a 4-es eleje között. közel 6 másodpercig? Erre a kérdésre a választ úgy kaphatjuk meg. míg a második TextBox-nál már erre nem volt szükség.767 másodperccel kezdte csak el a telefon számolni.

és persze saját alkalmazásokkal is! A Windows Phone Performance Analysis elsajátítása nem egyszerű. 343 . Érdemes kísérletezni még a többi lehetőséggel.Összefoglalás 13-20 ábra: A CreateStarField vitte el a 3-as és 4-es frame közötti idő 88%-át. de az egyik leghasznosabb eszköz lehet a fejlesztés során a teljesítmény-problémák azonosításában. Összefoglalás Egy egész könyvet lehetne írni arról. Szó volt a szubjektív teljesítményről. sőt azon belül a CreateStarField metódusban töltötte. hogy a telefon az ideje jelentős részét a MainPage konstruktorában. Látható. az akadozó animációk lehetséges okait és megoldását. a lassú betöltődés és navigáció. a memóriafoglalás minimalizálásának módjairól és a mindezeket elemezni képes Windows Phone Performance Analysis eszközről is. kitűnő teljesítményű Windows Phone alkalmazásokat. hogy miképp készítsünk gyors. Ez a fejezet csak az út elejét tudta megmutatni – a CPU és GPU használatát.