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

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

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

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

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

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

.

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Egyebek között átállíthatjuk a betűtípust. illetve a szokásos (félkövér. Vegyük szemre a PageTitle nevűt! A TextBlock által megjelenített szöveget a Text tulajdonság segítségével adhatjuk meg (3-20 ábra). a betűk méretét. 55 . 3-20 ábra: A TextBlock szövegének beállítása A Text csoportban található tulajdonságok segítségével szabhatjuk testre a szöveg kinézetét.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 Windows Phone Application sablon rögtön két TextBlockot is beépít alkalmazásunk felületébe. amelynek nem kell szöveget megjelenítenie. dőlt. bonyolultabban formázott megjelenítésre pedig a RichTextBoxot. 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. Egyszerű szövegmegjelenítés a TextBlockkal Ahogy korábban láttuk.

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

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

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

hogy legfeljebb hány karaktert írhasson be a felhasználó a szövegdobozba. illetve kódból itt állíthatjuk be a szövegdoboz szövegét. a MaxLength csak a felhasználói adatbevitelt szabályozza. 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 TextBoxot. ahogy a két előző vezérlőnket is a szövegvezérlők csoportjában találjuk a Toolboxon (3-30 ábra). 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. a Toolboxon Nem meglepő módon a TextBox vezérlő Text tulajdonságán keresztül érhetjük el. A MaxLength tulajdonsággal megszabhatjuk. 3-31 ábra A TextBox tulajdonságainak beállítása a Properties panelen 59 . 3-30 ábra – A TextBox helye a szövegvezérlők között. Programozottan ennél többet is meg lehet adni.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

horizontálisan elnyúló vezérlő.Pivot és Panorama <local:NavigationBar VerticalAlignment="Bottom" /> Próbáljuk ki alkotásunkat úgy. 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). hogyan tudjuk alkalmazásunkat oldalakkal strukturálni. majd a végén meglátogatjuk a navigációt összegző lapot. Szorosabban kapcsolódó adatok megjelenítésére vagy egyszerűen látványosabb UI létrehozására is két remek vezérlő áll rendelkezésünkre. Mindkettő az ItemsControlból. 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. nem véletlen. hogy bejárjuk az összes oldalt. A WP7 programok kinézetének meghatározó formálói. törlünk párat. amelyeket ebben a részben ismerhetünk meg. A Pivot és a Panorama két nagyon hasonló. 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 .

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

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

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

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

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

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

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

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

.

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

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

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

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

amiket szeretnénk majd lejátszani! Jelöljük ki a zenefájlokat.0" VerticalAlignment="Top"> <Button Content="prev" x:Name="prevButton" Height="140" Width="140" Click="prevButton_Click"/> <Button Content="play" x:Name="playButton" Height="140" Width="140" Click="playButton_Click"/> <Button Content="next" x:Name="nextButton" Height="140" Width="140" Click="nextButton_Click"/> </StackPanel> <TextBlock x:Name="txtCurrentTrack" Height="75" HorizontalAlignment="Left" Margin="12.cs fájlban helyezzük el az alábbi metódust. így Zune-on keresztül a telefonra másolt zenéket ne is próbáljuk meg elérni! Az App.40.18. 5-6. ábrán látható.193.0" VerticalAlignment="Top" Width="438" TextWrapping="Wrap" /> </Grid> Hozzunk létre egy új mappát és másoljuk bele az MP3 fájlokat. 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. a Zune gyűjteményünkhöz nincs hozzáférése.xaml. 127 . ehhez hasonló eredményt kell kapnunk. Fontos megemlíteni. é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.0.Folyamatok a háttérben <StackPanel Orientation="Horizontal" Width="420" Margin="18. 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.

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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. Az Application Details alatt megadott képeket is itt teszteljük. 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. akkor a teszt megmondja.xml fájlban.12. A teszt közben a program által felkínált lehető legtöbb felhasználói esetet hajtsuk végre az alkalmazáson! 312 . 12-16 ábra: Automated Tests (Marketplace Test Kit) Monitored Tests Ezen a fülön (12-17 ábra) mérhetjük meg az alkalmazásunk teljesítményét és válaszképességét. A teszt során az alkalmazást egy fizikai készüléken kell kipróbálnunk. 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.

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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