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

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

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

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

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

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

.

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

.

az eddigi mobil operációs rendszerektől eltérő dizájnnal és szellemiséggel rendelkezik. új lehetőségeket. akik a semmiből. Ez a mobil operációs rendszer azonban elsősorban üzleti használatra készült. Az elmúlt években számos mesébe illő sikertörténetet hallhattunk olyan cégekről. a konkurrens termékekkel nem volt képes felvenni a versenyt. 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. illetve a könyv írásának pillanatáig nem sokat foglalkozott. hogy az okostelefonok megjelenésével egyfajta fejlesztői „aranyláz” tört ki. a fogyasztói piacnak azonban ezek az elvek és ez a termék nem tudott megfelelni. életünk. digitális identitásunk egyfajta kiterjesztéseként gondolunk rájuk. A Google ezzel a kérdéssel nem nagyon foglalkozik. hol vagyunk. Az új igényeknek. gyakorlatilag a nulláról indulva. de a Windows Phone újabb ilyen lehetőséget jelent! A Microsoft. Így nem csoda. azzal a gondolattal. Az a telefon lehet Windows Phone. hogy a Twitter. hogy bizonyos kategória alatt nem támogatnak telefonokat. mikor hol kellene lennünk. Ezt a terméket a megváltozott. 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. A Microsoft valahol a kettő közötti utat választotta. 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. mit szeretünk csinálni és kivel. bármikor elérhetővé válik. 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.1. bármi. sokszor kényszerülnek olyan döntéseket hozni. és maximálisan igyekeznek minket kiszolgálni. hogy az asztali Windows-t vihetjük a zsebünkben. a Windows Phone-nal jelent meg a piacon. illetve az okoskészülékek piacán. Sokszor társként. A világot helyezik kezünkbe. hogy újabb sikertörténetek születhessenek. kik a barátaink. A Microsoft egyike volt az elsőknek az okostelefonok piacán. hogy ez vajon mekkora fragmentációt jelenthet a készülékek piacán. Sajnos az idő előrehaladtával egyre nehezebb sikertörténeteket írni. és alapjaiban új operációs rendszerrel. Nem csoda hát. Habár saját eszközt nem dobott a piacra. amely évről évre csak nő. A Windows Mobile termékcsalád hosszú utat járt be – még ha ez az út igencsak rögös is volt. Az okostelefonok új piaca nemcsak a felhasználók számára jelentenek izgalmas. amely az előírt hardver követelményeket maradéktalanul kielégíti. 15 . kik vagyunk. de nagyon pontos specifikációt írt elő a telefon hardveres képességeit illetően. az alkalmazást hány különböző eszközre és hardver konfigurációra kell elkészíteni. 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. A Windows Phone Platform A Windows Phone megjelenésében merőben újszerű. 1-2 év alatt meghatározó szereplőkké nőtték ki magukat. és újabb lehetőségeket kínál. hogy a Microsoft készüléket nem. A Microsoft . A gyakorlott fejlesztők ezeket a sorokat olvasva biztosan felhördülnek és elgondolkodnak. a Windows Phone és saját alkalmazásboltja (Marketplace) megjelenésével új piacot nyit a vállalkozó szellemű fejlesztők számára. csupán mobil operációs rendszert fejleszt. A Windows Phone különlegessége.ezt a tényt felismerve szemmel láthatólag nem erőltette tovább ezt a vonalat. hanem a fejlesztőcégek számára is. új igényekhez igazítva tervezték. a Facebook. É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 gyártók döntő többsége 512MB-ot tesz a készülékeibe. illetve XNA. 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.1. Integráció a felhővel 3. Futtatókörnyezet 2. illetve futó taszkok közötti váltást szolgálja.     Kijelző:    A kijelzőnek legalább 800 x 480-as felbontással kell rendelkeznie. Iránytű Giroszkóp (jóval pontosabb pozíció/állapot meghatározásra képes. döntésének és egyéb pozícióinak követésére gyorsulásmérőt kell beépíteni. Műholdas navigáció tekintetében Assisted-GPS támogatás szükséges. ún. Kereső gomb: Minden esetben a beépített Bing keresőt hozza fel. valamint Wi-Fi-t kell támogatnia.1-ben ez a viselkedés nem módosítható. Hálózati jellemzők:   Memória:     Navigáció:  Mozgásérzékelés: A telefon mozgásának. Kezdő oldal gomb (Home): A Start képenyőre navigál bárhonnan. Az alkalmazások ennek köszönhetően nem férhetnek hozzá kontrollálatlanul tetszőleges erőforráshoz. sandboxban („homokozó”) futnak. Vissza gomb (Back): Az alkalmazáson belüli navigációt. Marketplace portál szolgáltatások 4. Fejlesztőeszközök Futtatókörnyezet A Windows Phone alkalmazások izoláltan. 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. 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. Saját termékek fejlesztése során két platform közül választhatunk: Silverlight. ezt a futtatókörnyezet szigorúan ellenőrzi. amelyek szorosan kapcsolódnak az operációs rendszer és a navigációs mechanizmus működéséhez. 16 . 7. A készüléknek hálózati kommunikáció tekintetében mobil adathálózatok kezelését. Operatív memória tekintetében legalább 256 MB memóriával kell rendelkeznie a készüléknek.) Adatok tárolásra minimum 8GB-os flash tárolóegységgel kell rendelkeznie a készüléknek. elsősorban biztonsági okok miatt. bármely alkalmazásból.

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

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

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

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

Shell. kiegészíthető. A fenti SystemTray. ha valami XAML-specifikus dologra van szükségünk.assembly=Microsoft. 21 . óra. Az x:Class tulajdonság segítségével azt határozzuk meg. 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.) látszik-e az alkalmazásban. mint a betűkészlet típusa.assembly=Microsoft. már csak a benne levő tartalom – azaz az oldal tartalma –a kérdéses.IsVisible tulajdonság határozza meg azt. hogy melyik saját osztály származik a PhoneApplicationPage osztályból. Mode=TwoWay}"/> Ne aggódjunk amiatt.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.openxmlformats. A következő két tulajdonság azt határozza meg. A „d” prefixszel ellátott beállítások egytől egyig a tervezőfelület számára meghatározott értékek. ezt kizárólag a tervezőeszköz tartja számon. akkor azt ebben a névtérben fogja keresni a XAML Parser. A prefix definíciók után néhány PhoneApplicationPage tulajdonság kerül beállításra. stb.microsoft. mérete.Phone.microsoft. De mi az az x prefix? Az x:Class-nál is feltűnt már korábban.microsoft. 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.Phone" xmlns:shell="clr-namespace:Microsoft. A következő sorokban számos prefix definíciót látunk. futásidőben nem játszanak szerepet. ahol nem szerepel prefix.com/expression/blend/2008" xmlns:mc="http://schemas. Jelen esetben egyetlen Grid panel található benne.Phone. Azaz.Phone" xmlns:d="http://schemas. vagy elrejtjük.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.Controls. erőforrásokra) hivatkoznak. amelyik a kapcsolódó mögöttes kódban megtalálható. amelyhez az x prefix került hozzárendelésre.SecondPage" xmlns="http://schemas. Az mc:Ignorable paraméter azt határozza meg. hogy az alkalmazás milyen orientációkat támogat (SupportedOrientations) és mi az alapértelmezett orientáció (Orientation).IsVisible="True"> <Grid x:Name="LayoutRoot" Background="Transparent"> </Grid> </phone:PhoneApplicationPage> A PhoneApplicationPage objektum egy Windows Phone képernyőt reprezentál.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. továbbá a panel neve „LayoutRoot” lett.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft. Az x prefix a XAML nyelv saját névterét reprezentálja. Végül a PhoneApplicationPage elem kerül definiálásra. Ezek rendszerszintű beállításokra (ún. azaz ha prefix nélkül írunk le xaml-ben egy elemet. Ez lesz az alapértelmezett névtér. illetve az előtér színe. akkor azt a XAML névtérben találhatjuk meg. azaz melyik az az osztály. ebből egy kiemelkedik. amelyen transzparens hátteret határoztunk meg. hogy a „d” prefixet nem kell figyelembe venni futásidőben. csupán az xmlns definíció.

hogy el ne készítse rá a dedikált Hello World alkalmazását. hogy számos különböző projektsablon áll rendelkezésünkre.1. 1-2 ábra: Új projekt létrehozása 2. Készítsük hát el első Windows Phone alkalmazásunkat! 1. 1-3 ábra: A projekt felépítése 22 . 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. Hozzunk létre egy új Windows Phone alkalmazást! Kattintsunk a File menüre. hogy a Windows Phone OS 7. Ezekkel a későbbi fejezetek során részletesebben is megismerkedünk majd. illetve különböző felépítéssel rendelkező alkalmazások speciális változatai. 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. majd kattintsunk az OK gombra! 3. hogy melyik operációs rendszer változatra szeretnénk fejleszteni. 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. mint különböző alkalmazás típusok.1 van kiválasztva. Egyelőre gondoljunk ezekre úgy. Győződjünk meg róla. A következő lépésben a Visual Studio megkérdezi tőlünk. Vegyük szemügyre a Visual Studio által létrehozott elemeket! A Solutions Explorer ablak tartalma az 1-3 ábrán látható.

0.0.png Background. Ezeknek a gyerekelemeknek a felvételével határozhatjuk meg.png MainPage.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.cs) ApplicationIcon.microsoft.xaml"/> </Tasks> <Tokens> <PrimaryToken TokenID="HelloWindowsPhoneToken" TaskName="_default"> <TemplateType5> <BackgroundImageURI IsRelative="true" IsResource="false">Background.xaml (App.xml fájl megér külön egy kis magyarázatot: <Deployment xmlns="http://schemas.com/windowsphone/2009/deployment" AppPlatformVersio n="7. stb. az ikon. A legérdekesebb szekció azonban a Capabilities elem és gyerekei. az alkalmazás felirata.png Induláskor megjelenő. töltési idő alatt látható kép A Properties alatt található WMAppManifest.xaml (MainPage.xaml. hogy az alkalmazás alapbeállításai itt kerülnek meghatározásra: a háttérkép.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.1"> <App xmlns="" ProductID= "{9bb8c371-293f-4726-a4ba-5b2e2efb152d}" Title="HelloWindowsPhone" RuntimeType="Silverlight" Version="1.0" Genre="apps.xaml. hogy az alkalmazásunk a telefon 23 .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.png</BackgroundImageURI> <Count>0</Count> <Title>HelloWindowsPhone</Title> </TemplateType5> </PrimaryToken> </Tokens> </App> </Deployment> A fenti XML kódrészletben jól látható.

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

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

A következő fejezetekben ezt a tudást mélyítjük el. valamint megírtuk életünk első Windows Phone alkalmazását.1. Betekintést nyerhettünk a platform legfontosabb építőelemeibe. amelynek során részletesen megvizsgáltuk. beállításai. melyek a legfontosabb elemei. Bemutatásra került a fejlesztőeszköz. hogy végül professzionális alkalmazásokat tervezhessünk és fejleszthessünk. 26 . 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. a Silverlight és a XAML nyelv alapjaiba. hogyan is épül fel egy Windows Phone projekt.

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

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

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

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

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

nekiállhatunk megtervezni. sok mindent gondosan meg kell terveznünk. Szintén sok ötletet meríthetünk egyéb sikeres alkalmazásokból. előbb-utóbb nem vesszük észre benne a finomságokat. 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. kérjük ki mások véleményét. mi a legértékesebb információ! Miután ez a tudás már a birtokunkban van. Felhasználói élmény tervezése Windows Phone-on odafigyeléssel mi magunk is kellemes élményt alakíthatunk ki. hogy hajtson végre valamit az alkalmazásunkkal. amelynek ki kell emelkednie. a tartalom az. Ezért a legfontosabb a kezdő ergonómus számára. az információból! Döntsük el. Rendkívül sokat segíthetnek az ún. hogy a felhasználó fejével gondolkodjunk. Ha elég sokat foglalkozunk a saját termékünkkel. A fogyasztói termékek piacán azonban elengedhetetlen a szép. A legfontosabb dolog. ezért létfontosságú. a használhatóság biztosítása. melyeket láttatni kell a felhasználóval. ha maradandó élményt nyújtunk! Sok mindenre sajnálhatjuk az erőforrásainkat. A weben tömegével megtalálható infografikai példák komoly segítséget nyújthatnak. 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. A középszerűségből csak úgy emelkedhetünk ki. é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. Teszteljünk minél többet. Használjuk bátran a vizuális eszközöket. hogy tesztelje le. Az alkalmazás középpontjában a tartalom van. annak kell ragyognia. hogy miként reprezentálhatjuk ezt látványosan.2. hogy a Metro dizájn elveit betartjuk. amit csinál. infografikákat! Végig tartsuk szem előtt. amelyben a vizuális hierarchiától kezdve a navigáción át. folyosó tesztek: kapjunk el valakit a folyosón és kérjük meg. hogy a tartalom megfelelően tálalva. a kiemelkedő vizuális élmény. nem elegendő. a vizuális dizájnra nem. és egy fekete-fehér alkalmazást készítünk. grafikonokat. é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. figyeljük a felhasználóink „ügyetlenkedését”. esztétikus alkalmazás. rosszabb esetben a nagyobb bajokat sem. hanem az értékből. 32 . Ne essünk tévedésbe! Az a gyakorlat. Ez igen tág témakör. hogy gondosan elemezzük. hogy mit és hogyan mutatunk meg a felhasználónak! Ne a vizualitásból induljunk ki. melyek a legfontosabb elemek. egészen az apró részletekig.

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

