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

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

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

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

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

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

.

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

.

gyakorlatilag a nulláról indulva. az alkalmazást hány különböző eszközre és hardver konfigurációra kell elkészíteni. illetve a könyv írásának pillanatáig nem sokat foglalkozott. a fogyasztói piacnak azonban ezek az elvek és ez a termék nem tudott megfelelni. 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. hanem a fejlesztőcégek számára is. A Google ezzel a kérdéssel nem nagyon foglalkozik.ezt a tényt felismerve szemmel láthatólag nem erőltette tovább ezt a vonalat. 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. hogy újabb sikertörténetek születhessenek. illetve az okoskészülékek piacán. amely az előírt hardver követelményeket maradéktalanul kielégíti. hogy az okostelefonok megjelenésével egyfajta fejlesztői „aranyláz” tört ki. 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. hol vagyunk. hogy ez vajon mekkora fragmentációt jelenthet a készülékek piacán. csupán mobil operációs rendszert fejleszt. A telefonok tudják. akik a semmiből. 15 . Ez a mobil operációs rendszer azonban elsősorban üzleti használatra készült. A Windows Phone Platform A Windows Phone megjelenésében merőben újszerű. életünk. A Microsoft valahol a kettő közötti utat választotta. hogy a Twitter. és maximálisan igyekeznek minket kiszolgálni. hogy a Microsoft készüléket nem. az eddigi mobil operációs rendszerektől eltérő dizájnnal és szellemiséggel rendelkezik. A Microsoft . a Windows Phone és saját alkalmazásboltja (Marketplace) megjelenésével új piacot nyit a vállalkozó szellemű fejlesztők számára. Nem csoda hát. Így nem csoda. bármikor elérhetővé válik. új lehetőségeket. kik vagyunk. azzal a gondolattal. Az a telefon lehet Windows Phone. de nagyon pontos specifikációt írt elő a telefon hardveres képességeit illetően. A Windows Phone különlegessége. digitális identitásunk egyfajta kiterjesztéseként gondolunk rájuk. de a Windows Phone újabb ilyen lehetőséget jelent! A Microsoft. Sajnos az idő előrehaladtával egyre nehezebb sikertörténeteket írni. A gyakorlott fejlesztők ezeket a sorokat olvasva biztosan felhördülnek és elgondolkodnak. Habár saját eszközt nem dobott a piacra. hogy az asztali Windows-t vihetjük a zsebünkben. É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. sokszor kényszerülnek olyan döntéseket hozni. Az új igényeknek. mit szeretünk csinálni és kivel. új igényekhez igazítva tervezték. hogy bizonyos kategória alatt nem támogatnak telefonokat. a Windows Phone-nal jelent meg a piacon.1. 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 világot helyezik kezünkbe. és újabb lehetőségeket kínál. 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. Az elmúlt években számos mesébe illő sikertörténetet hallhattunk olyan cégekről. mikor hol kellene lennünk. a Facebook. a konkurrens termékekkel nem volt képes felvenni a versenyt. 1-2 év alatt meghatározó szereplőkké nőtték ki magukat. Sokszor társként. amely évről évre csak nő. A Microsoft egyike volt az elsőknek az okostelefonok piacán. és alapjaiban új operációs rendszerrel. kik a barátaink. bármi. 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.

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.) 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. illetve XNA. Műholdas navigáció tekintetében Assisted-GPS támogatás szükséges. Kereső gomb: Minden esetben a beépített Bing keresőt hozza fel. Marketplace portál szolgáltatások 4. A készüléknek hálózati kommunikáció tekintetében mobil adathálózatok kezelését. döntésének és egyéb pozícióinak követésére gyorsulásmérőt kell beépíteni. Az alkalmazások ennek köszönhetően nem férhetnek hozzá kontrollálatlanul tetszőleges erőforráshoz. Kezdő oldal gomb (Home): A Start képenyőre navigál bárhonnan. 7. Vissza gomb (Back): Az alkalmazáson belüli navigációt. Iránytű Giroszkóp (jóval pontosabb pozíció/állapot meghatározásra képes. ún. (A gyártók döntő többsége 512MB-ot tesz a készülékeibe.1-ben ez a viselkedés nem módosítható. Futtatókörnyezet 2. Hálózati jellemzők:   Memória:     Navigáció:  Mozgásérzékelés: A telefon mozgásának. 16 . Integráció a felhővel 3. sandboxban („homokozó”) futnak.1. Operatív memória tekintetében legalább 256 MB memóriával kell rendelkeznie a készüléknek.     Kijelző:    A kijelzőnek legalább 800 x 480-as felbontással kell rendelkeznie. 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. 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. bármely alkalmazásból. Fejlesztőeszközök Futtatókörnyezet A Windows Phone alkalmazások izoláltan. amelyek szorosan kapcsolódnak az operációs rendszer és a navigációs mechanizmus működéséhez. valamint Wi-Fi-t kell támogatnia. illetve futó taszkok közötti váltást szolgálja. A kijelzőnek támogatnia kell a kapacitív technológiát és minimum 4 pontos érintést meg kell tudnia különböztetni.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

dőlt. 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. illetve a szokásos (félkövér. 55 . a Windows Phone Application sablon rögtön két TextBlockot is beépít alkalmazásunk felületébe. bonyolultabban formázott megjelenítésre pedig a RichTextBoxot.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. a betűk méretét. 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). Egyszerű szövegmegjelenítés a TextBlockkal Ahogy korábban láttuk. Egyebek között átállíthatjuk a betűtípust. 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.

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

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

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

3-31 ábra A TextBox tulajdonságainak beállítása a Properties panelen 59 . A MaxLength tulajdonsággal megszabhatjuk. a MaxLength csak a felhasználói adatbevitelt szabályozza. 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). hogy legfeljebb hány karaktert írhasson be a felhasználó a szövegdobozba. A TextBoxot. 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.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. 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. 3-30 ábra – A TextBox helye a szövegvezérlők között.

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

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

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

hogy hányadik elem legyen alapértelmezetten kijelölve. 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ó.) 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. hogy a TextBoxba írt szövegeket a gomb megnyomásával a ListBoxhoz rendeli. végletekig egyszerűsített tennivaló-listát valósítjuk meg. (3-38 ábra) 63 . nincs kijelölt elem. hogy több elem is kijelölhető legyen-e. A SelectedIndex segítségével állíthatjuk be. a SelectionMode-dal pedig megadhatjuk.Alapvető WP7 vezérlők 3-36 ábra: A ListBox kiválasztása a Toolboxról A működés megértéséhez a 3-37 ábrán látható. a -1 azt jelenti. Mindössze annyit tud.

