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

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

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

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

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

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

.

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

aláhúzott) betűformázási lehetőségeket is megkapjuk (3-21 ábra). Egyszerű szövegmegjelenítés a TextBlockkal Ahogy korábban láttuk. a Windows Phone Application sablon rögtön két TextBlockot is beépít alkalmazásunk felületébe. illetve a szokásos (félkövér. bonyolultabban formázott megjelenítésre pedig a RichTextBoxot. a betűk méretét. dőlt.Alapvető WP7 vezérlők 3-19 ábra: Parancsvezérlők a felületen Szövegmegjelenítési vezérlők Nagyon kevés olyan program van. 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. A Silverlightban erre elsősorban két vezérlőt használunk: egyszerű szövegmegjelenítésre a TextBlockot. 55 . amelynek nem kell szöveget megjelenítenie. Egyebek között átállíthatjuk a betűtípust. 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).

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

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

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

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

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

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

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

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

illetve az „X” gombbal törölhetünk egy elemet (3-39 ábra).3. 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. 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. amit átírhatunk. melyben szerkeszthetjük a ListBox tartalmát. Egy stringet hozzáadva (az mscorlib|Systemben találjuk) a szerkesztőablak jobb oldalán megjelenik a karakterlánc.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

beágyazásuk pedig a Background tulajdonság hozzáadásával történik (4-19 ábra): <controls:Panorama. Ilyeneket könnyen találunk az interneten. de számos ismétlődő feladat még így is ránk hárul. 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. így ennek kipróbálására most nem térünk ki. 105 . 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. Miután telepítettük a csomagot.Background> 4-19 ábra: Panorama egy háttérkép megadása után A táblázatban kiemelt különbségeken túl a Pivot használata teljesen megegyezik a Panorama vezérlőjével.codeplex.com. Ezek elvégzését könnyíti meg a Silverlight Toolkit. az elérhető a Visual Studio Add Reference dialógusából (4-20 ábra).Silverlight Toolkit for Windows Phone7 </controls:PanoramaItem> <!--Panorama item two--> <controls:PanoramaItem Header="item2"> <Grid/> </controls:PanoramaItem> </controls:Panorama> </Grid> A dolog látványossá tételéhez csupán egy széles háttérkép hiányzik.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.jpg" /> </controls:Panorama.

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

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.Expander> <toolkit:ExpanderView. elem" /> <toolkit:MultiselectItem Content="3.Items> </toolkit:ExpanderView> 107 . elem" /> <toolkit:MultiselectItem Content="2. amelynek egy elemét kiválasztva az lenyílik.Items> <TextBlock Text="Alelem 1" /> <TextBlock Text="Alelem 2" /> </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. és a részletei is láthatóvá válnak (4-23 ábra).

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

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

Row="1" Margin="12.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.ContextMenu> </toolkit:HubTile> <toolkit:HubTile Name="hirekTile" Tap="hirekTile_Tap" Title="Hírek" Source="Images/news.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. 110 .png" Margin="6" Background="#A500FF" GroupTag="TileGroup" Notification="Noti" Message="Microsoft Minősített Szerviz Partner project"> </toolkit:HubTile> </toolkit:WrapPanel> </Grid> A fenti kód pedig (természetesen a képek Images mappába másolása után) a 4-27 ábrán látható megjelenést eredményezi.place additional content here--> <toolkit:WrapPanel x:Name="ContentPanel" Grid.0. Haladó alkalmazásfejlesztés Windows Phone-on </StackPanel> <!--ContentPanel .png" Margin="6" Background="#FF008000" GroupTag="TileGroup" Notification="Noti" Message="Microsoft Minősített Szerviz Partner project"> <toolkit:ContextMenuService.0"> <toolkit:HubTile Tap="hirekTile_Tap" Title="Minden" Source="Images/all.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.4.ContextMenu> <toolkit:ContextMenu> <toolkit:MenuItem Header="Menü 1" Click="MenuItem_Click" /> </toolkit:ContextMenu> </toolkit:ContextMenuService.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.