Tervezés Sketchflow-val A Microsoft Expression Blend for Windows Phone termék rendkívül hatékony eszköz. Sketchflow projektek létrehozására is.2. dinamikus prototípusok készítésére alkalmasak. Ezek a projektek kizárólag sketchek. mint például az Expression Blend Sketchflow. Az Expression Blend egyéb változataiban lehetőségünk van ún. (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 . 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. Ez a fejlesztőeszköz Windows Phone fejlesztéshez ingyenesen elérhető. A felhasználói felület végleges kialakításában. vázlatok. a hatékony és gyors munkában elengedhetetlen szerepe van. Sketchflow-s Projekt sablon a Blend-hez (http://wp7sketchflow. Windows Phone fejlesztéshez elérhető a Codeplex-en.codeplex.com/). használhatunk erre specializálódott eszközöket is. melynek segítségével Windows Phone alkalmazások prototípusát készíthetjük el.

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

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. A mozgás és az animáció minősége és jellege határozza meg elsősorban. 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. Windows Phone esetén a mozgás és az animáció a legfontosabb visszajelzése annak. netán akadozó animációk nagyban rontják a felhasználói élményt. amelyek vele foglalkoznak. mintha szinte csak neki íródtak volna. illetve weboldala: releváns. jó érzés használni. hogy a felhasználói interakciónak virtuális értelemben vett fizikai hatása van. hogy a felhasználó mennyire érzi folyamatosan válaszra késznek az alkalmazást. amelyek róla szólnak. a nem. A korosztály. naprakész tartalom és ajánlatok. sima és könnyed animációk ezt az érzetet keltik. Friss és értékes tartalom. személyre szabott.és hírközpontú alkalmazások. személyes. míg a lassú. navigáció). Azok az alkalmazások. amelyek úgy tesznek. újdonság szolgáltatása nélkül szinte lehetetlen a felhasználóinkat visszavonzani. sokkal sikeresebbek. Felhasználói élmény tervezése Windows Phone-on megszemélyesítjük a jellemző felhasználóinkat.2. Ezek a tényezők együttesen fektetik le azokat a jellemzőket és alapvetéseket. a felhasználó számára értékes funkcionalitással bír. jól használható. annál nagyobb sikerre számíthatunk! 2-14 ábra: Személyes alkalmazás (Facebook) Hasznos. nehézkes. mint objektumok folyamatos átpozicionálásáról. Jól integrálódik az operációs rendszer megszokott jellemzőivel (pl. és kívánatos. Minél inkább a felhasználó képére tudjuk formálni az alkalmazást. A gyors. 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. a közös jellemzők meghatározása jelentősen leegyszerűsítik a tervezés folyamatát. kívánatos A tökéletes alkalmazás hasznos. az ő igényeiről. könnyen használható és egyszerűen tanulható. 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. Nagyon jó példa erre az Amazon alkalmazása.

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

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. Fontos. JPEG vagy PNG formátumban. hogy a Marketplace-ből kisebb eséllyel kerül letöltésre. gyengén megtervezett és megrajzolt lapkával rendelkező alkalmazás azt is kockáztatja. vágáshoz vezethet. Ezenfelül az alkalmazás listába érdemes külön 63x63 pixeles képet biztosítani. ellenkező esetben az alapértelmezett lapka kerül átméretezésre. ami torzításhoz. melyek a megfelelő Windows Phone témák esetén „transzparens” háttérként funkcionálnak (2-16 ábra) Transzparens háttereket.2. felfelé vagy lefelé. 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ű. 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 . árnyékok alkalmazását Lekerekített lapkákat Fekete vagy fehér háttereket. Az ennél nagyobb vagy kisebb képek átméretezésre kerülnek.

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

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.2. 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. illetve horizontális mozgatással lehetséges. Háttérképként jellemzően JPEG ajánlott 480x800-as. dinamikus parallaxszerű effektust eredményezve. Az animáció során a tartalom és a feliratok különböző sebességgel. időben eltolódva hajtódnak végre. 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. Map vezérlők). és biztosítja a navigációt közöttük. illetve 1024x800-as felbontásban. A navigáció a menüelemek fejlécét érintve. a görgetés során pedig egészen egyedi animációval és tulajdonságokkal rendelkezik. Ez biztosítja a jó teljesítményt és a gyors betöltést. Toggle. ezáltal rendkívül látványos. valamint az átméretezés elkerülését. A Panorama vezérlővel ellentétben nem egyetlen nagy téren helyezkednek el az egyes szekciók. A vezérlő önálló. elkülönített nézeteket helyez el egymás mellett. 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. 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. 40 . 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.

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

minimum 4.2mm2-esnek kell lennie. holt terület helyes meghatározása. Ennél kisebb területet a felhasználók nem fognak interaktívnak tekinteni. amelyet szándékozott. Holt területnek nevezzük azt a szabad területet. a használhatóság vonatkozásában! Összefoglalás Ebben a fejezetben megismerkedtünk a Metro Design legfontosabb elveivel. valamint a dizájnvezérelt tervezés módszerével. amely érintésre reagál. interaktív területet is célszerű nagyobbnak választani a vizuális elem területénél. azaz „félrenyom”. Ezenfelül az érinthető. Bár a holt területet célszerű arányaiban megállapítani. 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. amelyen már a vizuális visszajelzés (lenyomás animáció) is érzékelhető 10-15mm2 között mozog. A fenti szempontok figyelembevételével ennek a kockázata jelentős mértékben csökkenthető. itt a minimum korlát a 7mm-es magasság. Ezeket az elveket betartva olyan stabil termékek születhetnek. Ez az érték csupán a kis vizuális elemekre értendő. melyek mind számunkra. és semmilyen interakcióval nem rendelkezik. 42 . A helyes interkaciós modellek megválasztása és támogatása kulcsfontosságú szereppel bír a felhasználói élmény. 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. a 2mm-es minimum jó alsó határértéknek tekinthető. A gyakorlati tippek fontos útmutatóként szolgálnak az ergonómiai követelmények kielégítésében. mind a felhasználóink számára élvezetes. tipikusan listák esetében. A helyzeten tovább javít az ún. örömteli perceket szerezhetnek. amely két célobjektum között helyezkedik el.2. 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. Az ideális méret.

ahogy látni is fogjuk. Azonban a felületek kialakítása egyes esetekben eléggé fájdalmas tud lenni a VS használatával. akár több már meglévő elem együttes 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. hogy segítsék a dizájnerek és a fejlesztők együttműködését. viselkedést adjunk nekik –. amelyek segítségével a legegyszerűbbtől a legbonyolultabb üzleti alkalmazásokig bármilyen felhasználói felületet átlátható.3. A vezérlők kinézetét egy nagyszerű vezérlősablonrendszerrel. é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 –. összetett felhasználói felületek (a továbbiakban UI – User Interface) kialakításának támogatása. izgalmassá. A Visual Studio 2010 elsősorban a fejlesztőknek készült. 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. Az Expression termékek elsősorban a dizájnereknek készültek – ahogy a Silverlight elődjét. illetve saját vezérlőket hozzunk létre. 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. Alkalmazásfejlesztés Windows Phone-on Az eredetileg RIA fejlesztésre kialakított Silverlight keretrendszer talán legfontosabb alapgondolata a gazdag tartalmú. Ezek azok az alapvető építőelemek. akár a teljes felület bizonyos helyzetekben felvett megjelenítését írhatjuk le központi. amelyek testre szabhatóvá. 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. és lehetőséget adnak arra. 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. 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. adatfüggő felületeket. kézre álló módon felépíthetünk. Többek között a VS ezen gyenge pontját ellensúlyozandó hozta létre a Microsoft az Expression termékcsaládot. 43 . Mivel már rengeteg könyv megjelent Silverlight 4 témában. 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. ez a fejezet csak egy gyors. hogy kiterjesszük azokat – új tulajdonságokat. A fejezet során végig az Expression Blend 4 segítségével hozzuk létre és szabjuk testre a felületeket. illetve stílusok segítségével változtathatjuk meg. 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. és az ezekben leírtak komolyabb változtatások nélkül alkalmazhatók Windows Phone 7-fejlesztésben is. Előbbiben értelemszerűen a vezérlőket találjuk. egységes módon. Ennek a fejezetnek az első részében ezekkel az építőelemekkel ismerkedünk meg. de korábban megszerzett tudása azonnal és közel száz százalékosan átvihető WP7-re. 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. ezenfelül pedig könnyedén animálhatjuk azokat. az is találhat néhány új dolgot (például az InputScopeok). könnyen használhatóvá teszik a vezérlőket. illetve a keretrendszer UIhoz kapcsolódó szolgáltatásaiban. Ebben a fejezetben ezeket a témaköröket nézzük meg közelebbről. sok minden megegyezik az „asztali” Silverlighttal. amelyek a felületek építéséhez elengedhetetlenek. Az adatkötésirendszerrel és az adatsablonok használatával pedig rengeteg kódot megspórolva építhetünk dinamikus. Ahogy a Silverlight „asztali” verziójában is. áttekintő összefoglalást kíván adni. amelyekkel akár az egyes vezérlők. a Windows Presentation Foundationt is azzal a céllal hozták létre. Különböző vizuális állapotokat hozhatunk létre.

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

Asset Library-t. 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. Ha kiválasztunk valamit az Asset Library-ban. annak ikonja a duplanyíl alatt jelenik meg. néhány ikon jobb alsó sarkában egy kis nyilat vehetünk észre – ez azt jelenti. ahonnan egyéb.7720. amelyeknél van ilyen nyíl. illetve egyéb gyakran használt vezérlők (gomb ikon).68. mint a Visual Studio. Azoknál az ikonoknál.10. 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 45 . 7. Az OK gombra kattintva a Blend létrehozza a projektet. a harmadik csoportban találjuk a primitív vezérlőket szimbolizáló egyszerű négyszöget. a kéz ikonnal tudjuk egyszerűen görgetni a tervezőfelületet. négy részre osztott négyzet ikon). Lejjebb. szerkeszteni). hanem a C:\Users\<felhasználónév>\<dokumentumok>\Expression\Blend 4\Projects mappában! A választott 7. Lejjebb.1-es OS verzió ne tévesszen meg senkit! A Mangóként ismert. a szövegvezérlők (keretes T betű). Alatta találhatók az elrendezés-vezérlők (Grid.Alapvető WP7 vezérlők Tartsuk észben. Erre kattintva érjük el az ún.5-ösként reklámozott OS belső verziószáma 7. a toolboxon nem szereplő vezérlőket és egyéb felhasználható típusokat érhetünk el. A nagyító ikon segítségével nagyíthatunk a felület egy részére. A toolbox legalsó eleme jelen pillanatban egy dupla. Ismerkedjünk meg a felülettel. jobbra mutató nyíl. hogy nem egy eszközről van szó. hanem egy csoportról. hogy a Blend alapbeállításként nem ugyanabban a könyvtárban hozza létre a projekteket. Ha közelebbről megnézzük.

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

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

Az egyik. ezzel érhetjük el a ritkábban használt tulajdonságokat. hat egyforma cellára bontják a felületet. látható. ha hozzáadunk a RowDefinitions és a ColumnDefinitions tulajdonságokhoz két oszlopot és három sort. ahogyan azt a 3-6 ábra mutatja. Ez nemcsak dizájnelem.) 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.3. amelyeket elsőre könnyű nem észrevenni. 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. ha fehér. hogy a tervezőfelületen is megjelennek a cellák határoló vonalai. 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. és így tovább. valamilyen adatkötésből kapja az értékét. 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. (Az adatkötésről és az erőforrásokról a későbbiekben lesz szó. ha sárga. akkor a tulajdonság az alapértelmezett értékén áll. Itt két dologról is érdemes szót ejteni. Visszatérve a ContentPanelre. akkor kézzel állították be valamilyen értékre. hogy a csoportok alján található egy lefelé mutató nyíl. A másik. hogy sok tulajdonságtól jobbra egy kis négyzet található. amelyek nélkül nincs élet a Silverlightban! 48 .

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

hogy gombunk még nem rendelkezik névvel. 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 –. Marginok nélkül Azt is észrevehetjük. é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). széltében kitölti a cellát (3-11 ábra). Alapértelmezés szerint nem kell.3. akkor érdemes nevet adni nekik. Itt kapcsolhatjuk azt a kódot a felülethez. a gomb szélesebb lesz. a Button Click eseményéhez kell hozzárendelnünk egy eseménykezelő metódust. a Blend átvált az aktuális oldal mögöttes kódjára.) Ahhoz. amikor a felhasználó megnyomja a gombot. amellyel megvalósíthatjuk az elvárt működést. 3-10 ábra: A Margin alaphelyzetbe állítása az Advanced options Reset parancsának segítségével 3-11 ábra: Gomb. viszont ha hivatkozni szeretnénk rájuk a mögöttes kódban. (Esetünkben ez btnOne lesz. 50 . hogy valamilyen kód lefusson. 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). hogy nevet kapjanak a vezérlők. A Properties panel tetején válthatunk át eseménynézetbe.

Az ismertebb MVVM-keretrendszerek leírása a http://en. rész alatti linkeket érdemes megnézni. illetve több keretrendszer is létezik implementálására.aspx. a gombot nyomogatva növekszik az érték (3-13 ábra). és átadom a gombnak mint tartalmat. növel egy számlálót. Ebben az MVVM (Model-View-ViewModel) alkalmazásfejlesztési minta lehet segítségünkre. hogy amikor megnyomják.wikipedia.) Itt annyit fog tenni a gomb. aztán annak aktuális értékét megjeleníti a gombon. Ennek leírása túlmutat e könyv határain.microsoft. 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. vagy kiválaszthatjuk a Project menüből a Run Project menüpontot.silverlight.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.Content = taps. 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. public MainPage() { InitializeComponent().com/en-us/magazine/dd419663. btnOne. Ahogy az alkalmazás elindult.RoutedEventArgs e) { taps++. (Az Open source MVVM frameworks c.Windows.net/learn/advanced-techniques/the-mvvm-pattern/using-the-mvvm-pattern-insilverlight-applications. } } } Az alkalmazás futtatásához vagy megnyomjuk az F5 billentyűt. A Devices panel beállításai szerint a Blend vagy a WP7 emulátort indítja el. } private void btnOne_Click(object sender.org/wiki/Model_View_ViewModel linken található. Josh Smith WPF-guru cikke az MVVM-ről WPF alatt itt található: http://msdn. 3-13 ábra: A program az emulátoron futtatva 51 . System.Int32 típusú változót az oldal mögöttes kódjában. 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. Ehhez először létrehozok egy System.

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

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