Az egyes elemek sorrendjét az ablak alján lévő nyilakkal változtathatjuk meg. Alkalmazásfejlesztés Windows Phone-on 3-38 ábra: A ListBox tulajdonságainak beállítása a Properties panelen Ha az Items melletti „…” gombra kattintunk. illetve az „X” gombbal törölhetünk egy elemet (3-39 ábra). Egy stringet hozzáadva (az mscorlib|Systemben találjuk) a szerkesztőablak jobb oldalán megjelenik a karakterlánc. melyben szerkeszthetjük a ListBox tartalmát. 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 .3. Az „Add another item” gombra kattintva kiválaszthatjuk a ListBoxhoz hozzáadni kívánt elem típusát. amit átírhatunk. az Object Collection Editor ablak jelenik meg.

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

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

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

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

de ha sok tulajdonságot szeretnénk egyazon objektumról megjeleníteni. nem lehetne egy kicsit központosítani az adatkötést? Természetesen lehet.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). és létrejön az adatkötés (3-50 ábra). 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. szép. 3-49 ábra: Az új adatforrás tulajdonságai a Data panelen 3-50 ábra: Az adatforrás részeinek adatkötése drag-and-drop módszerrel Szép.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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. azokon belül pedig a Panorama és Pivot vezérlőket. 111 .Ö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. 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. az egyszerű címkereséssel és az útvonaltervezéssel. Ezekkel a módszerekkel nemcsak hogy rendkívül egyszerűen valósíthatunk meg komplex alkalmazásokat. Végül a Silverlight Toolkit előnyeit ismerhettük meg.

.

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Kamera használata taszk nélkül

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

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

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

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

153

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

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

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

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

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

154

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

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

155

6. Alapvető telefonos funkciók használata

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

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

156

Kamera használata taszk nélkül

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

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

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

157

6. Alapvető telefonos funkciók használata

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

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

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

158

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

illetve láttuk a Mangóban újdonságként bevezetett hibrid renderelési rendszer működését és használatát is. 300 . Megismerkedtünk az XNA Framework alapvető használatával. Az utóbbira építve elkészítettük egy Snake játéknak az alapjait is. Játékok a Mango világában fejlesztésébe.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.

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

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

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

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

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

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

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

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

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

akkor indítsuk el az 310 . és kapcsoljuk ki a Frame rate számlálókat is! Ha ez megtörtént. hogy legalább egy 480x800-as képernyőkép legyen az alkalmazásunkról mellékelve. de a Windows Phone 7. 12-13 ábra: Screnshot készítése Nézzük meg használat közben! Indítsuk el az alkalmazást. de a legtöbbjük használata legtöbbször kényelmetlen. majd a nagyítási beállításokat (nagyító ikon) állítsuk 100%-ra. OneNote.12. é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.1 SDK-ja óta ez a funkció már az emulátor mellett is megtalálható (12-13 ábra). A neten persze találhatunk erre is jó néhány eszközt. 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. A méretnek pontosnak kell lennie.

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Sign up to vote on this title
UsefulNot useful