Végül a Silverlight Toolkit előnyeit ismerhettük meg.Összefoglalás 4-27 ábra: HubTile-ok WrapPanelbe csomagolva Összefoglalás A fejezet elején részletesen megismerkedhettünk a Bing Maps szolgáltatás felhasználási lehetőségeivel. azokon belül pedig a Panorama és Pivot vezérlőket. Ezekkel a módszerekkel nemcsak hogy rendkívül egyszerűen valósíthatunk meg komplex alkalmazásokat. 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. az egyszerű címkereséssel és az útvonaltervezéssel. Ezt követően átnéztük a tartalmak rendszerezésére szolgáló műveleteket: az oldalak kezelését. ezek között a kiemelt pozíciók jelölésével. 111 .

.

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

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

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

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

115

5. Az alkalmazás életciklusa

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

116

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

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

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

117

5. Az alkalmazás életciklusa

Esemény Launching Activated Deactivated Closing OnNavigatedFrom OnNavigatedTo

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

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

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

118

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

  

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

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

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

119

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

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

120

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

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

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

121

5. Az alkalmazás életciklusa

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

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

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

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

122

Állapotok kezelése

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

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

123

5. Az alkalmazás életciklusa

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

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

124

Folyamatok a háttérben

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

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

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

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

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

125

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

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

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

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

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

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

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

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

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

minden feladatnak speciálisan a hozzá illeszkedő feladat kategóriába kell kerülnie. 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. ahol a megfelelő objektumok végrehajtják az általunk megvalósított feladatok logikáját. 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. amelyre eddig csak nagyon nehézkesen vagy esetleg egyáltalán nem találhattunk megoldást. 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 . melyek az alkalmazást segítik beilleszkedni a Windows Phone életciklus modelljébe. és arról gondoskodnak.Összefoglalás Összefoglalás A fejezetben láthattuk.

.

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

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

hogy ezt a forrást a tervező eszközök meg is jelenítsék. logika.xaml állománya. megjelenítési felületek által elvárt formában tárolják az egyéb adatforrásból származó információt. mivel példát mutat arra.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. é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.1-es verziót. hogyan tudjuk az MVVM modellnek megfelelően szervezni kódunkat. A ViewModels mappa fogja össze azokat az osztályokat. 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 . Ilyen adatforrás például a SampleData MainViewModelSampleData. ami XAML formátumban rögzít néhány tesztbejegyzést a tervezésidejű megjelenítéshez (a Blend és a Visual Studio design felülete is ezt használja). Ahhoz. 6-3 ábra: A sablon által generált projekt Ez a megközelítés a lehető legjobban elválasztja a különböző felelősségeket (adatszolgáltatás. megjelenítés). amelyek az egyes oldalak.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

É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. Az utóbbira építve elkészítettük egy Snake játéknak az alapjait 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. Játékok a Mango világában fejlesztésébe. melyet az Olvasó tetszése szerint tovább bővíthet. 300 . Megismerkedtünk az XNA Framework alapvető használatával.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ha a diagramon kijelöljük a 3-as és 4-es képkocka közötti területet. Visszatérve a képkockákra (13-17 ábra). A jelenség oka. 342 .13.CPU Usage . hogy az első szöveg kirajzolásánál a környezetnek még a TextBox osztályt is be kellett töltenie és értelmezni. majd a Performance Warnings . Talán meglepő lehet. Teljesítmény 13-19 ábra: A 4. közel 6 másodpercig? Erre a kérdésre a választ úgy kaphatjuk meg. 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). Ennyire lassan rajzolna szöveget a futtatókörnyezet? A PageTitle viszont csak 5 ms. éles szeműek észrevehették. hogy az ApplicationTitle TextBox kezelése egy tized másodpercbe került. hogy melyik elemmel mennyit foglalkozott a telefon. Mi történt vajon a 3-as kocka vége és a 4-es eleje között. csak magára az elrendezésre és a rajzolásra. 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.

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

Sign up to vote on this title
UsefulNot useful