Checked. növeli az értéket. } private void cbGenderIsMale_Indeterminate(object sender. mind a RadioButton IsChecked tulajdonsága Nullable<Boolean> típusú. IsThreeState. Indeterminate).Content = taps. Ilyen esetekben használhatjuk a RadioButtont (rádiógomb). 3-18 ábra: A RadioButton tulajdonságainak beállítása Ha több csoportba szeretnénk rendezni a rádiógombokat. Ezért kell előbb Booleanné alakítani.3. btnOne. 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. 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. de a különböző csoportokban lévők között már ne legyen kapcsolat. hogy ha az rbIncrement választógombot jelöli be a felhasználó. ha a felhasználó több lehetőségből egyet választhatna. } Mind a CheckBox. System. Unchecked. RoutedEventArgs e) { MessageBox. hogy azt szeretnénk. RoutedEventArgs e) { MessageBox.Show("Sheila Broflovski"). Alkalmazásfejlesztés Windows Phone-on private void cbGenderIsMale_Unchecked(object sender. 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. IsChecked. 54 .Windows. GroupName tulajdonságuk segítségével csoportosíthatjuk őket. úgy. Előfordul azonban.vagy bekapcsolását adhatjuk a felhasználó kezébe.RoutedEventArgs e) { if ((bool)rbIncrement. private void btnOne_Click(object sender.Show("Liane Cartman"). azaz a true és false értékén kívül null értéket is felvehet.IsChecked) taps++. else taps--. csökkenti azt (3-19 ábra). ha pedig nem. hogy minden csoportban kölcsönösen kizárják egymást a lehetőségek.

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. 55 . amelynek nem kell szöveget megjelenítenie. aláhúzott) betűformázási lehetőségeket is megkapjuk (3-21 ábra). A Silverlightban erre elsősorban két vezérlőt használunk: egyszerű szövegmegjelenítésre a TextBlockot. 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. Egyszerű szövegmegjelenítés a TextBlockkal Ahogy korábban láttuk. dőlt.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. bonyolultabban formázott megjelenítésre pedig a RichTextBoxot. 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). a betűk méretét. illetve a szokásos (félkövér.

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

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

és a felhasználó különböző parancsokat futtathat. 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 link már jól fog működni – ha megérintik. 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. és TargetName tulajdonságának a „_blank” értéket kell adni. vagy éppen választhat lehetőségek közül. megnyílik az Internet Explorerben a megadott weblap.3. hanem ő maga adhasson meg valamilyen bemenetet. Ha ezek után fut az alkalmazás. hogy megkönnyíthessék a felhasználói adatbevitelt. amit a program fel tud dolgozni. 58 . De gyorsan szembe kerülünk azzal az igénnyel. A Silverlight számos speciálisabb vezérlőt kínál a fejlesztőknek. hogy ne csak a felkínált lehetőségek közül választhasson. de legáltalánosabb adatbeviteli vezérlő mindig is a TextBox marad.

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 MaxLength csak a felhasználói adatbevitelt szabályozza.Alapvető WP7 vezérlők Szövegbevitel a TextBoxszal A TextBox. 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. illetve kódból itt állíthatjuk be a szövegdoboz szövegét. ahogy a két előző vezérlőnket is a szövegvezérlők csoportjában találjuk a Toolboxon (3-30 ábra). 3-31 ábra A TextBox tulajdonságainak beállítása a Properties panelen 59 . 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. hogy legfeljebb hány karaktert írhasson be a felhasználó a szövegdobozba. A TextBoxot.

Text. } 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. az oldal címe automatikusan frissül. TextChangedEventArgs e) { PageTitle. Alkalmazásfejlesztés Windows Phone-on Amikor a TextBox szövege megváltozik. mint egy teljes értékű és méretű fizikai billentyűzeten tenni ugyanezt. Ha például tudjuk. illetve. 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. 60 . 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. private void tbTitle_TextChanged(object sender. Ezt az InputScope tulajdonsággal tehetjük meg (3-33 ábra).3. elkaphatjuk a TextChanged eseményt.Text = tbTitle. hogy esetleg megakadályozzuk a felhasználót érvénytelen adatok bevitelében. a Silverlight for Windows Phone 7 lehetővé teszi. Ahogy gépel. hogy a felhasználó egy szövegdobozba csak számokat fog gépelni. hogy néhány kattintással pontosan beállíthassuk a TextBox vezérlők virtuális billentyűzetét.

tbTitle. ins. 61 .Number.InputScope = ins. insName. 3-34 ábra: Number InputScope-úra beállított TextBox Ugyanezt természetesen kódból is beállíthatjuk.Add(insName).Names. InputScopeName insName = new InputScopeName(). így akár futás közben is változtatható egy TextBoxhoz rendelt billentyűzet: InputScope ins = new InputScope().NameValue= InputScopeNameValue.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. a felhasználó csak számokat tud majd beírni ebbe a szövegdobozba (3-34 ábra).

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

hogy hányadik elem legyen alapértelmezetten kijelölve.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ó. (3-38 ábra) 63 . a -1 azt jelenti. hogy több elem is kijelölhető legyen-e.) 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. nincs kijelölt elem. végletekig egyszerűsített tennivaló-listát valósítjuk meg. hogy a TextBoxba írt szövegeket a gomb megnyomásával a ListBoxhoz rendeli. A számozás 0-tól indul. Az Items listán keresztül adhatunk elemeket a ListBoxhoz. (Az elemek törlése már feláras funkció. Mindössze annyit tud. a SelectionMode-dal pedig megadhatjuk. A SelectedIndex segítségével állíthatjuk be.

illetve az „X” gombbal törölhetünk egy elemet (3-39 ábra). Az „Add another item” gombra kattintva kiválaszthatjuk a ListBoxhoz hozzáadni kívánt elem típusát. Az egyes elemek sorrendjét az ablak alján lévő nyilakkal változtathatjuk meg. amit átírhatunk. 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 . az Object Collection Editor ablak jelenik meg.3. melyben szerkeszthetjük a ListBox tartalmát. Egy stringet hozzáadva (az mscorlib|Systemben találjuk) a szerkesztőablak jobb oldalán megjelenik a karakterlánc. 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.

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

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

ha átváltunk a Resources panelra. például egy CLR-objektumhoz.Adatkötés Az is észrevehető. 67 . hogy a Blend nagyon szépen jelzi. ott is megtalálható az erőforrások között az újonnan létrehozott string. hanem valami máshoz. A kész erőforrás innen azonnal. 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. 3-44 ábra: Az adatforrások a Resources panelon Ugyanezt elérhetjük. 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. hogy a tulajdonság egy erőforrásból kap értéket Továbbá. 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). ha nem egy előre elkészíthető erőforráshoz akarunk kötni. 3-43 ábra: A zöld keret és pötty jelzi. létrehozva ezzel az erőforráshoz kötést (3-44 ábra). Mi a helyzet akkor. hanem egy erőforráshoz kötöttük hozzá (3-43 ábra). illetve a Silverlightban. hogy egy tulajdonság nem lokálisan kap értéket. drag-and-drop módszerrel áthúzható egy felületi elemre.

vagy hiányzik a program szerelvénye a listából. A megjelenő ablakban válasszuk ki a Character osztályt. 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.) 68 .3.} public string City {get.} public Character() { Name = "Hubert Farnsworth". és megjelenik. é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. 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. Ezzel véletlenszerű mintaadatokkal feltöltött adatforrásokat hozhatunk létre. illetve adjuk meg az adatforrás nevét! (Ha még nem jelenne meg az osztály. set. Hasznos a fejlesztésnek abban a fázisában. ahol a tényleges adatok még nem állnak rendelkezésre. City = "New New York". a „Create sample data” nevűt. } } Hozzunk létre egy példányt ebből az oldalon. fordítani vagy futtatni kell. set.

de ha sok tulajdonságot szeretnénk egyazon objektumról megjeleníteni. és létrejön az adatkötés (3-50 ábra). szép. Vezérlőink DataContext tulajdonsága szolgál 69 . Drag-and-drop módszerrel az egész adatforrást vagy egyes részeit ráhúzhatjuk egy felületi elemre.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). nem lehetne egy kicsit központosítani az adatkötést? Természetesen lehet. 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.

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

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

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

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

akár teljesen ki is cserélhetjük megjelenésüket. custom expression. a vezérlőt leíró osztály csupán a működést definiálja. amire rá lehet kattintani” — esetünkben tapintani. a kinézetet nem. Appearance és Layout csoportokba a Properties panelen.) 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. 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. A Silverlight (illetve eredetileg a WPF) vezérlői „kinézetmentes” (lookless) vezérlők. (Advanced options. 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ó. hogy két TextBlock van a sablonban. „valami. A korábban megismert adatkötési eljárással ez is könnyedén megoldható. A vezérlők kinézetének testreszabása vezérlősablonokkal Adatok megjelenését már testre tudjuk szabni. Data Context. Data Binding…. Azonban ha ez nem elég. Egy gomb mindössze.3. Tartozik hozzá egy alapértelmezett kinézet – 74 . tehát a fent elkészítettet átadhatjuk egy másik oldal másik ListBox objektumának is.

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

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

érdemes saját vezérlőt készíteni.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. hogy a sablon már a gombtól veszi a feliratát (3-67). é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. csupán a képeik térnek el. ez pedig elengedhetetlen. 77 . amelynek egy plusz ImageSource tulajdonságot adunk. Érdemes a képeket Visual Studióban hozzáadni a projekthez. illetve a tervezőfelületen látszik. 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. a képet természetesen egy másikra állítva a Hozzáadás gomb is megszépíthető (3-68 ábra). 3-67 ábra: A vezérlősablon átveszi a vezérlőtől az értéket Ugyanezeket a lépéseket eljátszva.

hogy olyan kódot írjunk. ami a felület megjelenését közvetlenül befolyásolja. Az egy csoportban lévő állapotok kölcsönösen kizárják egymást. Ezzel központosíthatjuk a felületleírást. Vegyük példának az alábbi egyszerű alkalmazást! Két gombból áll. próbáljuk meg elkerülni.3. 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. de ha egy mód van rá. 3-69 ábra: A VisualState-eket bemutató program kinézete és szerkezete Ezt az egyszerű logikát leírhatjuk kódban is. amelyek két képhez kapcsolódnak olyan módon. 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). 78 . hogy ha a felhasználó megnyomja az egyik gombot. Ehelyett a States panelen hozzunk létre két állapotot! VisualState-jeink csoportokba rendezhetők. és az egyes állapotok közötti váltás is jelentősen leegyszerűsödik a korábbi módszerekhez képest. tehát az alkalmazás egy VisualStateGroupnak egyszerre csak egy VisualState-jében lehet. ezért először egy csoportot kell létrehozni (3-70 ábra). a másik kép. ha a másikat. a másik pedig engedélyezetté (3-69 ábra). Emellett pedig a megnyomott gomb letiltottá válik. melyekben leírhatjuk a felület elvárt állapotát bizonyos helyzetekben. az egyik kép tűnik elő.

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

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

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. dragand-drop módszerrel érhető el. Szépen. Vagy például szeretnénk azt elérni. hanem látványos. Vagyis az animációkat elég XAML-ben megfogalmazni: „milyen tulajdonságot. mindenféle kód nélkül össze tudjuk állítani a felületet a különböző állapotokban. a Microsoft a WPF-fel előtérbe helyezte azt a megoldást. 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. Ennek előnye. kinézetét a kiinduló. engedélyezett gomb legyen felül! Ez a tervezőfelületen. amikor a változtatásokat végzi az ember. hogy mindig az a gomb legyen felül.és a végállapot között. hogy az ehhez hasonló látványelemeket ne imperatív kóddal valósítsa meg a fejlesztő. ha például a kép nem egy pillanat alatt váltana át. Szebb lenne. A XAML előnye pedig. de érezhetően kicsit fapados a kinézet működése. gyorsan.) 81 . (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. 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. menyi idő alatt. és a háttérben az erre optimalizált keretrendszer elvégzi helyettünk a bonyolult kód megírását. hanem csak írja le (deklarálja). 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. Ezután csak annyit kell tenni. de nem árt arra ügyelni. Mivel ennek az implementálása értékes időt vett el a fejlesztőtől. hogy mit is szeretne elérni. animált. hogy a megfelelő állapot legyen kijelölve. abban pedig kiszámolni a vezérlő aktuális elhelyezkedését. amit a felhasználó megnyomhat – és a gombok helycseréje se pillanatszerű legyen. „átúszna” a másik képbe. hanem egy másodperc alatt elhalványulna. amikor ennyi nem elég. hogy gyorsan leírható. és utána (gyakran pixelről pixelre) kirajzolni a vezérlőt. milyen végértékre szeretnék hozni”. hogy minden állapotban a másik állapotba váltó. Maga az animáció egy tulajdonság értékének adott idő alatti megváltoztatását jelenti.

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

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

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

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

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

amelyeken az előző nézet útvonalai természetesen ugyanúgy ki vannak emelve. ugyanis a térkép Mode tulajdonsága egy olyan objektumpéldányt vár. csak az utakra összpontosító nézetet kapunk. és nevezzük is el a térképet! <maps:Map Name="myMap CredentialsProvider="Ajdyq5FaN2RZvzvogm_. Ezt a ZoomLevel megadásával változtathatjuk meg: <maps:Map Name="myMap" CredentialsProvider="Ajdyq5FaN2RZvzvogm_. " Center="47. hanem az ezek alapján készített.129404" ZoomLevel="17" /> Az egyszerűbb felhasználás kedvéért és a tesztelés miatt is érdemes megjeleníteni a ZoomBar gombjait... 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. ami a MapMode osztályból származik – ez a megjelenítéshez szükséges 87 .-122. A vezérlő viszont még ezt követően is a teljes világtérképet fogja megjeleníteni. 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ú.. A módok közötti váltáshoz egy kicsit többet kell dolgoznunk. hiszen nem állítottuk még be a nagyítás fokát."/> Ennek hatására a figyelmeztetés eltűnik. függetlenül a Center pozíciótól.Térképek kezelése 4-4 ábra: A térkép..639655. Ez az alapértelmezett mód. és XAML kódból a pozíciót leíró koordinátákat is felhasználhatunk az értékadás során. 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... AerialMode: Teljes műholdképek. és rendesen használhatjuk a vezérlőt.

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

12862). -122.Device. Ezeket a pushpineket akár egyesével. csupán koordináták és kiírandó szöveg megadásával használható vezérlő.-122. Az így kapott jelöléseink végtelenül egyszerűek. Egy Pushpin felvétele XAML-ben az alábbi módon történhet: <maps:Pushpin Location="47.GeoCoordinate(47. de akár dinamikus listákat is köthetünk a vezérlőhöz. 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. címek. Ennek eszköze a szintén a Maps vezérlő névtérhez tartozó Pushpin osztály. viszont szükség esetén a Silverlightban megszokott könnyedséggel testre is szabhatjuk azt.63876.639655. XAML vagy C# kódból hozzáadogathatjuk a térképhez.Children. Ez egyszerűen.Location.Add(new Pushpin { Location = new System. csupán a tartalomnak beállított szöveget mutatják az adott pozíción. Content = "C#" }). megjelölt pozíciók nélkül.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. amint azt a 4-6 ábra is mutatja.

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

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

4. valamint a lenti vezérlőgombokkal ezeknek a rétegeknek a megjelenítését váltogathatjuk. Haladó alkalmazásfejlesztés Windows Phone-on 4-8 ábra: A pozíció-listák a térképen megjelenítve Ahhoz. } } A benzinkutak rétegéhez kapcsolódó PetrolStations_Click kódja teljesen hasonló ehhez.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.Visibility = System.Visibility.Visibility.png" Text="Bárok" Click="Pubs_Click"/> <shell:ApplicationBarIconButton IconUri="/Images/petrol.ApplicationBar> <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True"> <shell:ApplicationBarIconButton IconUri="/Images/beer. EventArgs e) { if (lPubs. } else { lPubs. 92 . Eddigi munkánk végeredménye tehát egy olyan térkép.png" Text="Benzin" Click="PetrolStations_Click"/> </shell:ApplicationBar> </phone:PhoneApplicationPage.Windows.Visible) { lPubs.Collapsed.Visibility = System.Windows. hogy kihasználjuk a rétegek előnyeit. amint azt a 4-9 ábra mutatja.Windows. helyezzünk el két gombot az ApplicationBar-on.Visibility.Visible.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.

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

4. Hozzuk is létre ezt a proxyt a MainPage konstruktorában! Ahhoz. és kiolvassa belőle az elérhető interfészeket és azokon belül a felkínált funkciókat. ehelyett egy Credential típusú objektumot is létre kell hoznunk: 94 . de mi itt csak kliens alkalmazást fejlesztünk. RouteServiceClient proxy = new RouteServiceClient(). Itt már nem használhatjuk a XAML-ben rendelkezésünkre álló egyszerűsített értékadást. Ezt érdemes egy külön változóban tárolni. 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. A dialógusban lévő Discover gomb lehetőséget biztosít. hogy a keretrendszer megtalálja ezt az osztályt. Ezt követően példányosítással létrehozhatunk egy proxy objektumot. amit a Bing Maps regisztrációjánál kaptunk. így a távoli metódusokat egyszerű függvényhívásokkal érhetjük el programunkból. a MainPage osztály elején. amelynek metódusai a szolgáltatást címzik meg. természetesen a RouteService névteret fel kell vennünk egy using taggal a file elején: public MainPage() { InitializeComponent(). this. 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. hogy a környezet a mi saját Solutionünkön belül keressen elérhető szolgáltatásokat. } Ezeknél a szolgáltatásoknál szintén szükségünk lesz arra az azonosítóra. így erre nem lesz szükségünk. é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. 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.DataContext = this.

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

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

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

Az első segítségével férhetünk hozzá a QueryString-hez. az oldal neve pedig legyen MainMenuPage! A többi sablon is ehhez hasonló szerkezetű. 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. amely alapértelmezés szerint abszolút. 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.xaml-t! Az oldalak közti váltás már működne. de ez a WP7 esetében mindig false értékű lesz. mint például a lap orientációja. azon belül pedig helyezzünk el egy gombot: <Grid x:Name="ContentPanel" Grid. Ezzel a paranccsal címezzük meg a fejezet első részében létrehozott MainPage. amelyen keresztül elérhetjük a többi lapot. mint weblapok esetében. azaz a GoForward(Uri) függvény kivételt dob.xaml".Relative)).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). ami csakúgy. nekünk viszont most egyszerűbb lesz. Ezek kipróbálására egészítsük ki az előző alkalmazást egy új oldallal. Haladó alkalmazásfejlesztés Windows Phone-on   Source – A jelenleg aktív vagy mindjárt aktívvá váló oldal címe. } A Navigate függvény egy URI-t vár. csupán néhány alapbeállításban térnek el egymástól. onnan pedig sehova nem tudunk navigálni! A megoldáshoz nyissuk ki a Properties mappát. azon belül pedig keressük ki a WMAppManifest. Ezen az új oldalon adjunk a ContentPanel nevű Gridhez egy StackPanelt.Navigate(new Uri("/MainPage. 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. az URL-ben átadható paraméterek kulcs-érték szótárát jelenti. a NavigationContext-ből és az előbb említett NavigationService-ből.12. valamint az ehhez kapcsolódó előrenavigálás.4. A PhoneApplicationPage navigációs eszköztára két fontosabb részből áll. ha ezt relatívra cseréljük.0. RoutedEventArgs e) { NavigationService. azonban egy probléma még van: a MainPage nyílik meg először. UriKind.Row="1" Margin="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.xml-t (4-14 ábra)! 98 . ami egy főmenüt fog tartalmazni. amivel ezt módosíthatjuk(RemoveBackEntry).

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

Ehhez a veremhez mi is hozzáférhetünk.ItemsSource = NavigationService.Windows. // saját kód string myParam. úgyhogy új objektumra kell állítanunk az ItemsSource-ot! */ icNavigationList. Hozzunk létre egy új oldalt Navigation névvel.NavigationEventArgs e) { base.Row="1" Margin="12. if (NavigationContext.ToList(). A DisplayMemberPath tulajdonság beállításával jelezzük. } Ha felveszünk valahova egy linket.4.QueryString.ItemsSource = NavigationService. 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.Navigation. Haladó alkalmazásfejlesztés Windows Phone-on protected override void OnNavigatedTo(System. amiről a hardveres Back gomb leveszi a legfelső elemet. } icNavigationList. azaz a BackStack nem ad magáról értesítést a megjelenítő vezérlőnek arról. a gomb eseménykezelője viszont egy kis magyarázatot érdemel.OnNavigatedTo(e). sőt a visszalépést is egyszerű függvényhívással megvalósíthatjuk.0. Mi viszont az egyszerűség kedvéért nem használtunk adatkötést. // 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. és töltsük ki a gomb eseménykezelőjét is! protected override void OnNavigatedTo(System.OnNavigatedTo(e).Windows.BackStack.NavigationEventArgs e) { base. hogy az beállítsa a XAML-ben definiált vezérlők hiányzó értékeit. /* nem használtunk adatkötést. RoutedEventArgs e) { NavigationService. A RemoveBackEntry függvény törli a navigációs verem felső elemét. } private void btnDelete_Click(object sender.BackStack.TryGetValue("myParam".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.Text = myParam.RemoveBackEntry(). és visszanavigál erre az oldalra. Az OnNavigatedTo működése magától értetődő.Navigation. Ilyenkor nem elegendő az ItemsSource-ot újra a BackStack- 100 . hogy a későbbiekben bekötött elemek Source tulajdonságát akarjuk kiírni! Vegyünk fel még egy gombot is.12. é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. out myParam)) { tbMyParam. hogy frissült. BackStack Az alkalmazásunkon belüli lapváltásokat egy verem tárolja. amivel a verem legutóbbi elemét el tudjuk távolítani. már megfigyelhetjük a NavigationService működését. ami erre az oldalra mutat.

hiszen ugyanezen verem alapján dolgozik az is.xaml-re navigál − akár paraméter átadásával −. Így ha törüljük a legfelső elemet. akkor az előtte lévőre fog a gomb visszavezetni.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. 4-15 ábra: Az elkészítendő navigációs vezérlő Az ehhez tartozó XAML kód: <UserControl x:Class="_04_Advanced_Development. ami a paraméter nélküli oldalváltást teszi lehetővé.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft. A Navigation vezérlő egy Hyperlink. úgyhogy a vezérlő sem frissül.NavigationBar" xmlns="http://schemas. és nevezzük el vezérlőnket NavigationBar-nak! Ezt a vezérlőt úgy alakítjuk ki. hogy a középső TextBox értékét átadja a megcímzett oldalnak. Ennek megvalósításához az Add New Item menüben válasszuk a Windows Phone User Control sablont. hogy bárhonnan a Navigation. például a BackStack-ből előálló listára kell állítanunk az icNavigationList-et.microsoft. amikor a BackStack nem üres. azzal a kiegészítéssel. hogy ezzel a törléssel a hardveres Back gomb működését is befolyásoljuk. azaz az alkalmazáson belül is tudunk még visszafelé navigálni. Komplexebb navigáció megvalósításához olyan felhasználói vezérlőt kell készítenünk. A dolog varázsa az.microsoft. 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. A Vissza gomb pedig csupán akkor aktív.com/expression/blend/2008" xmlns:mc="http://schemas. hiszen a referencia ekkor nem változik. Ez azért is érdekes téma. 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. valamint felkínál egy gombot. ami a hardveres vissza gombbal megegyező funkcionalitású. Ehelyett egy új példányra.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. A kész vezérlő megjelenítése a 4-15 ábrán látható.openxmlformats.com/winfx/2006/xaml" xmlns:d="http://schemas. Az Adatok gomb ugyanezt valósítja meg.Navigáció re állítani. mert a UserControl osztály nem tartalmaz NavigationService-t.

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

horizontálisan elnyúló vezérlő. és megnyomjuk a vissza gombokat! Ha minden jól működik. hogy bejárjuk az összes oldalt. majd a végén meglátogatjuk a navigációt összegző lapot. pontosabban a TemplatedItemsControlból származik (4-17 ábra). törlünk párat. hogyan tudjuk alkalmazásunkat oldalakkal strukturálni. nem véletlen. 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. hogy a beépített alkalmazások többsége is ezek felhasználásával készült el. 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. A WP7 programok kinézetének meghatározó formálói. 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 . amelyeket ebben a részben ismerhetünk meg. A Pivot és a Panorama két nagyon hasonló.Pivot és Panorama <local:NavigationBar VerticalAlignment="Bottom" /> Próbáljuk ki alkotásunkat úgy. Mindkettő az ItemsControlból.

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

Silverlight Toolkit for Windows Phone7 Az eddig bemutatott vezérlőkkel már egy gazdag eszközkészletből válogathatunk. Miután telepítettük a csomagot.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. 105 .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.jpg" /> </controls:Panorama. beágyazásuk pedig a Background tulajdonság hozzáadásával történik (4-19 ábra): <controls:Panorama.codeplex. de számos ismétlődő feladat még így is ránk hárul. az elérhető a Visual Studio Add Reference dialógusából (4-20 ábra).com. így ennek kipróbálására most nem térünk ki. Ilyeneket könnyen találunk az interneten. 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. Ezek elvégzését könnyíti meg a Silverlight Toolkit.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.

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. hogy az elemeket a XAML-ben is elérjük. 106 .Phone.1\Toolkit\Aug11 \Bin\Microsoft.Phone. nagyszerűen használható menük kialakítására.Toolkit.Toolkit" Fontosabb vezérlők HubTile – A főoldal lapkáihoz hasonló dinamikus vezérlő. 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. amelyek az egyszerű navigáción túl információt.assembly=Microsoft.4. hogy a felsorolt elemek közül többet is kiválasszunk (4-22 ábra). 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. üzeneteket is szolgáltatnak a felhasználó számára (4-21 ábra).Controls.Phone. 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.Controls. a már ismert módon adjuk hozzá a névteret a leíráshoz: xmlns:toolkit="clrnamespace:Microsoft.dll Ahhoz.

Expander> <Rectangle Height="80" Width="400" Fill="Blue" /> </toolkit:ExpanderView. amelynek egy elemét kiválasztva az lenyílik. elem" /> <toolkit:MultiselectItem Content="2. és a részletei is láthatóvá válnak (4-23 ábra).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. elem" /> </toolkit:MultiselectList> ExpanderView – Szintén a leveleknél (pontosabban a hosszabb levélváltásoknál) megszokott lista.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. elem" /> <toolkit:MultiselectItem Content="3.Expander> <toolkit:ExpanderView.Items> <TextBlock Text="Alelem 1" /> <TextBlock Text="Alelem 2" /> </toolkit:ExpanderView.

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

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

ContextMenu> </toolkit:HubTile> <toolkit:HubTile Name="hirekTile" Tap="hirekTile_Tap" Title="Hírek" Source="Images/news.place additional content here--> <toolkit:WrapPanel x:Name="ContentPanel" Grid.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. Haladó alkalmazásfejlesztés Windows Phone-on </StackPanel> <!--ContentPanel .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.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.Row="1" Margin="12.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.4.png" Margin="6" Background="#FF008000" GroupTag="TileGroup" Notification="Noti" Message="Microsoft Minősített Szerviz Partner project"> <toolkit:ContextMenuService.ContextMenu> <toolkit:ContextMenu> <toolkit:MenuItem Header="Menü 1" Click="MenuItem_Click" /> </toolkit:ContextMenu> </toolkit:ContextMenuService.0"> <toolkit:HubTile Tap="hirekTile_Tap" Title="Minden" Source="Images/all.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. 110 .12.

azokon belül pedig a Panorama és Pivot vezérlőket. az egyszerű címkereséssel és az útvonaltervezéssel. 111 . Végül a Silverlight Toolkit előnyeit ismerhettük meg. Ezekkel a módszerekkel nemcsak hogy rendkívül egyszerűen valósíthatunk meg komplex alkalmazásokat. ezek között a kiemelt pozíciók jelölésével. Ezt követően átnéztük a tartalmak rendszerezésére szolgáló műveleteket: az oldalak kezelését. 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.Ö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.

.

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

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

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

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

40.0" VerticalAlignment="Top" Width="438" TextWrapping="Wrap" /> </Grid> Hozzunk létre egy új mappát és másoljuk bele az MP3 fá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.xaml.Folyamatok a háttérben <StackPanel Orientation="Horizontal" Width="420" Margin="18.0. ábrán látható. ábra: A projekt struktúrája Következő tennivalónk a zenefájlok átmásolása az Isolated Storage-ba.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.cs fájlban helyezzük el az alábbi metódust. a Zune gyűjteményünkhöz nincs hozzáférése. Fontos megemlíteni. ehhez hasonló eredményt kell kapnunk. 127 . hogy az AudioPlayerAgent csak Isolated Storage-ban és távoli elérési úton elhelyezett audio fájlokat tud lejátszani. 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.18.193. 5-6. így Zune-on keresztül a telefonra másolt zenéket ne is próbáljuk meg elérni! Az App. amiket szeretnénk majd lejátszani! Jelöljük ki a zenefájlokat.

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

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

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

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

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

Mielőtt részletesen megnéznénk. } Az 5-8.Title ). ábra az alkalmazást mutatja be működés közben.Folyamatok a háttérben csomagolva. A Windows Phone Mango bevezette a Background File Transfer objektumokat.Find( item.Name ). nézzük meg azokat a korlátozásokat.Remove( reminder. if ( reminder != null && reminder. ne Zune média könyvtárból akarjuk elérni. ábra: a Cook Timer alkalmazás működés közben Adatok letöltése a háttérben Elképzelhető. stb) Fájl letöltése WIFI hálózaton (akkumulátorról) Maximális méret 5 MB 20 MB 100 MB 133 . 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. 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. Sajnos az FTP protokoll használata jelenleg nem támogatott.IsScheduled == false ) ScheduledActionService. hogyan is történik letöltés. akkor arra a következő kódrészlet mutat példát: void CleanupOldReminder( AlarmItem item ) { var reminder = ScheduledActionService. melyek HTTP és HTTPS protokollokon képesek adatokat forgalmazni. 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. HSDPA. 5-8.

amely egyesével végrehajtja az átadott letöltés-kéréseket.RelativeOrAbsolute ). //megadjuk. hogy csak a celluláris hálózaton. BackgroundTransferRequest request = new BackgroundTransferRequest( transferUri ). akkor a kivételkezelést figyelembe véve megkezdhetjük a letöltést a BackgroundTransferService objektum segítségével. 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. Ha a beállításokkal végeztünk. ez egy olyan sorként képzelhető el.EscapeUriString( transferFileName ).5. Azt is megadhatjuk. hanghívás megzavarhatja-e a letöltést (ha nem 3G hálózaton vagyunk.Substring(transferFileName. UriKind. request.0 fejlesztőknek című könyv PDF változatát tölti le a háttérben: // Silverlight 4. ahova ezeket a Windows Phone bemásolhatja. Miután fájlrendszerbe fognak letöltődni a fájlok. és a HTTP protokoll melyik igéjét szeretnénk hozzá használni. request. A következő kódrészlet a Silverlight 4. A másik a BackroundTransferService. és így tovább. 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. Uri downloadUri = new Uri( "shared/transfers/" + downloadFile.Add(request). esetleg Wifin keresztül kívánjuk ezt lehetővé tenni. A BackgroundTransferRequest objektumnak meg kell adnunk.gl/9dkcY". akkor ez előfordulhat). try { // a háttérben beütemezzük a letöltést BackgroundTransferService. amely leírja magát a kérést egyetlen távoli állományra mutatva. hanem mondjuk GPRS vagy EDGE módban működünk. Két objektumtípus segít bennünket ezeknek a feladatoknak a megvalósításában. hogy a letöltések szüneteltetésre kerülnek. Ilyen beállítás például az.0 fejlesztőknek könyv pdf-ben string transferFileName = "http://goo. hogy honnan kell a letöltést végeznie. Az egyik a BackgroundTransferRequest. hogy hova töltse le a fájlt string downloadFile = transferFileName. UriKind. hogy milyen beállítások mellett szeretnénk az adatforgalmazást engedélyezni.TransferPreferences = TransferPreferences. Uri transferUri = new Uri( Uri.DownloadLocation = downloadUri.Method = "GET". request. esetleg várjunk töltő csatlakoztatására.AllowCellularAndBattery. így egy olyan helyi elérési útra is szükségünk lesz.LastIndexOf( "/" ) + 1 ). } catch(Exception ex) { // ha valami probléma volt } 134 .RelativeOrAbsolute ).

és arról gondoskodnak. Az elméleti bevezetést követően gyakorlatban is láthattuk azokat a lépéseket. ahol a megfelelő objektumok végrehajtják az általunk megvalósított feladatok logikáját. 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. minden feladatnak speciálisan a hozzá illeszkedő feladat kategóriába kell kerülnie. hogy nem végezhetünk akármit szabadon a háttérben. 135 . amelyre eddig csak nagyon nehézkesen vagy esetleg egyáltalán nem találhattunk megoldást.Összefoglalás Összefoglalás A fejezetben láthattuk. Az új multitasking környezet számos új dolgot tesz lehetővé a fejlesztőknek. melyek az alkalmazást segítik beilleszkedni a Windows Phone életciklus modelljébe. hogy semmilyen esetben se veszhessenek el a felhasználó munkafolyamataihoz tartozó adatok. Láthattuk.

.

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

de a platform többi részével konzisztens megoldást is biztosít. Amennyiben viszont nincsenek egyedi igényeink a funkcióval kapcsolatban. Ez a felhasználó számára sokkal egységesebb rendszerképet és könnyebb kezelhetőséget garantál.6. amely feladatát egy-egy beépített vezérlő is képes ellátni. 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. amit legegyszerűbben a Windows Phone Pivot Application projektsablon kiválasztásával (6-2 ábra) helyezhetünk el alkalmazásunkban. Erre elegáns módszer a 4. A példaalkalmazás létrehozása A fejezet első részében a felsorolt taszkokkal fogunk részletesen megismerkedni. 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. fejezetben bemutatott Pivot vezérlő. 138 . érdemes ezek mentén külön lapokra bontani a megjelenítési felületet is. akkor nemcsak egyszerűbb a taszk használata.

hogy ezt a forrást a tervező eszközök meg is jelenítsék. A ViewModels mappa fogja össze azokat az osztályokat. megjelenítési felületek által elvárt formában tárolják az egyéb adatforrásból származó információt. és kihasználja a Silverlight által biztosított adatkötési mechanizmust. 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 .xaml állománya. logika.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. mivel példát mutat arra.1-es verziót. megjelenítés). amelyek az egyes oldalak. 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). Ahhoz. Ilyen adatforrás például a SampleData MainViewModelSampleData. 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. hogyan tudjuk az MVVM modellnek megfelelően szervezni kódunkat. 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.

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

egyet a launcherek és egyet a chooserek számára. 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. Alakítsuk át a projektet a taszkok teszteléséhez szükséges formába! A Pivot két lapot tartalmazzon.ViewModel. hogy a panel görgethetővé válik.-6.Loaded += new RoutedEventHandler(MainPage_Loaded). ezek pozicionálását pedig bízzuk egy StackPanelre! A StackPanelt viszont mindenképpen egy ScrollVieweren belül definiáljuk. // Adatkötés DataContext = App.IsDataLoaded) { App. hiszen ezzel biztosítható az.0.0. akkor a Silverlight 4: A technológia. Minden taszk indítására vegyünk fel külön gombot.ViewModel.0" Style="{StaticResource PhoneTextExtraLargeStyle}"/> <TextBlock Text="{Binding LineThree}" TextWrapping="NoWrap" Margin="12. Az oldal kontextusát a MainPage konstruktora állítja a megfelelő ViewModelre: // Constructor public MainPage() { InitializeComponent(). } } A generált projekt megvizsgálásával egy kis betekintést nyerhettünk az MVVM architekturális minta használatába.0" Style="{StaticResource PhoneTextSubtleStyle}"/> </StackPanel> </DataTemplate> </ListBox. és ami mögötte van című könyv 10. private void MainPage_Loaded(object sender. viszont ha komolyan érdeklődünk a téma iránt.LoadData(). this.A példaalkalmazás létrehozása <TextBlock Text="{Binding LineOne}" TextWrapping="NoWrap" Margin="12. } // Adatok betöltése.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.0. amint elkészült az oldal. RoutedEventArgs e) { if (!App. fejezete tökéletes kiindulópontot jelent a tanuláshoz.

// a tagolás nem kötelező. A chooserek lapja tartalmazzon egy Image vezérlőt is. } A Show() metódus elindítja a taszkot.DisplayName = "WP7 support". hiszen működésük teljesen azonos. majd a hívást összegző üzenetet láthatjuk (6-4 ábra). csupán az érintett tulajdonság különbözik. RoutedEventArgs e) { PhoneCallTask phoneCallTask = new PhoneCallTask(). 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). 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. 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.Show(). phoneCallTask. a kihangosítási. de vizuális elemeket ez sajnos nem tartalmazhat. // ezt nem kötelező megadni phoneCallTask. de ennek hiánya sem okoz problémát: private void btnPhoneCallTask_Click(object sender.6. fejezet részletesen taglalja.PhoneNumber = "00361/123-4567". 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. 142 . némítási lehetőségekkel. Emellett egy nevet is megjeleníthetünk. de így is megadhatjuk a számot phoneCallTask. Launcherek PhoneCallTask Telefonhívás indításakor kötelező megadni a hívandó telefonszámot. mivel ezeket a 12. A hívás lebonyolítása a megszokott felületen történik.

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

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

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

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

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

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

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

BitmapImage bmp = new BitmapImage(). 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.6. a Contacts és az Appointments osztály érhető el. 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.TaskResult == TaskResult. result) => { if (result. // dimenziók beállítása photoChooserTask. // lehetőséget adhatunk a kamera taszk indítására is egy gomb engedélyezésével photoChooserTask.Completed += (s. Alapvető telefonos funkciók használata private void btnPhotoChooserTask_Click(object sender. bmp. 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).PixelHeight = 50. } }. ami egy kijelölt tárterületen képes lekérdezéseket futtatni. a találatokat pedig generikus listán szolgáltatja a hívó alkalmazásnak.ChosenPhoto).OriginalFileName != null) { MessageBox. photoChooserTask.Source = bmp.PixelWidth = 200. imgResult.SetSource(result.OK && result. RoutedEventArgs e) { PhotoChooserTask photoChooserTask = new PhotoChooserTask().Show(result. } A példakódban egy 50 pixel magas és 200 pixel széles képet szeretnénk beolvasni.ShowCamera = true.Show(). photoChooserTask. és csupán az ezen belül található képrészt adja majd vissza alkalmazásunk számára (6-13 ábra). photoChooserTask. Az új fejlesztői készletben megjelent ugyanis a PhoneDataSharingContext osztály. így a taszk lehetőséget kínál egy ekkora terület kijelölésére. Jelenleg két implementációja.

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

JobTitle. 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.Source = bmp. // felhasználó képének lekérése BitmapImage bmp = new BitmapImage(). string note = contact. }. A függvény futásának eredménye a 6-14 ábrán látható. string title = contact.CompanyName. Hotmail.).Companies. FilterKind. significantOther.First(). // egyéb adatok string name = contact.CompleteName. string company = contact. MessageBox. A bejegyzést megtestesítő Appointment osztály főbb tulajdonságai a következő táblázatban láthatók: 152 . null).ToShortDateString().First().FirstName.Notes. stb. RoutedEventArgs e) { Contacts contacts = new Contacts(). result) => { var contact = result. name.GetPicture()). de természetesen a keresés ettől függetlenül felhasználók listáját adja vissza.Results. company. imgDataSharing. string birthday = contact. Facebook. // megjelenítés string formatStr = "Name: {0}\nCompany: {1}\nTitle: {2}\n" + "Birthday: {3}\nSignificantOther: {4}\nNote: {5}". ahol a tulajdonságok többsége szintén egy IEnumerable példány.First().Birthdays.Show(string. sajnos az emulátoron mindig egy üres listát fogunk visszakapni.SetSource(contact.First(). title.First(). } A fenti kódban minden listának csak az első elemét kérdeztük le. bmp. string significantOther = contact. birthday.SearchCompleted += (s. viszont mivel ezek az adatok mindenképpen felhasználói fiókhoz kötődnek (Live.Companies.6. 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. // csak a nevek között keresünk contacts. note)).SignificantOthers.DisplayName.Format(formatStr.First(). contacts.SearchAsync("c".

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

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

így a MediaLibrary típusú library objektumot a CameraViewModel osztályban deklaráljuk: // Microsoft. ahol korábban már egy // TODO: mentés megírása sort hagytunk. amiből tudhatjuk. hogy a kamera váltása megtörtént.Frameword dll! MediaLibrary library = new MediaLibrary(). ezért hivatkozzunk erre a dll-re projektünkben! A tárolás szintén a ViewModel dolga. 6-18 ábra: Értesítés a feldolgozás befejeződéséről Már csak annyi maradt hátra.Framework szerelvény része. amikor a kép már elkészült. például tároljuk el a készülék médiatárában. majd a feldolgozás végén egy üzenetablakban kapunk értesítést a feladat befejeződéséről (6-18 ábra). Ehhez egy MediaLibrary példányra lesz szükségünk. ezt cseréljük most ki az alábbiaknak megfelelően: 160 . A mentés akkor történjen.Xna.Xna. amelyen keresztül hozzáférhetünk a telefonon tárolt zenékhez és képekhez. Az osztály a Microsoft. A mentés helye a CaptureImageAvailable eseménykezelő. Kép készítésekor a gomb egy időre inaktívvá válik. hogy a kapott képpel kezdjünk is valamit. 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.6. 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.

}.Show(name + " mentve!"). Deployment. // mentés a médiatárba library. A fejezet végén pedig egy példaalkalmazás írásán keresztül láthattuk. 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.Dispatcher. Végigvettük az erre kínált taszkokat. }). Ezt követően megnéztük a partner.ImageStream).SavePictureToCameraRoll(name.ToShortTimeString() + ". Az én emulátoromon például a 6-19 ábra művészeti remekművei készültek.Összefoglalás Camera.jpg". // újra fotózhatunk IsPhotoEnabled = true.Now.CaptureImageAvailable += (s. az előlapon lévő kamera képét ugyanis egy bal oldalra mutató sárga pötty. míg a hátlapon lévőét egy felfelé mutató jelképezi.é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. e) => { string name = DateTime.Current. e. 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.BeginInvoke(() => { // visszajelzés küldése (UI szál) MessageBox. amelyek egyszerű hozzáférést biztosítanak a telefon valamely funkciójához. 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. 161 . 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.

.

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

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

. Oldjuk meg azt is. hogy a négyzet nyomva tartása (Hold) esetén a négyzet nagyobbra nőjön.) 7-2 ábra – A Hold (és a Tap) esemény hatása 165 .Height += 20.. rect. GestureEventArgs e) { rect. } Tesztelésnél látható. ha adunk neki egy nevet az x:Name tulajdonságon keresztül.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.5. Így megkímélhetjük magunkat a sok típuskonverziótól. egyszerűbb. hogy a Hold esemény hatására a négyzet 20-20 képpontonként nő. tehát ha 1 mp-en belül felengedjük az ujjunkat. akkor elfordul a négyzet. 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=". (Emellett persze továbbra is működik a Tap.5"> .Width += 20. </Rectangle> Az eseménykezelőben növeljük meg a négyzet méretét! private void rect_Hold(object sender..

hogy mely objektumhoz viszonyítva történik a manipuláció (ez maga a manipulált objektum). ((RotateTransform)rect. Ennek ManipulationContainer tulajdonsága megadja.RenderTransform). Ehhez nem kell több ujját használnia – már egy érintéstől is kiváltásra kerül az esemény. } Multitouch manipulációk Az előző események egyetlen ujj érintését jelzik vissza felénk. így elviekben semmi nem gátolja a felhasználót abban.. 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=". nem a ManipulationDelta. 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.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. Ha ezt meghívjuk.RenderTransform> <RotateTransform Angle="0"/> </Rectangle. ha többérintéses eseményeket szeretnénk tesztelni – az emulátor nem támogatja a több érintést. GestureEventArgs e) { rect. A Windows Phone-nal felszerelt telefonokban alapkövetelmény a legalább négy érintési pontot kezelni képes kapacitív kijelző. hogy szintén a ManipulationStartedEventArgs része a Complete metódus. További telefonos funkciók használata A DoubleTap megoldása is az előbb leírtakat követi. hogy előre megfontolt szándékkal egyszerre több ujjával is megérintse a kijelzőt. amikor a felhasználó megérinti a kijelzőt. Az események második szintje a többpontos (multitouch) érintések kezelését is lehetővé tevő úgynevezett Manipulation események csoportja. 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. illetve a ManipulationOrigin tulajdonság. 166 . az operációs rendszer lezártnak tekinti a manipulációt.Height = 100. Készítsük be a telefont. hanem a ManipulationCompleted esemény fut majd le.7. amit megnyomtak. tehát ha a felhasználó továbbra is a kijelzőn tartja ujját.5"> <Rectangle. Hasznos lehet még tudni. rect.Width = 100.5.Angle = 0. Ennek egyik paramétere egy ManipulationStartedEventArgs típusú objektum.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

akkor lehetőleg azonnal töröljük azokat. amint már nem használjuk. Ahogy a neve is mutatja. mindössze annyi a különbség. akkor csak az Isolated Storage áll a rendelkezésünkre. amit relációs adatbázisban tárolunk. é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). amikor tárolni kell adatokat a készüléken. legyen szó egyszerű beállításokról vagy összetett adatokról. így ha az alkalmazás törlésre kerül. olvasni. ahol az alkalmazásunk képes írni. valamint az általános fájlműveleteket is el tudja végezni. 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). A Windows Phone 7 Isolated Storage megoldása nagyon hasonló a Silverlightos Isolated Storage megoldásához. Minden alkalmazás csak a saját Isolated Storage-ében tud garázdálkodni. akkor a megszokott környezetével találkozhat. 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. néhány szempontot célszerű szem előtt tartani:     Csak akkor használjuk a fájlrendszert. vagyis itt egy alkalmazás korlátlanul gazdálkodhat a tárhellyel.1 verziója óta háromféle adatkezelési módszer létezik a készüléken (8-1 ábra):    187 . Adatkezelés Minden nagyobb alkalmazásnál eljön az az idő. 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. Ebben a fejezetben megismerkedhetünk azzal. A Windows Phone SDK 7. ezzel növelve a biztonságot és a fájlkárosodás elkerülését. vagyis az alkalmazások nem férhetnek hozzá egymás tárhelyéhez. Leginkább az alkalmazásunk beállításainak mentésére használjuk. a felhasználó adatai még megmaradnak. Relation Data: Relációs adatokat tárolhatunk egy lokális adatbázisban (SQL Server Compact Edition). illetve ha a felhasználó másik kliensen jelentkezik be. csak és kizárólag az alkalmazásunk által használt Isolated Storage-ünket. ez egy tárhely (Storage). amiket a Linq To SQL technológiával érhetünk el. hogyan kezeljünk adatokat a Windows Phone 7 készülékünkön. Minden alkalmazás kérhet magának egy-egy ilyen elkülönített tárhelyet. mint a Silverlightnál.8. ott viszont úgy. hogy itt nincs megszabva kvóta. így más alkalmazások semmilyen módon nem befolyásolhatják az alkalmazásunk működését. ahogy csak szeretné. Settings: Kulcs/érték adatokat tárolhatunk benne (IsolatedStorageSettings). Közvetlen módon tehát nem érhetjük el a teljes fájlrendszert.

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

object value). Remove(string key). Contains(string key).IsolatedStorage névtérre. "Attila").IO. ICollection<KeyValuePair<string.IO. és ezeket az értékpárokat az adott alkalmazás IsolatedStorage-ébe menti el. Ha már létezik a kulcs.ApplicationSettings. } public int Count { get. out T value).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. ezért a rá vonatkozó szabályok élnek. set. TryGetValue<T>(string key. object>>. } public public public public public public } } void void bool bool void bool Add(string key.IsolatedStorage { public sealed class IsolatedStorageSettings : IDictionary<string. Save(). 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. Az 189 .ArgumentException-t kaphatunk. TValue> objektum. Az alábbi kódrészlet az IsolatedStorageSettings felépítését mutatja be: namespace System. object>>. a fájlművelethez pedig a System. ebben az esetben az első paraméter egy kulcs. amely egy kulcs/érték párost tud tárolni. } public ICollection Values { 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). IEnumerable { public static IsolatedStorageSettings ApplicationSettings { get. ICollection. IEnumerable<KeyValuePair<string. IDictionary. aminek egyedinek kell lennie. } public ICollection Keys { get.Add("UserName". Mivel ez egy Dictionary.IO névtérre lesz szükségünk. Clear(). a második paraméter pedig egy tetszőleges objektum lehet. Ahhoz. Az alábbi példában egy egyszerű stringet láthatunk: // Felhasználónév hozzáadása – Új kulcs létrehozása IsolatedStorageSettings. a System. } public object this[string key] { get. object>. akkor egy System. hogy az IsolatedStorage-et elérjük..

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

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

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

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

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

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

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

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

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

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

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

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

Adatkezelés ISETool.microsoft. hogy adatokat töltsünk le a telefonunkról (vagy emulátorunkról a számítógépünkre).0 –ás) változatában nem volt beépített lehetőség. és azokat lefuttassuk az adott adatbázismotoron. Ezt az adatbázist csak a Linq To SQL API segítségével érhetjük el. mint az Isolated Storage esetén − nem oszthatjuk meg a többi alkalmazással! Linq To SQL A Linq To SQL egy ún. Ezt a kiegészítőt a következő oldalról tölthetjük le: http://visualstudiogallery.8.NET Framework tartalmaz. az alkalmazásba beépülő módon működő relációs adatbázis-kezelő. hogy a gépünkről töltsünk fel adatokat a telefonon futó alkalmazásunk könyvtárába.msdn. az 202 . olyan eszköz is létezik. hogy ez működjön. amely a Visual Studio-ba épül be. sőt. azt –ugyanúgy.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. hogy kódunkban beágyazva fogalmazzunk meg lekérdezéseket. a Mango frissítéssel viszont az Isolated Storage-ben az alkalmazásunk elhelyezhet relációs adatbázist is. amely egy fájl alapú. Az SQL Servernél megszokott Transact SQL segítségével közvetlenül nem érhetjük el az adatbázist. amely szintén lehetőséget biztosít arra. Ezt Microsoft SQL Server Compact Edition (CE) teszi lehetővé. Az adatbázist csak saját alkalmazásunk írhatja és olvashatja. illetve lehetőséget biztosít arra is. és így objektumorientált módon kezelhetjük adatainkat. A Linq To SQL lehetőséget biztosít arra.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. Ilyen eszköz például az Isolated Storage Tool (8-9 ábra). ORM (Object Relational Mapping) keretrendszer. amelyet a .

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

és írjuk meg a szervert meghívó Windows Phone alkalmazást! Ehhez nyissunk egy új Visual Studio projektet. E művelet során olvassa majd be a Visual Studio a szerverünk által publikált leíró állományt. kézzel írjuk be! Az URL-t jegyezzük meg. amely legyen Windows Phone Application típusú. A /SampleService. Referencia felvételéhez kattintsunk jobb gombbal a projekt nevére (WebServiceClientSample) a Solution Explorer ablakban. 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). majd kattintsunk a Go gombra! (Fontos. hogy a telefon melyik verziójához készítjük a projektet. és kattintsunk az OK gombra! 221 . 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. és minden gépen más lesz. ha a szerveroldalon Windows Azure-t használunk. Most térjünk át a kliensoldalra.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. fel kell rá vennünk egy referenciát. hogy használhassuk a webszolgáltatást. ha nincs ott.svc elérési útnak viszont szerepelnie kell. és készíti el a bevezetőben említett proxy osztályt. Jelenleg egy ilyet tartalmaz a webszolgáltatásunk: az imént megírt Translate() metódust. Válasszuk a Windows Phone OS 7. neve pedig WebServiceClientSample! A projekt létrehozását követően a Visual Studio megkérdezi majd. hogy webes projektünknek még futnia kell!) A Visual Studio letölti és feldolgozza a megcélzott webszolgáltatás adatait. akkor ellenőrizzük az URL-t! A localhost nevet követő portszám véletlenszerűen generált.1 (vagy valamelyik újabb) változatot! Ahhoz. é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. Adjunk egy nevet a referenciának (SampleServiceReference).

client.TranslateCompletedEventArgs>( client_TranslateCompleted). elég csak ki-be kapcsolnunk).SampleServiceClient client = new SampleServiceReference. 222 . hogy a felhasználó felé jelezhessük a háttérben zajló munkát. é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. Ezt ServiceReferences. ami a Windows Phone „mozgó pontjait” generálja. Most kattintsunk duplán a gombra.SampleServiceClient(). Kommunikáció szerverrel 9-3 ábra: A Service Reference-hozzáadó ablak A Visual Studio legenerálja a proxy osztályt. Ezért meghívásához először feliratkozunk arra az eseményre. amely MainProgressBar névre hallgat és alapértelmezésként nem látható. 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. hogy épp hány százalékon áll.TranslateCompleted += new EventHandler<SampleServiceReference. a webszolgáltatás aszinkron.9. ami a kérés befejezését jelzi majd. és tulajdonságait elhelyezi egy új fájlban. RoutedEventArgs e) { SampleServiceReference. bekapcsoljuk a ProgressBar-t: private void TranslateButton_Click(object sender. amikor a telefon dolgozik valamin)! A ProgressBar nem látható az eszköztáron. akkor ebben az állományban kell átírni a webszolgáltatás URL-jét a végleges címre.ClientConfig néven találjuk meg projektünkben. ezért kézzel kell hozzáadnunk alkalmazásunk XAML kódjához. Ha alkalmazásunkat élesben szeretnénk felhasználni. 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. de amint korábban már szó volt róla. hogy belépjünk a Click eseménykezelőjébe! Kódunknak meg kell hívnia a webszolgáltatást. Keressük meg a XAML kódban a gombunkat leíró sort (<Button>). Ezenfelül.

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

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

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

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

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

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

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

Az itt megtanultak alapján már tudunk egy ODatafogyasztásra képes alkalmazást készíteni. létrehozhatunk benne aszinkron kommunikációra alkalmas várakozási sorokat (Queue Service). mert rengeteg Microsoft-termék és számos külső gyártó már most támogatja! Ilyen például az SQL Azure. mint pl. egy telefonkönyv (Table Service). az látogasson el a http://www. illetve feltölthetünk egyszerű táblajellegű információkat.odata. Ezeket az igényeket természetesen megoldhatjuk egy saját szerverrel. a Netflix és még sokan mások. Érdemes megismerkedni a protokollal. amint később azt látni fogjuk. hogy mindhárom tárhelyszolgáltatás alkalmas komoly. a SharePoint. ráadásul két. A webszolgáltatásokhoz hasonlóan az OData is rendkívül széles témakör. 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. Mindhárom szolgáltatásra igaz. Aki szeretné jobban megismerni az OData protokollt. Ismerjük meg ezeket részletesebben! 230 .org weboldalra. Az Azure emellett komoly kötelezettségeket vállal a szolgáltatás rendelkezésre állására is. egymástól több száz kilométerre lévő adatközpontba is szétmásolja. Így elmondhatjuk. 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. valamint a protokollal kapcsolatos részletes információk és a fórum. professzionális alkalmazások kiszolgálására is. ráadásul egyszerű objektumorientált API-n keresztül. Az Azure Storage háromféle szolgáltatást nyújt: tárolhatunk benne fájlokat (Blob Storage). 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. így a véletlen adatvesztés gyakorlatilag kizárt.9. 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. 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. az eBay. melyre alkalmazásunk egy webszolgáltatáson keresztül tölti fel az anyagokat. Ez utóbbi nem váltja ki az SQL szervert.

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

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

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

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

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

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

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

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

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

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

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

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. és másoljuk ki az ott megjelenített értéket (9-14 ábra)! 9-14 ábra: Access Control szolgáltatásunk menedzsment-jelszava 242 . 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.9. Kattintsunk a Password elemre.

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

.

A telefon kezdőlapja nem élettelen ikonokból áll.10. hogy egy külső eseményről nem a felhasználót szeretnénk tájékoztatni. A fejezetben részletesen megismerkedünk a lapkák és a további értesítési szolgáltatások képességeivel. de akár szerveroldalról. fontos eseményekről maradna le. Frissíthetjük őket az alkalmazás futtatása közben. melyek tartalmát a fejlesztő szabadon változtathatja – ahogyan azt a 10-1 ábra mutatja. például minden folyamatban lévő játszmához egy-egy. 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. Ha ezeket jól tudjuk használni. ahogyan azt a 10-2 ábra illusztrálja. Alkalmazásunkhoz akár több lapka is tartozhat. 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). szöveget vagy számot jeleníthetünk meg. 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. hanem a telefonon futó alkalmazásunknak akarunk üzenni. 10-1 ábra: Windows Phone lapkák A lapkákon képeket. hanem nagyméretű lapkákból. A platform eszközeivel erre is lehetőségünk van. programozásával. mintha 245 . akkor sokkal gazdagabb élményt kínálhatunk. A lapkák a telefon kezdőképernyőjén kapnak helyet. Ezek az üzenetek a felhasználó aktuális tevékenységétől függetlenül mindig megjelennek. így ha más módon nem tudnánk üzenni a felhasználónak. az alkalmazás futása nélkül is. 10-2 ábra: Felugró üzenet Végül az is lehet.

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

Minden tulajdonság pontosan meghatározott módon változtatja meg a 247 . Mi. Egy ilyen dinamikus lapkára mutat példát a 10-5 ábra. animálhatjuk. a széles lapkák számunkra nem használhatók. ha alkalmazásunk lapkája is megjelenik ott.A lapkák tulajdonságai Széles lapkája mindössze néhány beépített Windows Phone alkalmazásnak van – ilyenek pl. 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. és a lapka törlésével a hozzá tartozó alkalmazás nem kerül eltávolításra. a Calendar és a Pictures. ahogyan azt a 10-4 ábra illusztrálja. A frissen feltelepített alkalmazások alapértelmezésként nem kerülnek ki a kezdőképernyőre. a másodlagos lapkák tárgyalásánál. 10-5 ábra: Dinamikus lapka. 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. 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. megnyomáskor az alkalmazás kezdőlapjára visznek – vagyis ezek a statikus lapkák. ezért nagyon jó. Ám alapértelmezésként ezek a lapkák mindössze az alkalmazás ikonjából és nevéből állnak. arra kizárólag a felhasználónak van joga. és törölhetjük is őket a kezdőképernyőről. a négyzet alakú lapkák 173 pixel szélesek és magasak. Statikus és dinamikus lapkák Ha egy alkalmazást fejlesztünk. az külön programozói erőfeszítés nélkül is kitűzhető lesz a kezdőképernyőre. azaz rendelkezik majd lapkával. Azonban lapka kitűzését kódból még kezdeményezni sem tudjuk. 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. hogy egy telefon felhasználójaként tetszésünknek megfelelően rendezhetjük el őket – megváltoztathatjuk sorrendjüket. Mivel a kezdőképernyőt a felhasználó a telefon minden bekapcsolásakor látja. a részleteket lásd később.

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

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

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

a program hibára fut. 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. akkor a telefon azt átméretezi majd nekünk.BackgroundImage = new Uri("/AppTileBackground. é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.Relative). menüpontot (10-10 ábra)! Tallózzuk ki az imént létrehozott képet. mint beírni a tileData adatstruktúrába az így létrehozott kép URL-jét. A sor végén található UriKind. Ez adja meg.Relative paraméter nagyon fontos.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. tileData. már nincs más dolgunk. Mentsük el a képet PNG vagy JPG formátumban. majd az Add menüből válasszuk az Existing Item. 251 . hogy a frissen megadott fájlt tartalomként akarjuk használni – ezután tudunk majd kódból hozzáférni.png".. A Solution Explorer-ben jelöljük ki a frissen beszúrt fájlt. 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. vagy akár egy képfájlra mutató internetes URL-t is megadhatunk. és a Solution Explorer ablakban kattintsunk jobb gombbal a projekt nevére (LocalTileApiSample). de ha eltérő méretűt hozunk létre. hogy az URL relatívként értelmezendő. UriKind.. statikus képet is helyezhetünk. Ha ezt nem írjuk be. AppTileBackground néven! Térjünk vissza a Visual Studióba.

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

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

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

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

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

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

és letöltése nem tarthat 30 másodpercnél tovább. hogy a megjelenítendő információt szerveroldalon készítsük elő. 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. fix alkalommal vagy határozatlan ideig)? Milyen gyakran történjen meg a frissítés (óránként. 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. amelyek utána a háttérben futnak majd. ha a szükséges tartalmat nem a készüléken. A képfájl maximum 80 kilobájtos lehet. óránként szeretnénk frissíteni. szerver igénybevétele nélkül. imperatív módon tudtuk frissíteni lapkáinkat. Mindkét módszer segítségével a telefonon futó kódból. Bizonyos esetekben azonban kényelmesebb lehet. akkor az időzítést törli a futtatókörnyezet. alkalmazásunk leállását követően is. 258 . hogy ehhez még külső szerverre sincs szüksége. Időzítés beállítása az elsődleges lapkára Korábban megismerkedtünk a lapkák tulajdonságaival. a többi tulajdonság ezen az API-n keresztül nem módosítható. hogy a felhasználó a kezdőképernyőre tűzve tartsa alkalmazásunkat.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. 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. azaz nem használhatunk a telefonon lévő helyi erőforrásokat. a telefon pedig egyszerűen csak letöltse azt. Ehhez kódunkat helyezzük a MainPage() konstruktorába. 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. Írjunk egy rövid példaprogramot. 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. Windows Phone OS 7. A ShellTileSchedule arra ad lehetőséget. Egy folyamatosan frissülő lapka pedig jó ok arra. Használatához (a Background Agent-hez hasonlóan) alkalmazásunk futása közben időzítenünk kell a frissítéseket. közvetlenül az InitializeComponent() metódushívás után! Lapkánkat határozatlan ideig.10. hanem egy kiszolgálón állítjuk elő. Ha az időzített művelet végrehajtása 3 egymást követő alkalommal sikertelen. naponta. A Background Agent nagy előnye. 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.

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

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

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

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

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

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

Amint a példakódban levő XML-ből látjuk.Net. A fentiek elvégzése után az űrlapnak a 10-19 ábrához kell majd hasonlítania. akkor új példányt kell indítanunk. 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.Text + "</wp:Title>" + "<wp:BackBackgroundImage></wp:BackBackgroundImage>" + 265 .0\" encoding=\"utf-8\"?>" + "<wp:Notification xmlns:wp=\"WPNotification\">" + "<wp:Tile>" + "<wp:BackgroundImage></wp:BackgroundImage>" + "<wp:Count></wp:Count>" + "<wp:Title>" + MessageTextBox.Text. using System. a címkébe pedig a visszatérési értéket helyezzük majd el. ehhez a Visual Web Developer Express-re van szükségünk. egy gombot SendTileButton néven és „Lapkafrissítés küldése” felirattal. amit megjelenítünk majd a lapkán! A gombbal kezdeményezzük a küldést. neve PushNotificationServerSample ! A projekt létrejötte után adjunk ahhoz egy új Web Form típusú elemet.IO.A Push Notification szolgáltatás Ezt létrehozhatjuk a már megnyitott Visual Studio példányban is.aspx oldal a vezérlőelemekkel Következik a szerveroldali kód megírása. kódunk ezért először felépíti ezt az XML struktúrát. a lapkák korábban megismert valamennyi tulajdonságát frissíthetjük. akkor az nem változik a lapkán. //Előállítjuk az üzenetet. valamint egy címkét ResponseLabel néven! Az első szövegdobozba kerül majd az MPNS által visszaadott URL. Ha valamelyik XML tulajdonságot üresen hagyjuk. Hozzunk létre az űrlapon két szövegmezőt UrlTextBox és MessageTextBox néven.NET Empty Web Application. A második szövegdobozba írjuk üzenetünket. ahová üzenetünket küldjük majd. 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. mert a telefonos fejlesztésre használt Visual C# Express nem támogatja a webfejlesztést. Default. de ha a Visual Studio Express verzióit használjuk. 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. 10-19 ábra: A Default. using System. a többi tulajdonságot változatlanul hagyja. string tileMessage = "<?xml version=\"1. A projekt típusa legyen ASP.aspx néven! A Visual Studio automatikusan megnyitja az űrlap HTML nézetét.

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

hogy ez az XML is tartalmazza a felugró értesítések valamennyi lehetséges tulajdonságát. é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. amint az a 10-21 ábrán látható. a Push Notification-öknél ez nincs így – ha az alkalmazás épp nincs kitűzve. és ezeket is kezelje le. ha ékezetes betű van az üzenetben. 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.BindToShellTile(). és tűzzük ki a kezdőképernyőre. elküldjük az URL-t a szervernek. 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. és kattintsunk a Lapkafrissítés küldése gombra! A webalkalmazás összeállítja az XML-t.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 lapkákhoz hasonlóan itt is 267 . ami rögtön továbbítja azt a telefon felé. é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. Szintén fontos. hogy a Push Notification-ök sajnos nem minden karaktert támogatnak. Hibát kaphatunk. Ennek hatására a frissítés gyakorlatilag azonnal megjelenik. Írjuk be a pushChannel. hogy a létrehozott csatornán keresztül értesítések is érkezhetnek. ha az alkalmazás lapkája nem volt kitűzve. 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. A szerveroldalon szintén nagyon kevés változtatásra van szükségünk. sor alá a következő egyetlen sort: pushChannel. Mindössze azt kell közölnünk a telefonnal. Végül térjünk vissza a webalkalmazáshoz. Értesítések megjelenítése Push Notification-ök segítségével Nézzük. az üzenet elvész.BindToShellToast(). hogy míg a ShellTile API-n keresztül elvégzett változtatásokat akkor is elmentette a telefon. Ennek megfelelően a kliensoldali kódban minimális változtatást kell csak végrehajtanunk. a szerverről pedig XML formátumú kéréseket irányítunk a csatornába. 10-21 ábra: A Push Notification-nel frissített lapka Jó tudni. elküldi az MPNS-nek.

Add("X-WindowsPhone-Target". 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 . sendNotificationRequest. majd másoljuk át az URL-jét a webalkalmazásba. "toast"). így ezúttal egy eseményre kell majd feliratkoznunk. Lapkák és értesítések ügyeljünk. "2").xaml</wp:Param>" + "</wp:Toast> " + "</wp:Notification>".Headers. mert a 7. Helyezzük a következő kódot mindkét pushChannel. A raw üzenetek csak akkor fogadhatók. 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. Erre azért van szükség.ErrorOccurred += kezdetű sor után: pushChannel.10. é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. akkor ehhez a ShellToastNotificationReceived eseményre kell feliratkoznunk. és nem fut le a módosított kódunk. akkor csak újrahasznosítja a csatornát. és 22 a 900 másodpercen belülit). Miután ezzel elkészültünk. már tesztelhetjük is az alkalmazást.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(pushChannel_HttpNotificationReceived). 12 a 450 másodpercen belülit. amikor alkalmazásunk fut. hogy ez egy értesítés.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. Ezután módosítsuk a kérés HTTP fejrészét! Meg kell adnunk.Text + "</wp:Text1>" + "<wp:Text2></wp:Text2>" + "<wp:Param>/MainPage. 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).Add("X-NotificationClass". A teszteléshez előbb el kell távolítani a kliens alkalmazást a telefonról. és kattintsunk az Értesítés küldése gombra! Az eredmény a 10-22 ábrához hasonlít majd. string tileMessage = "<?xml version=\"1. ami lapkafrissítéshez is beregisztrálná (a BindToShellToast() hívás).0\" encoding=\"utf-8\"?>" + "<wp:Notification xmlns:wp=\"WPNotification\">" + "<wp:Toast>" + "<wp:Text1>" + MessageTextBox. Így ha most elindítjuk. 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. azaz „toast” típusú.Headers. Távolítsuk el tehát a programot a telefonról. sendNotificationRequest. mert korábbi tesztjeink során az már megnyitotta a Push Notification csatornát.

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

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

Ez azt jelenti. több éve kedvelt és elterjedt technológia. könnyebben tanulható és könnyebben kezelhető. amely a legújabb technológiákra épít. mint Windows. 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. A választás az XNA Frameworkre esett. mint azelőtt volt. Természetesen. és az arra való áttérés egy . amely magasabb absztrakciójú megoldásokat kínál. Azonban a Windows Phone az ipar számára egy újonnan belépő tagot jelentett. ezzel elméleti és gyakorlati alapot adva azon Olvasóinknak is. amire egy játékprogram esetében szükség lehet (11-1. és tartalmaz mindent. Miután a teljes . hogy ezen a téren a Mango frissítés milyen újdonságokat hozott magával. aránylag rövid kiadási ciklusokkal. amely a teljes platformnak csak egy darabja). hogy mindenképpen érdemes adni egy rövid ízelítőt a telefonos játékok fejlesztéséből. 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. í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. . A fejezet első részében megismerkedünk az XNA Framework és a grafikus programozás legfőbb mozzanataival. Ők nagy valószínűséggel nem fognak egy komplex grafikus rendszert kitanulni. Amikor a platform utódjának fejlesztésébe kezdtek. Az XNA a Microsoft játékfejlesztési eszközkészlete és futtatókörnyezete különböző eszközökre. így a választás a Direct3D lehetett volna. így nemcsak a tapasztalt játékfejlesztőket kellett megcélozni a technológiai támogatásokkal. PC-re írt játékok esetében két elterjedt grafikai API létezik: OpenGL és DirectX (pontosabban a Direct3D.11. azonban úgy gondoltuk. és mikor tudjuk kihasználni az új lehetőségeket.NET fejlesztő számára sokkal kevésbé megterhelő. így sokkal kényelmesebb megoldásra volt szükség. Miután a Microsoft a nyílt OpenGL-t nem használja saját fejlesztéseihez. á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 . Ezek után megnézzük. 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.NET Framework számos okból nem vihető át egy mobil eszközre. a fejlesztői modell előnyei és hátrányai jól körvonalazódtak. Xbox és most már a Windows Phone is.és kezdő fejlesztőket is. ahogy azt megszoktuk. skálázási eltérésekre és néhány. illetve bemutatni. és a Windows a grafikus alrendszer támogatásán kívül mást nem nyújt. pontosan mit is jelent a Silverlight és az XNA hibrid megjelenítési rendszere. 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. A Silverlight mint korszerű alkalmazásépítési platform jó választásnak tűnt. Windows Phone – a motorháztető alatt A Windows Mobile fejlesztése során a Microsoft rendkívül sok tapasztalatot halmozott fel. egy olyan sokkal átgondoltabb és korszerűbb rendszert szerettek volna alkotni. hogy a céleszközök között az alkalmazások átvihetők. hanem a játékok fejlesztése iránt érdeklődő hobbi. Azonban hiába a gazdag médiatámogatás. akik eddig még soha nem találkoztak fejlesztői szempontból számítógépes játékokkal vagy grafikus programozással.NET alapú programozási felülettel rendelkezik.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ahogy a 11-20 ábrán is látható! 11-20 ábra: új projekt létrehozása a játékhoz Látható. é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. a másik viszont újdonság. továbbá alkalmas arra. amely hivatkozik a Content projektre.xaml fájllal is. hogy a fő projekt tartalmazza a Silverlight alkalmazásokban jól megszokott MainPage. amerre haladnia kell (irányvektorként tekintsünk rá) PrevDirection: akkor fogjuk felhasználni.11. Y) koordinátákkal Direction: az aktuális irány. a neve pedig Snake. szükségünk lesz egy osztályra.xaml fájlt. amely a kígyónak a szegmenseit tárolja. Egy XNA könyvtár. melynek neve SnakeBlock. 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. Az egyik az XNA tartalomkezelője. Továbbá bővült a projektünk az eddigiekhez képest egy GamePage. amely a felhasználói felületünknek az alapját jelenti. hogy elkészítsük benne az XNA komponenseinket. melynek deklaratív része teljes mértékben üres. ennek a típusa most Windows Phone Silverlight and XNA Application legyen. Készült még két projekt. amellyel már találkoztunk a fejezet során. A játék jelentős részét itt fogjuk megírni. 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. Miután a projektet létrehoztuk. a mögöttes kód viszont az XNA-val való együttműködésre fel lett készítve.

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

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

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

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

a tartalomkezelő felhasználásával inicializálnunk kell a kígyó objektumpéldányunkat. Szükségünk lesz egy új objektumpéldányára a kígyó osztályunknak. hogy ide ne kelljen a későbbiekben visszatérnünk. private private private private private private private private ContentManager contentManager.Draw += OnDraw. ami a mi esetünkben semmi mást nem jelent. amellyel az eleséget fogjuk elszórni a pályán.Current. LayoutUpdated += new EventHandler(GamePage_LayoutUpdated). és onnan térünk át a játékoldalra). ha deklaráljuk. amely minden egyes alkalommal le fog játszódni. amelynek funkcióját a későbbiekben részletesen megismerjük majd. SpriteBatch spriteBatch.UpdateInterval = TimeSpan. timer. mint a textúrák lekérését a tartalomkezelőtől. timer = new GameTimer().FromTicks(333333). elhelyeztem egy UIElementRenderer adattagot is.Update += OnUpdate. kelleni fog egy háttér textúra és egy véletlen szám generátor.Current as App).Content. SnakeObject snake. Itt történik meg az első felszedhető szegmens (ha az eleség név tetszetősebb. timer. protected override void OnNavigatedTo(NavigationEventArgs e) { SharedGraphicsDeviceManager. public GamePage() { InitializeComponent(). } Amikor az oldalra navigálunk (először a MainPage. timer.Flick. TouchPanel. 297 . akkor hívhatjuk így is) inicializálása is.xaml-lel indul az alkalmazás.EnabledGestures = GestureType.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.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. contentManager = (Application. amikor a felület frissül.GraphicsDevice. akkor be kell töltenünk a tartalmakat. és fel kell iratkoznunk az oldal LayoutUpdated eseményére is. Az osztály konstruktorában engedélyeznünk kell az érintésminták használatát. Random rand = new Random(). GameTimer timer. UIElementRenderer uiRenderer.SetSharingMode(true). SnakeBlock newBlock. snake = new SnakeObject( contentManager ). Texture2D background. Ahhoz. egyelőre elég.

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

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

11. melyet az Olvasó tetszése szerint tovább bővíthet. É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 . 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. Az utóbbira építve elkészítettük egy Snake játéknak az alapjait is.

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

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

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

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

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

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

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

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

(pl: egy cég számára készítünk egyedi fejlesztést). Ezt a funkciót „my dashboard” menüpont alatt érhetjük el.  I will publish it manually after it has beed certified: A sikeres ellenőrzés után saját magunk kézzel kell. akkor sem kell aggódnunk. Menthetjük a folyamatot. mellyel az alkalmazásunkat rögtön publikálják a Marketplace-re. ha az alkalmazásunk tesztelését végző személlyel speciális információt szeretnénk megosztani.   Ha ezzel is készen vagyunk. ha átmegy a teszteken. de ha esetleg 4-5 nap lenne. Akkor kell kitöltenünk. kattintsunk a Submit gombra. As soon as it’s certified. ha az alkalmazásunkat csak egy szűk réteg fogja használni. As soon as it’s certified: Ez egy automatikus folyamat. 309 . deep linkre. but make itt hidden: Hasonlóan az előző beállításhoz. hogy engedélyezzük a piactérre kerülést.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.) Ezt akkor használjuk. ekkor a soron következő köszöntő képernyő fogad. akkor kattintsunk a Next gombra! Ezt követően a Test ablakra jutunk. hogy mikor kerüljön az alkalmazás a piactérre. és ezt követően bármikor visszatérhetünk az oldalra az alkalmazást publikálni. de csak azok a felhasználók érhetik el. Publishing options: Azt határozhatjuk meg. Itt néhány teszteléssel kapcsolatos adatot adhatunk meg (12-12 ábra):   Test notes or instructions: A mező kitöltése opcionális. itt is azonnal a Marketplace-re kerül az alkalmazás. akikkel mi megosztjuk az alkalmazás elérhetőségét (ehhez szükségünk lesz egy ún. Az elfogadás folyamata néhány napot igénybe vehet: általában 1-2 nap. amint sikeresen átment az ellenőrzéseken.  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). és kapcsoljuk ki a Frame rate számlálókat is! Ha ez megtörtént. de a Windows Phone 7. de a legtöbbjük használata legtöbbször kényelmetlen. majd a nagyítási beállításokat (nagyító ikon) állítsuk 100%-ra. OneNote.12. akkor indítsuk el az 310 . 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. hogy legalább egy 480x800-as képernyőkép legyen az alkalmazásunkról mellékelve. 12-13 ábra: Screnshot készítése Nézzük meg használat közben! Indítsuk el az alkalmazást. A méretnek pontosnak kell lennie. A neten persze találhatunk erre is jó néhány eszközt. é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.

ikonokat és képernyőképeket. ami nem engedélyezett egy Backround Agenttel? Nincs-e váratlan hiba. amiről a screenshotokat szeretnénk elkészíteni. 311 . Application Details Automated Tests Monitored Tests Manual Test A Test Kit felhasználói felületén négy fül található. 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. az alkalmazásunkhoz tartozó képeket. A tesztek lefuttatásához egy Release konfigurációval történő fordításra is szükségünk van. Az Applicaton package mezőbe az XAP fájl útvonala található.Publikálás alkalmazást.1 SDK –val érkezett egy hasznos eszköz (Marketplace Test Kit) is. 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. ami nem engedélyezett a számunkra? Használ-e olyan API-t. Ha nem adjuk meg ezeket a képeket. és navigáljunk arra az oldalra. hogy az alkalmazásunk megfelel-e a Marketplace követelményeinek. amivel megvizsgálhatjuk. ha bezárjuk az alkalmazást? Stb. é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. az alapbeállítás szerint a Bin\Release mappában található XAP-ra mutat. ahol különböző teszteket futtathatunk le: Nézzük meg. akkor a tesztünk sikertelen lesz. Windows Phone Marketplace Test Kit A Windows Phone 7. 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. Ezenkívül ezen a fülön adhatjuk meg az alkalmazások piactérre feltöltendő képeit és képernyőképeit.

Az Application Details alatt megadott képeket is itt teszteljük. hogy az alkalmazásunk számára milyen Capability beállításokat (képességeket) kell meghatároznunk a WPAppManifest. Ha lefuttatjuk a tesztet. A teszt során az alkalmazást egy fizikai készüléken kell kipróbálnunk. például az alkalmazás méretét és képeit.12.xml fájlban. 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. A teszt közben a program által felkínált lehető legtöbb felhasználói esetet hajtsuk végre az alkalmazáson! 312 . 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. akkor a teszt megmondja. tehát csak a fejlesztői zárolás feloldásával ellátott készüléken tudjuk ezt megtenni.

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

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

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

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

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

.

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

Visual Studio-ban hozzunk létre egy új C# nyelvű Windows Phone alkalmazást CpuAndGpu néven. hogy újra meg újra megnyomjuk a gombot. csillagok… Illusztrációként készítsünk egy egyszerű programot – ezen fogjuk megvizsgálni a fenti teljesítményproblémákat. Elfogy a memória: Sokszor a felhasználó csak az alkalmazás lefagyását vagy hirtelen kilépését tapasztalja. egymás fedő vagy félig átlátszó textúra (bittérkép) egymásra helyezése.cs -be írjuk be az alábbiakat: 320 . stb). De hogy lesz egy vezérlőből (pl. mennyi idő alatt jön meg a válasz? Ha nincs semmi visszajelzés. a layout (elrendezés) számítása. Négyszögletes vágás – a textúrákból a GPU is képes vágást készíteni (clip). A CPU feladata még a XAML értelmezése.de megfelelő használatával mégiscsak megteremthető a 3D illúziója. és a CPU végzi. egy gomb) textúra? Ezt a folyamatot renderelésnek vagy raszterizálásnak hívják. bittérképeket manipulál. 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. több millió darabot másodpercenként. Perspektivikus torzítás – a textúra elforgatása 3D-ben. mint a nagytestvérei az asztali gépeken – háromszögeket képes a térben elhelyezni és megjeleníteni. A CPU (processzor) egy remek kis jószág. a legtöbbször észre sem vesszük. feliratok elhelyezésére. még az is lehet. amennyiben a vágó geometria téglalap alakú. és a javításuk módját. de van pár dolog. így elkerülhető a pixelesedés. mert a CPU önmagában nem lenne elég erős nagyfelbontású videók lejátszására. Teljesítmény  Hosszú válaszidő (reszponzivitás): Ha megnyomtunk egy gombot a programban. hogy a Silverlight motor a GPU-t dolgoztatja. 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. Ilyenek például a grafikai műveletek. hogy a GPU textúrákat. Ezért a telefonokban egy GPU (grafikus processzor) is található. ha tudunk pár dolgot a GPU-ról. A program az első lépésben egy csillagmezőt jelenít meg. és természetesen a programunk futtatása is.5D. Azonban a teljesítmény-problémák orvoslásához már jó. A GPU képes átméretezéskor az éleket elmosni.xaml. inkább 2. A GPU hasonlóan működik. Az általunk írt program a CPU-n fut. mint ahogy a SurfCube 3D Browserben is történt (lásd 13-14. vagy a videó dekódolás. 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. Csillagok.      Figyelmes olvasóknak feltűnhetett. Ez nem igazi 3D. mivel nem testekről csak lapos textúrákról beszélünk . utasítások és azokból szőtt algoritmusok végrehajtására. Forgatás – egy bittérkép elforgatása Átméretezés – nagyítás vagy kicsinyítés.13. a vezérlők létrehozása. amire nem ideális. 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. azt gondolva. és a MainPage. (Komolyabb 3D alkalmazást inkább XNA-val készítsünk). 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. ábra). Így viszont marad ideje egyéb feladatokra (pl. seek bar megjelenítésére. 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.

Width = size.VerticalAlignment = VerticalAlignment.Fill = new SolidColorBrush(Colors.Left. A program működése igen egyszerű.Media.Width. csillagok… using using using using using using System. ellipse. } public void CreateStarField(int numOfStars) { Random x = new Random(). Loaded += OnLoaded. } } } } A Solution Explorer-ben töröljük ki a SplashScreen. ellipse. System.Show("Startup time: " + stopwatch. 0. for (int i = 0. 321 . ellipse. double size = x. CreateStarField(100).jpg fájlt.Top.Windows.Next(607). a 13-1 ábrán látható eredményt kapjuk. ellipse.Csillagok. System. 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. A stopper elindítása után az InitializeComponent függvény a XAML-ben leírtakat értelmezi.Add(ellipse).Diagnostics. namespace CpuAndGpu { public partial class MainPage : PhoneApplicationPage { private Stopwatch stopwatch. x. RoutedEventArgs routedEventArgs) { MessageBox.Margin = new Thickness(x. i < numOfStars.Shapes. InitializeComponent(). A MainPage osztály létrehozása után elindítunk egy stoppert. 0). stopwatch.Children.HorizontalAlignment = HorizontalAlignment. ellipse.Next(456). System. System.Windows. i++) { Ellipse ellipse = new Ellipse(). ami az indulás óta eltelt ezredmásodperceket méri. // Constructor public MainPage() { stopwatch = new Stopwatch().ElapsedMilliseconds + " ms"). ellipse.Phone. Microsoft.White).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. ContentPanel.Start().NextDouble()*3.Controls.Height = ellipse. Ha elindítjuk a programot az emulátorban. } private void OnLoaded(object sender.

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

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

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

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

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

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

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

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

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

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

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

hogy az alkalmazás sokat gyorsult. A szabály az. hogy 256 Mbyte-os telefonon max. 13-14 ábra: a SurfCube visszafordul az első oldalra a könyvjelző kiválasztása után. Teljesítmény értesül a felhasználó. Természetesen a Silverlight-ban és a . Ezért változtattunk a működésen.13. 90 Mbyte-ot használhat a program. é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.NET-ben megszokott optimalizáló fogások Windows Phone-on is működnek. mert a Marketplace az alkalmazás befogadásakor igen szigorúan ellenőrzi a memória használatát. Érdemes azonban áttekinteni néhány platform-specifikus területet. Í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. nagyobb memóriával rendelkező készülékeken ennél többet is. de az azonnali reakció miatt a felhasználók egyértelműen (de tévesen) úgy érezték. é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. 338 .

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

13. ezért nincs itt sok értékelhető adat. Jellemzően 30 és 60 közötti értékeket szeretünk itt látni. a szürke a rendszer-szálat jelenti. 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). Várjuk meg. hogy egy másodperc alatt a képernyő hányszor került újrarajzolásra. 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. majd a Select All-t a grafikonon). Mit jelent mindez? 13-16 ábra: Az analízis eredménye A felső skála a másodpercekben mért időt mutatja. Mivel a csillagok kirajzolása után az alkalmazás nem csinál semmit. Teljesítmény elindul az alkalmazás a telefonon. A CPU-használatot mutató grafikonon a fehér szín azt jelzi. Alatta a Frame Rate azt mutatja. 340 . amikor a CPU nem csinál semmit. amíg megjelennek a csillagok. A zöld szín az UI szálat.

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

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

Látható. a lassú betöltődés és navigáció. Érdemes kísérletezni még a többi lehetőséggel. Szó volt a szubjektív teljesítményről. az akadozó animációk lehetséges okait és megoldását. 343 . 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. sőt azon belül a CreateStarField metódusban töltötte. hogy miképp készítsünk gyors. kitűnő teljesítményű Windows Phone alkalmazásokat. 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. hogy a telefon az ideje jelentős részét a MainPage konstruktorában. és persze saját alkalmazásokkal is! A Windows Phone Performance Analysis elsajátítása nem egyszerű.Összefoglalás 13-20 ábra: A CreateStarField vitte el a 3-as és 4-es frame közötti idő 88%-át. Ez a fejezet csak az út elejét tudta megmutatni – a CPU és GPU használatát.

Sign up to vote on this title
UsefulNot useful