windows 8 kódgyűjtemény
TRANSCRIPT
WINDOWS 8
KÓDGYŰJTEMÉNY
Turóczy Attila
Livesoft Kft.
2012.03.01.
Készült a Microsoft Magyarország
megbízásából
Tartalomjegyzék
Előszó ............................................................................................................................................................................ 5
Fájlkezelés engedélyezése ..................................................................................................................................... 6
Fájlkezelés .................................................................................................................................................................... 7
Fájlműveletek ............................................................................................................................................................. 9
Mappák és fájlok listázása ................................................................................................................................... 10
Fájlinformációk ........................................................................................................................................................ 11
File Picker ................................................................................................................................................................... 13
Contact Picker .......................................................................................................................................................... 15
Fénykép készítése ................................................................................................................................................... 16
Video készítése ........................................................................................................................................................ 18
Kamera előnézeti képe ......................................................................................................................................... 19
Kamera beállítások ................................................................................................................................................. 20
Application Bar ........................................................................................................................................................ 21
Navigation Bar ......................................................................................................................................................... 23
Orientáció .................................................................................................................................................................. 24
Geolokáció ................................................................................................................................................................ 25
Bing Maps – regisztráció ...................................................................................................................................... 26
Bing Maps API használata ................................................................................................................................... 28
MessageDialog avagy a MessageBox utódja ............................................................................................... 30
HttpClient .................................................................................................................................................................. 33
WebView .................................................................................................................................................................... 34
Helyi menü – ContextMenu ................................................................................................................................ 35
Vágólap – Clipboard .............................................................................................................................................. 36
Megosztás – Share ................................................................................................................................................. 38
Keresés – Search Contract ................................................................................................................................... 39
Keresési lehetőségek felajánlása ....................................................................................................................... 41
Charm Bar – Search megjelenítése .................................................................................................................. 43
Fájlok keresés ........................................................................................................................................................... 44
Content betöltése – ms-appx ............................................................................................................................ 45
Felhasználói információk ..................................................................................................................................... 46
Adatkötés ................................................................................................................................................................... 47
Stílusok ....................................................................................................................................................................... 48
Erőforrások ................................................................................................................................................................ 49
Próbaváltozatú alkalmazás készítése .............................................................................................................. 50
Alkalmazáson belüli vásárlás .............................................................................................................................. 51
Előszó
Amikor valaki a kezébe (vagy a monitorára) veszi ezt a könyvet, rögtön szembetűnik, hogy
ez nem szokványos szakmai könyv hosszas leírásokkal, és általános kijelentésekkel.
2012 tavaszán írtam meg a Windows Phone 7 kódgyűjteményt, amit több mint 4000 fejlesztő
töltötte le. Ez szép szám annak függvényében, hogy Magyarország szűk piac és elég kevés
fejlesztő van itthon. Az előző sikerén felbuzdulva írtam meg ezt a kódgyűjteményt is. Ebben
a kódgyűjteményben a Windows 8 fejlesztésének leglényegesebb területeit mutatom be.
Minden témakörre maximum kettő oldalt szántam, de megpróbáltam minden témakört egy
oldalba bezsúfolni. A témakörök nincsenek teljesen kifejtve, de nem is ez a cél. A cél az, hogy
egy-egy funkciót mutassak be a lehető legrövidebb módon.
A fejezetek nem kapcsolódnak szervesen egymáshoz, ahol mégis, ott jelölve van, így
tetszőleges sorrendben haladhatunk, nem fontos az általam összeállított sorrendet követni.
Ebben a könyvben nem megyünk bele mélyen az egyes témákba, hanem példákon keresztül,
a gyakorlatban segítünk elsajátítani a tudásanyagot. Ha e témák elméleti része komolyabban
is érdekel, akkor minden kellő információt megtalálsz a „Windows 8 Fejlesztés lépésről
lépésre” című könyvben. Ez a jegyzet egyfajta kiegészítése az előbb említett könyvnek,
melyek együttes használatával mind elméleti, mind gyakorlati tudásodat fejlesztheted.
Remélem, hasznosnak találod majd, és segít mindenben, amire szükséged lesz a fejlesztés
során.
Turóczy Attila
Budapest, 2012. november
Fájlkezelés engedélyezése
A Windows Store alkalmazásoknál nincs meg ugyan az a lehetőség, mint a korábbi
alkalmazásainknál, hogy szabadon elérjük a fájlrendszert. Ha el is akarjuk érni, akkor azt előre
jeleznünk kell, és fel kell tüntetnünk, hogy a mi általunk készített alkalmazás elfogja érni a
fájlrendszert. Ráadásul nem a teljes fájlrendszert érhetjük el, hanem csak speciális
könyvtárakat.
Nézzük meg először, hogyan is engedélyezzük ezt: A Solution Explorer-ben kattintsunk a
Package.appxmanifest fájlra. A Capabilities fülön pipáljuk be, hogy
melyik könyvtárhoz szeretnénk hozzáférést.
A következő lehetőségek állnak a rendelkezésünkre:
Document Library
Music Library
Pictures Library
Videos Library
Vannak még speciális eszközök is.
A példa kedvéért most a Document Library-t pipáljuk be. Ekkor a Capabilities tabfülön egy
figyelmeztetés jelenik meg, ugyanis meg kell mondanunk, hogy milyen fájl kiterjesztést
fogunk használni, azaz az alkalmazásunk milyen fájlokhoz tud hozzáférni (asszociálni).
Kattintsunk Declataions tabfülre. Az Available Declatations elemek közül válasszuk ki a File
Type Associations-t, majd kattintsunk az Add gombra. A megjelenő beállításoknál most az
egyszerűség kedvéért csak a File type-ot, illetve a name tulajdonságot határozzuk meg. A
name legyen text, míg a File type pedig .txt.
Most már írhatunk és olvashatunk is fájlokat a dokumentumok mappán belül!
Fájlkezelés
Ha fájlt akarunk kezelni, ne felejtsük el mindig ezt jelezni az alkalmazásunk számára! Ennek
lépéseit az előző Fájlkezelés engedélyezése című cikkben leírtuk.
Nézzünk egy egyszerű példát a fájlkezelésre. Ahhoz, hogy fájlokat kezeljünk, szükségünk lesz
a Windows.Storage névtérre!
using Windows.Storage;
Mint szinte minden Windows Store API-nál, a fájlkezelés is aszinkron műveleteket tartalmaz.
Így gyakran fogjuk látni az async és await kulcsszavakat.
Készítsünk egy üres fájlt a dokumentumaink közé.
private async void CreatFileButton(object sender, RoutedEventArgs e) { StorageFolder folder = KnownFolders.DocumentsLibrary; await folder.CreateFileAsync("Me.txt", CreationCollisionOption.ReplaceExisting); }
Ahhoz, hogy fájlt készítsünk, szükségünk lesz egy cél helyre. Ez jelen esetben a Documents
könyvtár! 1A fájl létrehozáshoz, a StorageFolder példány CreateFileAsync metódusát hívjuk
meg. Itt mindösszesen csak a fájl nevét és annak viselkedését kell megadnunk. Itt megadjuk,
hogyan reagáljunk arra, hogy ha a fájl már létezik. Ebben az esetben mi most felülírjuk. A
CreationCollisionOption egy enumeráció! Figyeljük meg a lehetséges értékeit! A
CreateFileAsync visszatérési értéke egy StorageFile példány. Későbbiekben ezt fogjuk
használni!
1 Ne feledjük! A cél könyvtár akkár a Music, Pictures vagy Video könyvtár is lehet. Ezt a Capabilites alatt definiálhatjuk!
Fájlok írás és olvasása nagyon hasonló analógiával történik. A fájlkezelés tekintetében ilyen
téren nagyon egyszerű és egyben jól használható API-t kapunk, ráadásul minden fontosabb
metódus alapból aszinkron.
Kezdjük a file írással. Ehhez a Windows.Storage.FileIO osztályt fogjuk használni.
StorageFile myFile = await folder.CreateFileAsync("Me.txt", CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(myFile, "Teszt adat");
A FileIO osztálynak a következő írással kapcsolatos metódusai vannak: WriteBufferAsync,
WriteBytesAsync, WriteLinesAsync, WriteTextAsync. Válasszuk mindig a számunkra
legmegfelelőbbet! Ha már meglévő fájlhoz szeretnénk adatot fűzni, azt az AppendLinesAsync
vagy az AppendTextAsync segítségével tudjuk megtenni.
A fájlok olvasása ugyan ezen az analógián alapszik. Itt Read*-el kezdődő metódusok kellenek
majd a számunkra. (ReadBufferAsnyc, ReadLinesAsync, ReadTextAsync)
string fileContent = await FileIO.ReadTextAsync(myFile);
Ne felejtsük el, hogy fájlírás és olvasás közben is kaphatunk hibákat!
Fájlműveletek
Nézzünk, néhány egyszerű fájlműveletet. Ezeket mind a StorageFile példányon keresztül
tudjuk elvégezni. Természetesen ezek a műveletek is aszinkron műveletek.
Kezdjük a fájl másolással! Egy adott fájl másoláshoz a StorageFile CopyAsync metódusát kell
meghívnunk. Paraméteréül a cél mappát kell megadnunk, a fájl új nevét, és már fájl létezés
esetén ennek a viselkedését.
StorageFile newFile = await myFile.CopyAsync(KnownFolders.DocumentsLibrary, "newFile.txt", NameCollisionOption.ReplaceExisting);
Természetesen van lehetőség áthelyezésre is ehhez a MoveAsync metódust kell meghívnunk.
A fájl törlése ugyanilyen egyszerű, itt a DeleteAsync metódust kell használnunk.
await myFile.DeleteAsync();
Mint láthatjuk, a fontosabb fájl műveletek a rendelkezésünkre állnak, és elég egyszerűen.
Mappák és fájlok listázása
A következő példában a Video Library fájljait fogjuk kilistázni. Arra is van lehetőségünk, hogy
az alkalmazásunkon belül lekérjük, hogy az adott Library-ban vagy mappában milyen fájlok és
mappák vannak. Ehhez természetesen ne felejtsük el engedélyezni, hogy az adott alkalmazás
el fogja érni a video library-t. Ezt a Capabilities alatt tehetjük meg.
Fájlok lekérdezéshez a StorageFolder GetFilesAsync metódusát kell meghívnunk. Ennek a
visszatérési értéke egy olyan Read Only lista ami StorageFile-okat tartalmaz.
StorageFolder videosFolder = KnownFolders.VideosLibrary; IReadOnlyList<StorageFile> files = await videosFolder.GetFilesAsync();
Mappák lekérdezése hasonlóan történik. Ehhez a GetFolderAsync metódust kell meghívnunk
ami egy olyan Read Only listát ad vissza ami StorageFoldereket tartalmaz.
IReadOnlyList<StorageFolder> folders = await videosFolder.GetFoldersAsync();
Ezen eredmények felhasználása már a mi dolgunk. Egyszerűen egy forech ciklussal
kiírathatjuk a tartalmukat, vagy a kreativitásunknak megfelelően használjuk fel.
Fájlinformációk
Nézzük meg, hogy fájlinformációkat, hogyan kérdezhetünk le. Ehhez először egy
StringBuilder-t készítünk. Ebbe tároljuk el a tulajdonságok eredményét. A StringBuilder a
System.Text névtérben található.
using System.Text; ... StringBuilder outputText = new StringBuilder();
Ha fájlokról akarunk információkat megtudni, akkor egyszerűen lekérdezhetünk alap
információkat úgy, hogy StorageFile tulajdonságait kiiratjuk. Itt viszonylag kevés információ
áll a rendelkezésünkre. Például: fájl név, típus, contentType stb.
outputText.AppendLine("Fájl neve: " + myFile.Name); outputText.AppendLine("Fájl típusa: " + myFile.FileType);
Ha valamivel specializáltabb információkra vágyunk, akkor a StorageFile példány
GetBasicPropertiesAsync metódusát kell meghívnunk. Ez a metódus egy BasicProperties
példányt ad vissza, amivel egyszerű tulajdonságok segítségével lekérdezhetjük a megfelelő
információkat.
BasicProperties basicProp = await myFile.GetBasicPropertiesAsync(); outputText.AppendLine("Fájl mérete: " + basicProp.Size + " bytes"); outputText.AppendLine("Módosítás dátuma: " + basicProp.DateModified);
A BasicProperties objektum a Windows.Storage.FileProperties névtérben található, ezt töltsük
be!
using Windows.Storage.FileProperties;
Ez még mindig nem nyújt speciális információkat a számunkra. Ha tényleg „mindent”
szeretnénk tudni egy-egy fájlról, akkor a StorageFile.Properties.RetrievePropertiesAsync
metódusát kell meghívnunk. A visszatérési érték egy IDictionary<string, object> példány,
majd lekérdezhetjük az adott kulcs értékét.
List<string> propNames = new List<string>(); propNames.Add("System.DateAccessed"); propNames.Add("System.FileOwner"); IDictionary<string, object> extraProp = await myFile.Properties.RetrievePropertiesAsync(propNames); var propValue = extraProp["System.DateAccessed"]; if (propValue != null) { outputText.AppendLine("Utolsó hozzáférés: " + propValue); } propValue = extraProp["System.FileOwner"]; if (propValue != null) { outputText.AppendLine("Tulajdonos: " + propValue); }
Ebben az esetben, olyan speciális információkat is letudunk kérdezni, mint a fájl
tulajdonosának neve, vagy az utolsó hozzáférésnek dátuma. Persze ehhez tudnunk kell, hogy
mit keresünk. Mint láthatjuk, ezt mi egy string segítségével tesszük meg.
Az eredmény most valami hasonló lesz:
Fájl neve: Me.txt
Fájl típusa: .txt
Fájl mérete: 10 bytes
Módosítás dátuma: 10/30/2012 8:39:42 PM +01:00
Utolsó hozzáférés: 10/30/2012 8:39:42 PM +01:00
Tulajdonos: CORIANE\Attila
File Picker
Windows-os alkalmazásainknál gyakran voltak dialógusok. Open File Dialog vagy Save File
Dialog. Ez a Windows Store alkalmazásoknál nincs, illetve nem ilyen módon, mint amilyen
korábban volt. Az alábbi ábrán egy régebbi típusú Windows Open File Dialogust látunk.
Windows Store alkalmazásoknál is van lehetőség, csak a vizuális reprezentációja hozzá
idomúl a környezetéhez. Ennek a használatához szükségünk lesz a Windows.Storage és a
Windows.Storage.Pickers névtérre.
using Windows.Storage; using Windows.Storage.Pickers;
Ha egy fájlt meg akarunk nyítni akkor a FileOpenPicker példányra lesz szükségünk. A
FileOpenPicker-nek van egy ViewMode tulajdonsága, amivel beállítható, hogy a megjelenő
fájlok Thumbnail (előnézeti kép) vagy Lista formájában jelenjenek meg. A FileOpenPicker
FileTypeFilter gyűjteményéhez hozzáadhatjuk azokat a kiterjesztéseket, amik az
alkalmazásunk számára lényeges. Ha csak egy fájlt akarunk kiválasztani és megnyitni, akkor a
PickSingleFileAsync metódusra lesz szükségünk. Ennek a visszatérési értéke most egy darab
StorageFile lesz.
FileOpenPicker fileOpenPicker = new FileOpenPicker(); fileOpenPicker.ViewMode = PickerViewMode.List; fileOpenPicker.FileTypeFilter.Add(".png"); StorageFile file = await fileOpenPicker.PickSingleFileAsync(); txtInfo.Text = file.Name;
Ha több fájlt szeretnénk kiválasztani, ehhez a PickMultipleFilesAsync metódust kell
használnunk. Ennek visszatérési értéke egy IReadOnlyList ami StorageFile-okat tartalmaz. Az
alábbi példa ennek felhasználását mutatja be.
IReadOnlyList<StorageFile> files = await fileOpenPicker.PickMultipleFilesAsync(); StringBuilder fileNames = new StringBuilder(); foreach (StorageFile file in files) { fileNames.AppendLine(file.Name); }
Ha menteni szeretnénk, akkor a FileSavePicker osztályra lesz szükségünk. Itt az egyik
legfontosabb gyűjtemény a FileTypeChoices, amelyhez hozzáadhatjuk, hogy milyen fájl
formátumban szeretnénk menteni a fájlt. Ebben az esetben is a PickSaveFileAsync metódusra
lesz szükségünk, aminek a visszatérési értéke egy StorageFile.
FileSavePicker fileSavePicker = new FileSavePicker(); fileSavePicker.FileTypeChoices.Add("PNG", new string[] { ".png" }); StorageFile file = await fileSavePicker.PickSaveFileAsync();
A felhasználói felület picit módosul, az FileOpenPicker-hez képest, ugyanis a képernyő alján
az alábbi felület lesz a segítségünkre, hogy megadjuk a fájl nevét és típusát.
Contact Picker
A Windows 8-ban integrálhatjuk a közösségi hálózataink kapcsolatait. Ezeket a kapcsolat
adatokat akár a mi is lekérdezhetjük az alkalmazásunkból. Ehhez a
Windows.ApplicationModel.Contacts névteret kell használnunk.
using Windows.ApplicationModel.Contacts;
A ContactPicker osztályra lesz szükségünk a kapcsolatok kiválasztásához. Egy vagy több
kapcsolat adatot is kiválaszthatunk. A PickSingleContactAsync metódussal egy kapcsolatot
választhatunk ki, míg a PickMultipleContactsAsync metódus segítségével több kapcsolati
elemet választhatunk ki a listából.
Az alábbi példában egy darab contactot választunk ki, és a kiválasztott contact nevét kiírjuk
egy szövegmezőbe, amelynek neve most a tbName.
ContactPicker contactPicker = new ContactPicker(); ContactInformation selectedContact = await contactPicker.PickSingleContactAsync(); tbName.Text = selectedContact.Name;
Ha több contactot szeretnénk kiválasztni, akkor a PickMultipleContactsAsync metódust kell
meghívnunk, melynek visszatérési értéke egy Read Only lista, amely ContactInformation-ket
tartalmaz.
ContactPicker contactPicker = new ContactPicker(); IReadOnlyList<ContactInformation> selectedContact = await contactPicker.PickMultipleContactsAsync(); foreach (ContactInformation contact in selectedContact) { }
Fénykép készítése
Alkamazásunkból egyszerűen tudunk fényképet készíteni. Ehhez is
egy jól specifikált egyszerű API áll a rendelkezésre. Természetesen
mivel ez is egy speciális erőforrás, ezt is külön jeleznünk kell az
alkalmazásunk számára, hogy használni szeretnénk.
A felhasználói felületre dobjunk fel egy image és button vezérlőt2. Az
image vezérlő neve legyen az imgPhotot. A gomb vezérlő neve
legyen a btnTakePhoto.
Kattintsunk a Solution Explorer-ben található Package.appxmanifest fájlra. A megejelenő
ablakban kattintsunk a Capabilities fülre és pipáljuk be, hogy az alkalmazásunk a
webcamera erőforrást használni fogja!
Most már elérhetjük a kamerát. Kattintsunk kétszer a btnTakePhoto-ra, ekkor a gomb klikk
eseményének fejléce elkészül. Mielőtt a törzsét megírnánk szükségünk lesz a következő
névterekre:
using Windows.Media.Capture; using Windows.Storage; using Windows.Storage.Streams; using Windows.UI.Xaml.Media.Imaging;
A gomb esemény törzsébe pedig írjuk a következőket:
private async void btnTakePhoto_Click(object sender, RoutedEventArgs e) { CameraCaptureUI dialog = new CameraCaptureUI(); Size ratio = new Size(16, 9); dialog.PhotoSettings.CroppedAspectRatio = ratio; StorageFile file = await dialog.CaptureFileAsync(CameraCaptureUIMode.Photo); BitmapImage bmp = new BitmapImage(); using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read)) { bmp.SetSource(fileStream); } imgCamera.Source = bmp; }
Példányosítunk egy CameraCaptureUI-t. Majd a PhotoSettings CroppedAspectRatio
tulajdonságnak egy képernyő méretet adunk át. (Size objektum)
2 Az ehhez hasonló vezérlőket célszerű az Application Bar-on elhelyezni! Most az egyszerűség kedvéért maradjon a tartalom területen.
Ezt követően meghívjuk a CaptureFileAsync metódust, melynek paramétere egy
CameraCaptureUIMode enumeráció. Ez az enumeráció nagyon fontos, hiszen itt mondjuk
meg, hogy kép vagy video készüljön.
Amikor az alkalmazást elindítjuk és rákattintunk a Photo gombra, a következő képernyő
fogadja a felhasználót.
Itt az alkalmazás megkérdezi a felhasználótól, hogy engedélyezi-e az adott alkalmazás
számára, hogy használja a webkamerát. Amennyiben a felhasználó az Allow gombra
kattintunk, akkor egy beépített kamera ablakot fogjuk látni, ahol elkészíthetjük a fotót. Itt a
kamera tulajdonságaihoz mérten beállítások is rendelkezésünkre állnak. Néhány kameránál
több, másnál kevesebb tulajdonságot tudunk állítani.
Az eredmény pedig most egy kép lett, amit az alkalmazásunkban meg is jelenítünk.
Video készítése
Természetesen nem csak fényképet, hanem akár videót is
készíthetünk. Ehhez ugyanazt a CameraCaptureUI osztályt kell
használnunk, mint amit korábban a fénykép készítésénél
használtunk. Arra viszont figyeljünk, hogy a Capabilities alatt
nemcsak a Webcamera erőforrás legyen kiválasztva, hanem a
Microsophone is! Egy videó ugyanis hanganyagból is áll,
ezért szükségünk lesz a mikrofon erőforrásra is!
A felhasználói felületre dobjunk fel egy MediaElement
vezérlőt, melynek neve most mediaelement lesz. Ez a vezérlő
audio és video tartalmakat képes megjeleníteni. A felhasználó
felületen lesz még egy gomb, amivel elkészítjük a felvételt. A gomb klikk eseményébe írjuk a
következőt:
CameraCaptureUI dialog = new CameraCaptureUI(); dialog.VideoSettings.Format = CameraCaptureUIVideoFormat.Mp4; StorageFile file = await dialog.CaptureFileAsync(CameraCaptureUIMode.Video); IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read); medialement.SetSource(fileStream, "video/mp4")
Mint látható itt is a CameraCaptureUI-t használjuk, de ebben az esetben már nem a
PhotoSettings-et állítjuk be, hanem a VideoSettings-et. A példában most csak a formátumot
határozzuk meg. Jelenleg csak Mp4 vagy WMV formátumot támogatott. Ezt követően
ugyanúgy, mint a fénykép készítésnél a CaptureFileAsync metódust kell meghívnunk, csak
épp itt a CameraCaptureUIMode enumeráció video elemét kell átadnunk a Photo helyet.
Ennek a metódusnak a visszatérési értéke egy StorageFile, amit megnyítunk. Ezt a stream-et
átadjuk a mediaelement nevezetű vezérlőnek, és meghatározzuk a mime típusát.
Az eredménye pedig egy olyan alkalmazás, amivel videót tudunk készíteni és ezt követően a
videót le is tudjuk játszani.
Kamera előnézeti képe
Lehetőségünk van arra, hogy a kamerát ne külön kezeljük,
hanem már az alkalmazásunkon belül is lássuk az előnézeti
képét. Természetesen ehhez is szükségünk van Capabilities
módosítására. Ebben az esetben is a Webcamera és a
Microphone elemet kell kiválasztanunk és engedélyeznünk.
A felhasználói felületre dobjunk fel egy CaptureElement
vezérlőt, melynek neve most capElement. Mielőtt
megjelenítenénk egy előnézeti képet célszerű lekérdezni, hogy
van-e legalább egy video eszközünk. Ezt a statikus
DeviceInformation osztály FindAllAsync metódus segítségével
tudjuk lekérdezni. A FindAllAsync –nek egy DeviceClass.VideoCapture-t adunk át. Azaz csak
azokra az eszközökre vagyunk kiváncsiak, amelyek képesek videót felvenni. A FindAllAsync
metódus egy DeviceInformationCollection-nel tér vissza, amelyben az összes videórögzitésre
alkalmas eszköz jelen van. Ha ebben a gyűjteményben több mint egy eszköz van, akkor
képések vagyunk megjeleníteni egy video eszköz képét. Ehhez most a MediaCapture osztályt
fogjuk használni.
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture); if (devices.Count > 0) { MediaCapture mediaCaptureMgr = new MediaCapture(); await mediaCaptureMgr.InitializeAsync(); capElement.Source = mediaCaptureMgr; await mediaCaptureMgr.StartPreviewAsync(); }
Először példányosítjuk majd meghívjuk az InitializeAsync metódusát. Mint látható ez is
aszinkron metódus! Ezt a MediaCapture példányt átadjuk a CaptureElement-nek (amelynek a
neve capElement), majd meghívjuk a StartPreviewAsync aszinkron metódusát!
Az eredmény pedig egy olyan app, amely az alkalmazáson belül megjeleníteni a kamera
képét3.
3 Ennél többre is képesek vagyunk. De most csak megszerettük volna jeleníteni a kamera képét az alkalmazásunkban.
Kamera beállítások
Olykor szükségünk lehet a kamera beállításainak módosítására. Például ha kontrasztot vagy
fényerősséget szeretnénk állítani, erre is van egy beépített felületünk, amit meghívhatunk az
alkalmazásunkból.
FIGYELEM! Ez a feladat az előző Kamera előnézeti képe feladat folytatása!
Az előző cikkben megnéztük, hogyan lehet a kamera képét megjeleníteni a programunkban,
most a kamera beállításait jelenítjük meg. Ehhez egy MediaCapture példányra lesz
szükségünk, amit átadunk a CameraOptionsUI osztály Show metódusa számára.
if (mediaCaptureMgr != null) { CameraOptionsUI.Show(mediaCaptureMgr); }
Ekkor az alkalmazásunkon belül megjelenik a kamera beállításai pop-up ablak, ahol a kamera
specifikus tulajdonságait állíthatunk be. A beállítások és tulajdonságok a kamera
képességének függvényében változhatnak!
Application Bar
Az ApplicationBar az egyik legfontosabb Windows Store App vezérlő. Ugyanis ezen a
felületen helyezzük el alkalmazásunk fontosabb parancsait. Ha lehetséges, minden funkciót
ezen a felületen helyezzünk el. Bár lehetőségünk van a munkaterületen is gombokat és menü
elemeket elhelyezni, amik valamilyen funkciót végeznek el, de ha ez nem feltétlenül fontos,
próbáljuk meg ezeket a funkciókat az Applicationbar-on elhelyezni. Ez a menü a képernyő
alján jelenik meg, ha jobb egérgombbal kattintsunk vagy a megfelelő gesztikulációt végezzük
el. Nézzük, meg hogy hogy hozhatunk létre egy ilyen Applicationbar-t.
Nyissunk meg egy tetszőleges oldalt, és az elrendezés vezérlő (Grid) valamint a Page definíció
közé írjuk a következőt:
<Page.BottomAppBar> <AppBar> <StackPanel Orientation="Horizontal"> <Button Content="Edit" /> <Button Content="Save" /> <Button Content="Refresh"/> </StackPanel> </AppBar> </Page.BottomAppBar>
Ha most elindítanánk az alkalmazásunkat, akkor valami hasonló Application Bar jelenne meg,
ami ugyan használható, de ez nem az elvárt.
Ha olyan Applicationbar-t szeretnénk, mint amit már megszoktunk Windows Store
alkalmazásoknál akkor először nyissuk meg a Common mappa alatt található
StandardStyles.xaml fájlt. Itt már vannak ApplicationBar Button style-ok, de ezek ki vannak
kommentezve. Vegyük ki a kommenteket! Egy stílus hozzávetőleg így néz ki:
<Style x:Key="SkipBackAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}"> <Setter Property="AutomationProperties.AutomationId" Value="SkipBackAppBarButton"/> <Setter Property="AutomationProperties.Name" Value="Skip Back"/> <Setter Property="Content" Value=""/> </Style>
Miután a kommenteket eltávolítottuk, térjünk vissza az Applicationbar-unk definíciójához és
módosítsuk az alábbiak szerint:
<Page.BottomAppBar> <AppBar> <StackPanel Orientation="Horizontal"> <Button Style="{StaticResource EditAppBarButtonStyle}" /> <Button Style="{StaticResource SaveAppBarButtonStyle}" /> <Button Style="{StaticResource AddAppBarButtonStyle}" /> </StackPanel> </AppBar> </Page.BottomAppBar>
Figyeljük meg, hogy ebben az esetben a Content-et eltávolítottuk és csak a Style
tulajdonságot határoztuk meg. (Próbáljuk ki, mi történik akkor, ha a Content tulajdonságot is
megadjuk!)
Ezt követően már felhasználhatjuk az Application Bar elemeit. Mind Click eseménye, mind
Commands tulajdonságai is vannak a gomboknak, amikkel feliratkozhatunk az eseményekre.
Természetesen arra is van lehetőségünk, hogy saját stílust definiáljunk az Applicationbar-ban
megjelenő gombok és vezérlők számára!
Navigation Bar
A Navigation Bar (NavBar) tulajdonképpen egy olyan Application Bar ami a Windows Store
alkalmazásunk tetején jelenik meg. Több alaklmazásnál példáual “tabfül” váltásra használják.
Az új Remote Desktop-nál tipikusan asztalok közötti váltásra szolgál. Ez mellett használhatjuk
olyan Application Bar-nak is, ami az alkalmazás tetején jelenik meg.
Használata megegyezik az ApplicationBar-ral, csak itt nem BottomAppBar van, hanem
TopAppBar.
Nyissunk meg egy tetszőleges oldalt, és az elrendezés vezérlő (Grid) valamint a Page definició
közé írjuk a következőt:
Ha olyan Applicationbar-t szeretnénk, mint amit már megszoktunk Windows Store
alkalmazásoknál akkor először nyissuk meg a Common mappa alatt található
StandardStyles.xaml fájlt. Itt már vannak ApplicationBar Button style-ok, de ezek ki vannak
kommentezve. Távolítsuk el a kommenteket és ezt követően, használhatjuk ezeket a stílusokat
az alkalmazásunkban!
<Page.TopAppBar> <AppBar> <StackPanel Orientation="Horizontal"> <Button Style="{StaticResource SkipBackAppBarButtonStyle}" /> <Button Style="{StaticResource PlayAppBarButtonStyle}" /> <Button Style="{StaticResource SkipAheadAppBarButtonStyle}" /> </StackPanel> </AppBar> </Page.TopAppBar>
Orientáció
Főképp tabletes alkalmazásoknál fontos lehet, hogy a képernyő milyen helyzetben van. Ezt
természetesen le tudjuk kérdezni. Ehhez a Windows.Graphics.Display névtér lesz a
segítségünkre.
using Windows.Graphics.Display;
A DisplayProperties objektum CurrentOperation tulajdonsága segítségével lekérdezhetjük,
hogy jelenleg, milyen a képernyő helyzete. Lehetséges értékek: Landscape, Portrait,
Landscape-flipped, Portrait-flipped.
tbOrientation.Text = DisplayProperties.CurrentOrientation.ToString();
A DisplayProperties-nek van egy OrientationChanged eseménye, amire feliratkozva
értesülhetünk arról, ha a készüléket elforgattuk. Ebben a példában, most csak kiiratjuk egy
szövegmezőbe (melynek neve tbOrientation), hogy mi a jelenlegi pozíció.
public MainPage() { this.InitializeComponent(); DisplayProperties.OrientationChanged += DisplayProperties_OrientationChanged; } void DisplayProperties_OrientationChanged(object sender) { tbOrientation.Text = DisplayProperties.CurrentOrientation.ToString(); }
Ezt a funkciót fizikai gép megléte nélkül, célszerű a szimulátorban kipróbálni.
A Package.appxmanifest fájlban definiálhatjuk, hogy az alkalmazások milyen orientációkat
támogat.
Geolokáció
Lehetőségünk van arra, hogy az alkalmazásunk lekérdezze, hogy a felhasználó épp hol van.
Ehhez is egy rendkívűl egyszerű API-t biztosít számunkra a keretrendszer. Természetesen
mivel ez is egy erőforrás ezt külön engedélyeznünk kell!
A Solution Explorer-ben kattintsunk az Package.appxmanifest fájlra, a Capabilites fül alatt
a Location elemet pipáljuk ki! Ha ezt nem tesszük meg, hibát kapunk abban a pillanatban,
amikor ezt az erőforrást használatba szeretnénk venni.
A geololáció API eléréséhez a Windows.Devices.Geolocation névtér lesz a segítségünkre.
using Windows.Devices.Geolocation;
Példányosítanunk kell a Geolocator osztályt, majd meg kell hívnunk a GetGeopositionAsync()
metódusát. (Mint látható, ez is aszinkron metódus!) A GetGeopositionAsync metódus egy
Geoposition példánnyal tér vissza. Ebből megtudhatjuk a jelenlegi szélességi és hosszúsági
fokokat is.
Geolocator locator = new Geolocator(); Geoposition myLocation = await locator.GetGeopositionAsync(); txtLat.Text = myLocation.Coordinate.Latitude.ToString(); txtLong.Text = myLocation.Coordinate.Longitude.ToString();
Természetesen arra is van lehetőségünk, hogy folyamatosan kérdezzük le a felhasználó
koordinátáit. Ehhez a PositionChanged és a StatusChanged események lehetnek a
segítsgünkre. Ezeket az információkat akár háttérben is lekérdezhetjük, amikor az alkalmazás
fizikailag nem fut (előtérben).
Ha az alkalmazásunkban térképet is megszeretnénk jeleníteni, akkor a Bing Maps SDK-ra lesz
szükségünk, ugyanis ez alapértelmezés szerint nem része a keretrendszernek!
Bing Maps – regisztráció
Ahhoz, hogy a Bing Maps térképszolgáltatását használjuk, egy Windows Store alkalmazásba
előbb ezt a komponenst külön le kell töltenünk. Ezt a komponenst alapértelmezettként nem
tartalmazza a Windows Store API. A Bing Maps SDK for Windows Store apps-ot innen
tölthetjük le.
Letöltés után telepítsük fel!
Ez egy ingyenes SDK, bárki szabadon használhatja (a Bing Maps licenc szerződésének
megfelelően). De ahhoz, hogy használjuk, szükségünk lesz egy API Key-re, amit ingyenesen
igényelhetünk. Látogassunk el a http://www.bingmapsportal.com oldalra, és kattintsunk a
Sign in gombra, majd a Windows Live ID–nk 4(Microsoft Account) segítségével jelentkezzünk
be!
4 Ha még nincs Windows Live ID-nk (Microsoft Account az új neve) akkor ingyenesen létrehozhatunk egyet. Ebben az esetben a New User menüpontot kell választanunk.
A bejelentkezést követően kattintsunk a bal oldali menüsávon található a Create or view
keys menüpontra.
A Create Key alatt adjunk meg az alkalmazásunk nevét, URL-jét (opcionális), a kulcs típusát
állítsuk Trial-ra, az Application Type-ot pedig Windows Store app-ra, majd kattintsunk a
Submit gombra.
Néhány másodpercen belül megjelenik az API Key-ünk. Erre szükségünk lesz a fejlesztés
során.
Bing Maps API használata
Ebben a feladatban egy Bing Maps térképet fogunk megjeleníteni az alkalmazásunkban. Ne
feledjük el a Bing Maps szolgáltatáshoz szükséges előkészületeket megtenni.
A projektünkben kattintsunk a References-re jobb egérgombbal, majd a megjelenő helyi
menüből válasszuk ki az Add Reference… menüpontot.
A megjelenő Reference Manager ablakban, a Windows alatt kattintsunk az Extension
menüpontra. A listából válasszuk ki a Bing Maps for C#, C++, or Visual Basic library-t, és
klikkeljünk az OK gombra.
Sajnos ebben a pillanatban még nem haszálhatjuk ezt a library-t. Egy sárga felkiátójel jelenik
meg a Bing Maps library mellet.
Az alábbi hibát kapjuk, ha megpróbáljuk lefordítani az alkalmazást:
The processor architecture of the project being built "Any CPU" is not supported by the referenced SDK
"Bing.Maps.Xaml, Version=1.0". Please consider changing the targeted processor architecture of your project (in
visual studio this can be done through the Configuration Manager) to one of the architectures supported by the
SDK: "x86, x64, ARM".
Hogy ezt kiköszöbüljük, kattintsunk a BUILD menüponton belül a Configuration Manager…
elemre.
A megjelenő Configuration Manager ablakban a Platformot állítsuk át most x86-ra. Ezt
követően már neki kezdhetünk a munkának.
Most már elkezdhetjük a munkát a térképpel. Nyissuk meg a MainWindows.xaml-t. (Vagy azt
az oldalt, amiben szeretnénk használni). Az XML névterek közé vegyük fel a Bing.Maps
névteret:
xmlns:Maps="using:Bing.Maps"
A térképet a Maps osztály segítségével használhatjuk. A Credentials tulajdonságnál meg kell
adnunk azt a kulcsot, amit a Bing Maps portálon kaptuk, hogy használhassuk a Bing Maps
térkép szolgáltatást.
<Maps:Map Credentials="AmnrGdyleHvu6FPIsIm_Q0lkQINvY5oeb…"> </Maps:Map>
Most már használhatjuk a Bing Maps térkép szolgáltatását!
MessageDialog avagy a MessageBox utódja
A Windows Store alkalmazásoknál nincs MessageBox, mint a WPF-nél vagy a Windows
Formsnál. A fejleszték nagyon szeretik az üzenet ablakokat feldobni, mert gyorsan és
egyszerűen tudtak üzenetet küldeni a felhasználói felületre. Ez a lehetőség viszont Windows
Store alkalmazásoknál nem így működik. MessageBox osztály nem létezik, helyette viszont
van MessageDialog ami a Windows.UI.Popups névtérben található.
using Windows.UI.Popups;
A MessageDialog használata valamivel összetettebb, mint a MessageBox-é, de cserébe sokkal
többet nyújt a feljesztők számára, mint a MessageBox. Nézzünk egy egyszerű példát:
Első példánkban egy üzenetet dobunk fel. Ehhez mindösszesen egy MessageDialog-ot kell
példányosítanunk, a megfelelő argumentumokat átadni majd a ShowAsync metódust
meghívjuk.
MessageDialog mDialog = new MessageDialog("Figyelmeztetés!", "Alkalmazás neve"); mDialog.ShowAsync();
Ennek az eredménye az alábbi párbeszédablak lesz.
Figyeljük meg, hogy egy Close gomb van csak a párbeszédablakban. A MessageBox-ban ezek
a lehetőségek korlátozottak voltak. A MessageDialog-nál ez sokkal jobban testreszabhatóbb.
Ha új gombokat szeretnénk hozzáadni, akkor a MessageDialog példány Commands
gyűjteményéhez kell új UICommand-ot hozzáadnunk. Az alábbi példában egy Igen és egy
Nem gombot adunk a felhasználói felülethez.
MessageDialog mDialog = new MessageDialog("Figyelmeztetés!", "Alkalmazás neve"); mDialog.Commands.Add( new UICommand("Igen")); mDialog.Commands.Add( new UICommand("Nem")); mDialog.ShowAsync();
Az eredménye, mint látató egy olyan MessageDialog, amelyen van egy Igen és egy Nem
gomb.
A gombok sorrendje nem más mint a Commands gyűjteményhez adás sorrendje. Tehát, ha
előbb adjuk hozzá a Nem UICommandot mint az Igent akkor az lesz a sorrendben elől.
MessageDialog mDialog = new MessageDialog("Figyelmeztetés!", "Alkalmazás neve"); mDialog.Commands.Add( new UICommand("Nem")); mDialog.Commands.Add( new UICommand("Igen"));
mDialog.ShowAsync();
Az eredmény az alábbi képen látható.
Figyeljük meg, hogy ebben az esetben a Nem gomb van kijelölve alapértlmezett gombnak.
Ha ezt befolyásolni szeretnénk akkor a DefaultCommandIndex-szel tehetjük meg az alábbi
módon.
MessageDialog mDialog = new MessageDialog("Figyelmeztetés!", "Alkalmazás neve"); mDialog.Commands.Add( new UICommand("Nem")); mDialog.Commands.Add( new UICommand("Igen")); mDialog.DefaultCommandIndex = 1; mDialog.ShowAsync();
Ennak az eredménye a következő MessageDialog lesz:
Figyeljük meg, hogy ebban az esetben az Igen gomb van alapértelmezet gombnak beállítva.
Ugyan eddig gombokat adtunk a MessageDialoghoz, de funkciókkal ezeket a gombokhoz
nem társítottunk.
A következő példában ezt fogjuk megtenni, még pedig a UICommand létrehozásánál kell
megmondanunk, hogy adott gomb megnyomására milyen legyen az alkalmazás viselkedése.
Az egyszerűség kedvéért mi most csak egy szövegmezőbe írjuk ki az IGEN vagy a NEM
szavakat annak megfelelően, hogy a felhasználó melyikre kattintott.
MessageDialog mDialog = new MessageDialog("Figyelmeztetés!", "Alkalmazás neve"); mDialog.Commands.Add( new UICommand("Nem", (command) => { //Törzs txtInfo.Text = "NEM!"; })); mDialog.Commands.Add( new UICommand("Igen", (command) => { //Törzs txtInfo.Text = "IGEN!"; }));
mDialog.ShowAsync();
HttpClient
Nagyon sok alkalmazásnál előrfordul az, hogy HTTP-n akar kommunikálni. Legyen szó egy
egyszerű weboldal letöltéséről vagy épp REST-es szolgáltatás hívásról. A HttpClient sokat
segíthet a számmunkra. A HTTP műveleteket támogatja (GET – GetAsync(), POST –
PostAsync(), PUT – PutAsync(), DELETE – DeleteAsync()) és ezen műveletek segítségével HTTP
kéréseket fogalmazhatunk meg. Nézzük meg a legegyszerűbbet a GET-et! A webs kérések
legnagyobb része a GET, és most megnézzük, hogy hogy kérjük le egy web oldal teljes
tartalmát. Ehhez szükségünk lesz majd a System.Net.Http névtérre.
using System.Net.Http;
A felhasználó felületre dobjunk fel egy TextBox-ot (Name: txtUri) egy Button-t (Content: GET)
és egy TextBlock-ot (Name: tbResult). A gomb klikk eseményének törzsébe írjuk a
következőket:
Uri resUri = new Uri(txtxUri.Text, UriKind.Absolute); HttpClient hClient = new HttpClient(); HttpResponseMessage response = await hClient.GetAsync(resUri); tbResult.Text = await response.Content.ReadAsStringAsync();
Itt készítünk egy Uri objektumot aminek a címe az a Http cím amit a Textboxba beírtunk. (Ha
helytelen a cím akkor hibát fogunk majd kapni). Ezt követően példányosítsuk a HttpClient
osztályt, majd hívjuk meg a HttpClient példány GetAsync metódusát. Ennek a metódusnak
egy Uri címet kell átadnunk. Mint látható ez is egy aszinkron metódus, amelynek visszatérési
értéke egy HttpResponseMessage. A következő sorban pedig egyszerűen csak kiolvassú a
tartalmát a ReadAsStringAsync metódussal. Az eredmény pedig valami ilyesmi lesz.
Innentől pedig már “csak” fel kell dolgoznunk az eredményt.
WebView
A WebView vezérlő egy olyan egyszerű vezérlő amelynek segítségével HTML tartalmakat
tudunk megjeleníteni az alkalmazásunkon belül. Sőt akár egyszerű szövegbe írunk HTML
tartalmat azt is megtudja jeleníteni a számunkra. A szövegben akár JavaScript is lehet.
A felhasználó felületre dobjunk fel egy TextBox-ot (Name: txtUri) egy Button-t (Content: GO)
és egy WebView vezérlőt (Name: webView). A gomb klikk eseményének törzsébe írjuk a
következőket:
Uri resUri = new Uri(txtUri.Text, UriKind.Absolute); webView.Navigate(resUri);
Ennek az eredménye az, hogy az alkalmazás betölti azt az oldalt, aminek a címét a txtUri
mezőbe írtuk.
De nem csak meglévő oldalra tudunk ellátogatni. Akkár helyileg is létrehozhatunk egy HTML
dokumentumot amit a WebView vezérlőjével megjeleníthetünk. Ebben az esetben a GO
gomb klikk eseményének törzsébe írjuk a következőt:
string htmldoc = @"<!DOCTYPE html> <html> <body> <h1>This is heading 1</h1> <h2>This is heading 2</h2> <p>This is a paragraph.</p> </body> </html>"; webView.NavigateToString(htmldoc);
A htmldoc egy egyszerű sztring amiben egy HTML dokumentumot fogalmaztunk meg.
(Ebben a dokumentumban akkár JavaScript is lehet!) Ezt a sztringet átadjuk a webView
NavigateToString metódusának. Ezt követően láthatjuk a HTML oldalunkat a WebView
vezérlőben!
Helyi menü – ContextMenu
Klasszikus értelembe vet helyi vagy más néven context menu nincs a Windows Store
alkalmazásoknál. Illetve van, csak nem úgy mint ahogy azt a fejlesztők nagy része korábban
megszokta a Windows rendszereknél. UI szempontból nem a legszerencsésebb a helyi menük
használata, de ha úgy döntünk, hogy számunkra ez feltétlen fontos akkor persze van rá
lehetőségünk. Ehhez szükségünk lesz a Windows.UI.Popups névtérre.
using Windows.UI.Popups
Ennek a használatához példányosítanunk kell egy PopupMenu osztályt, majd ennek a
Commands gyűjteményéhez hozzá kell adnunk a UICommand-jainkat. A UICommand első
paramétere a megnevezés (ez lesz megjelenítve a helyi menüben), a második paramétere
pedig egy UICommandInvokedHandler delegate. Itt megadhatjuk inline módon is futtatandó
kódjainkat.
PopupMenu menu = new PopupMenu(); menu.Commands.Add( new UICommand("Copy", (command) => { //Törzs })); menu.Commands.Add( new UICommand("Paste", (command) => { //Törzs }));
A Popup menü kész itt az ideje megjeleníteni! Ehhez két metódus is a segítségünkre lehet. Az
egyik a ShowAsync, amelynek egy Point objektumot kell átadnunk. Ez a Point objektum
mondja meg, hogy a képernyőn hol jelenjen meg a helyi menü. Jelen esetben a bal felső
sarokban fog megjelenni a helyi menü. (X: 1, Y: 1)
menu.ShowAsync(new Point(1, 1));
A második helyi menu megjelenítésére használatos metódus a ShowForSelectionAsync,
amelynek egy Rect példányt kell átadnunk. (Ezt gyakrabbban használjuk.)
menu.ShowForSelectionAsync(new Rect(1, 1, 100, 100));
Vágólap – Clipboard
Gyakori eset, hogy az alkalmazásunkból valamilyen adatot a vágólapra szeretnénk helyezni,
vagy épp onnan betölteni. Természetesen ehhez is meg vannak a megfelelő API-jaink amivel
ez egyszerűen lehetséges. Azt viszont fontos szem előtt tartanunk mindig, hogy milyen
adatot is szeretnénk mi a vágólapra helyezni vagy épp onnan betölteni. Ugyanis nem
mindegy, hogy egyszerű szöveget, HTML dokumentumot vagy épp egy képet szeretnénk a
vágólapra helyezni / betölteni. A vágólap használatához a
Windows.ApplicationModel.DataTransfer névtérre lesz szükségünk.
using Windows.ApplicationModel.DataTransfer;
A legegyszerűbb az egyszerű szöveg helyezés és betöltése a vágólapról. Az alábbi példában
egy DataPackage osztályt példányosítunk, amelynek meghívjuk a SetText metódusát. Ennek
paraméteréül egy szting szöveget kell adnunk. (Ebben az esetben egy txtMsg textbox Text
tulajdonságát adjuk meg a számára. Ezt követően a Cliboard SetContent metódusának a
korábban létrehozott DataPackage példányt adjuk át.
DataPackage dt = new DataPackage(); dt.SetText(txtMsg.Text); Clipboard.SetContent(dt);
A beillesztés legalább ilyen egyszerű. Ehhez a Clipboard GetContent metódusát kell
megívnunk, melynek a visszatérési értéke egy DataPackageView példány. De mielőtt még az
adatott beillesztenénk célszerű megviszgálni, hogy egyáltalán van-e megfelelő “formátúmu”
adatt a vágólapon. Ha van akkor a DataPackageView példány (clipboardData) GetTextAsync
metódusát kell meghívnunk. Ennek a visszatérési értéke egy sztring. (Ebben a példában egy
tbRes nevű TextBlock vezérlőbe íratunk ki)
DataPackageView clipboardData = Clipboard.GetContent(); if (clipboardData.Contains(StandardDataFormats.Text)) { tbRes.Text = await clipboardData.GetTextAsync(); }
Html tartalom elhelyezése és beillesztés ugyan ilyen egyszerű. Csak ebben az esetben nem a
SetText, hanem a SetHtmlFormat metódust kell meghívnunk, majd a DataPackage-t
ugyanúgy min korábban át kell adnunk a Clipboard SetContent metódusának.
DataPackage dt = new DataPackage(); string htmldoc = @"<!DOCTYPE html> <html> <body> <h1>This is heading 1</h1> <h2>This is heading 2</h2> <h3>This is heading 3</h3> </body> </html>"; dt.SetHtmlFormat(htmldoc); Clipboard.SetContent(dt);
A beillesztés hasonló analógiával történik. Ugyanúgy meg kell hívni a Clipboard GetContent
metódusát, csak itt az ellenőrzésnél a StandardDataFormats osztály Html tulajdonságát kell
átadnunk a Contains metódusnak, hogy ellenőrizzük, hogy tényleg van HTML tartalom a
vágólapon. A beillesztés itt természetesen a GetHtmlFormatAsync aszinkron metódussal
történik! (Ebben az esetben egy webViewControl nevű WebView vezérlőnek adjuk át a
beillesztet HTML tartalmat)
DataPackageView clipboardData = Clipboard.GetContent(); if (clipboardData.Contains(StandardDataFormats.Html)) { webViewControl.NavigateToString(await clipboardData.GetHtmlFormatAsync()); }
Természetesen akár képet, vagy más összetett objektumokat is elhelyezhetünk a vágólapra.
Ezzekhez külön speciális metódusok társulnak.
Egy DataPackage-ben akár több adatott is elhelyezhetünk a vágólapra! Például: egyszerre
elhelyezhetünk egyszerű szöveget és képet is a váglólapra. A beillesztésnél mondjuk, meg,
hogy mit szeretnénk beilleszteni szöveget vagy képet esetleg rtf dokumentumot?
Megosztás – Share
Manapság minden a megosztásról szól. Miért ne oszthatnánk meg az alkalmazásunkban
található tartalmat is másokkal. Legyen szó egyszerű szövegről, képről vagy összetett
objektumról. Nem hiába található a Charm bar -on megosztás gomb!
Természetesen ehhez is egy jól definiált API áll a rendelkezésünkre. Csak úgy mint a vágólap
kezelésnél itt is a Windows.ApplicationModel.DataTransfer névtér lesz a segítségünkre.
using Windows.ApplicationModel.DataTransfer;
Szükségünk lesz egy DataTrasferManager példányra. Ezt most a konstuktorban hozzuk létre,
úgy hogy meghívjuk DataTrasferManager osztály GetForCurrentView metódusát, majd
feliratkozunk a DataRequest eseményre.
DataTransferManager dt; public MainPage() { this.InitializeComponent(); dt = DataTransferManager.GetForCurrentView(); dt.DataRequested += dt_DataRequested; } void dt_DataRequested(DataTransferManager sender, DataRequestedEventArgs args) { args.Request.Data.Properties.Title = "Recept könyv"; args.Request.Data.Properties.Description = "Somlói galuska - Recept"; args.Request.Data.SetText("Végy sok tejszínhabot!"); }
A DataRequest esemény törzsében, a DataPacake-nek megahatározzuk a címét (Title), leírását
(Description), illetve ha csak egyszerű szöveget akarunk átadni akkor a SetText metódusát
hívjuk meg és ennek átadjuk a tartalmat. Ha a Charm bar -on a Posta menüpontot választjuk
ki, akkor a levelünk tárgya a Recept könyv szöveg lesz, míg a level törzse pedig az amit a
SetText metódus paraméterének adtunk meg. Figyeljük meg, hogy a Description nem jelent
meg sehol! Ez most azért van, mert ez az alkalmazás ezt nem támogatja és nem dolgozza fel.
(Saját alkalmazásunk ezt feldolgozhatja)
Ha megszeretnénk jeleníteni a Charm Bar Share menüpontját ezt a DataTransferManager
ShowShareUI metódusával tehetjük meg.
DataTransferManager.ShowShareUI();
Keresés – Search Contract
A Windows 8-ban a keresés funkció új dimenziókat nyit meg a fejlesztők számára. Ugyanis,
most már nem a start menü kereső mezője segítségével keresünk, hanem a Charm Bar lesz a
társunk ebben a feladatban. Ráadásul nem csak a fájlrendszeren tudunk keresni, hanem az
alkalmazásunkban/alkalmazásokban is. Ahhoz, hogy ez működjön egy úgynevezett „keresési
szerződést” kell kötnünk a rendszerrel. (Maradjunk a Search Contract definíciónál.)
Nézzünk egy egyszerű esetet. A Solution Explorer-ben kattintsunk a
Package.appxmanifest fájlra, majd válasszuk ki a Declarations tabfület. Az Available
Declarations listából válasszuk ki a Search lehetőséget és kattintsunk, az Add gombra. (A
tulajdonságokat most nem töltjük ki.)
Mostantól lehetőségünk van az alkalmazásból keresni. Nézzük meg, hogy mi a különbség
aközött, hogy ha van Search Contract illetve ha nincs. A bal oldali képen az látható, hogy ha
az alkalmazásunk nincs Search Contract. Ekkor a „This app can’t be searched” üzenetet
kapjuk. Míg ha már van Search Contract akkor megjelenik az alkalmazásunk neve, és
kereshetünk benne. Természetesen a keresés mikéntjét, nekünk kell megírnunk.
Ha valamit kerestünk a kereső mezőben azt az alkalmazásunk App.xaml.cs állományában az
OnSearchActivated metódusnál (override), a SearchActivatedEventArgs QueryText
tulajdonságával lekérdezhetjük le.
protected override void OnSearchActivated(SearchActivatedEventArgs args) { string search = args.QueryText; }
Keresési lehetőségek felajánlása
Sok esetben nem elég csak annyi, hogy lekérdezzük, hogy a felhasználó mit adott meg.
Legtöbbször segítenünk kell a keresést és ajánlatokat kell tennünk. Ehhez a
Windows.ApplicationModel.Search névtér lesz majd a segítségünkre. Természetesen itt el kell
végeznünk azokat az előkészületeket, amit a Keresés – Search Contract –ben leírtunk.
using Windows.ApplicationModel.Search;
Ezt követően létrehozunk egy SearchPane példányt a SearchPane GetForCurrentView()
metódus segítségével (Lásd: konstruktor). Majd feliratkozunk a SuggestionsRequested
eseményre.
A SuggestionsRequested törzsében a SearchPaneSuggestionsRequestedEventArgs
segítségével lekérdezhetjük azt a keresési kifejezést, amit a felhasználó jelenleg megadott
(args.QueryText). Az args.Request egy SearchPaneSuggestionsRequest példányt ad vissza.
Ezt követően indul a keresés. Ezt most egy egyszerű eset, hisz csak végig lépünk egy tömb
elemein, ha az egyik szó eleje megegyezik a keresési mezőben megadottal, akkor az
eredményt hozzáfűzzük a SearchPaneSuggestionsRequest SearchSuggestionCollection
gyűjteményéhez az AppendQuerySuggestion metódusa segítségével. Célszerű vizsgálni, hogy
hány lehetőséget adunk a felhasználónak. Mi most megvizsgáljuk, hogy ha már van legalább
öt darab elem átadva a SearchSuggestionCollection-nek, akkor megszakítjuk a keresést. Ha a
felhasználó újabb karaktert ad meg akkor a keresés újraindul.
SearchPane searchPane; private static readonly string[] cityList = { "Abaújszántó", "Abony", "Abádszalók", "Adony", "Ajka", "Albertirsa", "Alsózsolca", "Aszód", "Badacsonytomaj", "Baja", "Baktalórántháza", "Balassagyarmat", "Balatonalmádi", "Balatonboglár", "Balatonföldvár", "Balatonfüred", "Balatonfűzfő", "Balatonkenese", "Balatonlelle", "Balkány" }; public MainPage() { this.InitializeComponent(); searchPane = SearchPane.GetForCurrentView(); searchPane.SuggestionsRequested += searchPane_SuggestionsRequested; } void searchPane_SuggestionsRequested(SearchPane sender, SearchPaneSuggestionsRequestedEventArgs args) { string queryString = args.QueryText; SearchPaneSuggestionsRequest request = args.Request; foreach (string suggestion in cityList) { if (suggestion.StartsWith(queryString, StringComparison.CurrentCultureIgnoreCase)) { request.SearchSuggestionCollection.AppendQuerySuggestion(suggestion); if (request.SearchSuggestionCollection.Size >= 5) {
break; } } } }
Az eredmény pedig most így néz ki:
Charm Bar – Search megjelenítése
A keresési mezőt mi magunk is megjeleníthetjük. Ehhez a SearchPane példány Show
metódusát kell meghívnunk. Ha paraméter nélkül hívjuk meg akkor, csak megjelenik a
keresés mező.
FIGYELEM! Ez a feladat az előző Keresési lehetőségek felajánlása feladat folytatása!
searchPane.Show();
Viszont a Show metódusnak egy sztring paramétert is megadhatunk. Ha ezt megtesszük,
akkor a kereső ablak keresés mezőjében a Show metódusnak átadott szöveg jelenik meg.
searchPane.Show("Miskolc");
Ennek az eredménye itt látható:
Fájlok keresés
Ha szeretnénk, akkor kereshetünk az alkalmazásunkon belül is fájlokra. Ehhez mindösszesen
egy StorageFolder-re van szükségünk (Jelen esetben a zenék mappa). Ennek a StorageFolder-
nek van egy CreateFileQueryWithOptions metódusa, ami egy QueryOptions objektumot vár.
A QueryOptions a Windows.Storage.Search névtérben található.
using Windows.Storage.Search; using Windows.Storage;
A QueryOptions-nek átadhatunk egy CommonFileQuery és egy filtertype-ot is. A
QueryOptions objektum talán egyik legfontosabb tulajdonsága a UserSearchFilter. Ennek
most átadjuk egy Textbox Text tulajdonságát (A Textbox neve: txtSearch). A
CreateFileQueryWithOptions metódus egy StorageFileQueryResult objektummal tér vissza.
Ezt követően csak lekérdezzük a fájlokat és a számunkra megfelelő módon feldolgozzuk az
eredményt. Most egyszerűen csak kiíratjuk a nevüket egy TextBlock-ba. (A TextBlock neve
most tbResult)
StorageFolder musicFolder = KnownFolders.MusicLibrary; QueryOptions queryOptions = new QueryOptions(CommonFileQuery.OrderByName, new List<string> { ".mp3"}); queryOptions.UserSearchFilter = txtSearch.Text; StorageFileQueryResult result = musicFolder.CreateFileQueryWithOptions(queryOptions); IReadOnlyList<StorageFile> files = await result.GetFilesAsync(); foreach (var item in files) { tbResult.Text += item.Name + "\n"; }
Content betöltése – ms-appx
Tegyük fel, hogy a Solution-ünkhöz hozzáadunk egy fájlt. Ha ezt a fájlt dinamikusan be
szeretnénk tölteni akkor egy speciális URI előtagot kell ismernünk. Ami nem más mint az ms-
appx!
Ebben az esetben a Solutionünk része egy Budapest.jpg fájl (Content).
A felhasználói felületen van egy image vezérlő melynek neve az imgPhoto. Ha ezt a képet
beszeretnénk tölteni és a szokásos módszerrel próbálnánk betölteni akkor hibát kapnánk.
BitmapImage bmp = new BitmapImage(); bmp.UriSource = new Uri("Budapest.jpg", UriKind.Absolute); imgPhoto.Source = bmp;
Ebben az esetben egy UriFormatException-t fogunk kapni. Ugyanis egy speciális a Windows
Store alkalmazásoknál egy speciális prefixumot kell adnunk az útvonálokhoz.
BitmapImage bmp = new BitmapImage(); bmp.UriSource = new Uri("ms-appx:Budapest.jpg", UriKind.Absolute); imgPhoto.Source = bmp;
Ebben az esetben már helyesen működik az alkalmazásunk. Azaz betölti a képet és
megjeleníti a felhasználói felületen.
Felhasználói információk
A jelenlegi felhasználóról lekérdzhetünk bizonyos információkat. Például, ha üdvözölni
szeretnénk, a felhasználót lekérdezhetjük a nevét. Ehhez a Windows.System.UserProfile
névteret kell használnunk.
using Windows.System.UserProfile;
A megjelenítendő név lekérdezése nagyon egyszerű. Mindösszesen a statikus
UserInformation osztály GetDisplayNameAsync metódusát kell meghívnunk.
string fullName = await UserInformation.GetDisplayNameAsync();
De lekérdezhetjük, a felhasználó kereszt illetve vezeték nevét is. Ehhez is jól meghatározott
metódusok állnak a rendelkezésünkre. A GetFirstNameAsync és GetLastNameAsync
metódusok lesznek a segítségünkre.
string firstName = await UserInformation.GetFirstNameAsync(); string lastName = await UserInformation.GetLastNameAsync();
Ami érdekesebb, az az, hogy akár a felhasználó fotóját is lekérdezhetjük. Ehhez a
UserInformation GetAccountPicture metódusát kell meghívnunk. A metódus paraméteréül
egy AccountPictureKind enumerációt kell adnunk. Ezzel az enumerációval megahtározhatjuk,
hogy a felhasználó nagy profil képét (LargeImage) vagy kis profil képét (SmallImage)
szeretnénk visszakapni.
A kép betöltését nem részletezem, amennyiben ennek a részleteire is kiváncsi vagy olvas utána
a fájlolvasás című cikkben.
StorageFile image = UserInformation.GetAccountPicture(AccountPictureKind.LargeImage) as StorageFile; IRandomAccessStream imageStream = await image.OpenReadAsync(); BitmapImage bitmapImage = new BitmapImage(); bitmapImage.SetSource(imageStream); userImage.Source = bitmapImage;
Sőt arra is van lehetőségünk, hogy a mi alkalmazásunkból megváltoztassuk a felhasználó
profil képét. Ehhez a UserInformation SetAccountPictureAsync metódusát kell meghívnunk.
További metódusok is a rendelkezésünkre állnak!
Adatkötés
Az adatkötés nagyon fontos témakör minden fejlesztő számára. Képzeljük el, hogy van egy
objektum amiben vannak tulajdonságok (Name, Age, Address) stb. Ha ezt meg akarjuk
jeleníteni a felhasználói felületen akkor legegyszerűbb esetben kiíratjuk az adott objektum
tulajdonságának tartalmát. Igen ám, de ha a forrás adat változik akkor a felhasználói felületen
ezt a változást nekünk manuálisan ki kell eszközölni. Szólni kell a UI-nak, hogy “Hello, a
bennem lévő tulajdonság változott!”. Ezt persze nem szeretnénk minden esetben külön
manuálisan kieszközölni, mert sokkal több kódolást eredményez, a lehetséges hibákról ne is
beszéljünk és még sorolhatnánk ennek a “manuális” módszernek a kényelmetlenségeit.
Első körben most egy UI Element-hez fogunk kötni, ezzen ugyanis nagyon egyszerű az
adatkötés bemutatása. A felhasználói felületre dobjunk fel egy TextBox-ot és Slider vezérlőt.
A Slider vezérlő neve legyen a slider1. Az adatkötést most XAML-ben fogom bemutatni. (Ezt a
Visual Studio-ból is megtudjuk tenni, de első körben jobb a XAML, mert sokkal jobban
érthető mint az IDE varázslata)
Nézzük meg, hogy most mi található a XAML-ben. (Ennél több tulajdonságot láthatunk
magunk előtt, de a számunkra felesleges tulajdonságokat eltávolítottam, hogy csak a
lényeget lássuk.)
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Slider Name="slider1" /> <TextBox Text="" /> </Grid>
A feladat tehát az, hogy van egy slider vezérlő. Ha annak a slider vezérlőnek (Forrás) változik
az értéke akkor a TextBoxban jelenjen meg. Ezt adatkötés nélkül kb, úgy jeleníthetjük meg,
hogy a slider1 ValueChanged eseményére feliratkozunk és ott ahogy változik az értéke a
TextBox.Text tulajdonsága egyenlő lesz a slider1.Value-jával. Ez így nem igazi adatkötés és
macerás.
Az adatkötést most Markup Extensionnel fogjuk megtenni.
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Slider Name="slider1" /> <TextBox Text="{Binding ElementName=slider1, Path=Value}" /> </Grid>
Ebben az esetben az eredmény ugyan az mint az előbb leírtak, csak épp adatkötve. Azaz, ha
mozgatjuk a slidert abban a pillanatban a TextBox Text tulajdonsága is változni fog.
Figyeljük meg az adatkötés szintaktikáját. Az ElementName-nél adjuk meg azt a vezérlőt
amihez kötni szeretnénk, a Path-nál pedig a tulajdonság nevét amihez kötni szeretnék. Ez
pedig nem más mint a slider1 Value tulajdonsága.
Stílusok
A Windows Store-os alkalmazásaink vezérlőit elláthatjuk stílusokkal és témákkal. Ez
tulajdonképpen hasonló analógiával működik, mint a weves világban a CSS. Nézzünk egy
egyszerű példát, ahol egy gomb stílusát definiáljuk.
A példa kedvéért most inline módon határozzuk meg ezt a stílust. (Általában erőforrásokban
kezeljük). A stílus meghatározásnál a Setter elementnél egy Property-t és egy Value-t kell
meghatároznunk. A Property mondja meg, hogy a vezérlő melyik tulajdonságát szeretnénk
meghatározni, míg a Value-nál megmondjuk, hogy ennek a tulajdonságnak mi lesz az értéke.
Ebben a példában a gomb háttér színét és előtér színét változtatjuk meg.
<Button Content="Sample"> <Button.Style> <Style TargetType="Button"> <Setter Property="Foreground" Value="Red"/> <Setter Property="BorderBrush" Value="Green" /> </Style> </Button.Style> </Button>
Figyeljük meg, hogy a Style elementnél megmondtuk, hogy mi a TargetType, ami most
értelemszerűen a Button. Ezt most mindenkép meg kell adnunk! Ennek a példának az
eredménye most egy mérsékelten szép gomb.
Figyeljük meg, hogy mi történik, ha a gombnál explicit módon meghatározzuk a Foreground
tulajdonságot.
<Button Content="Sample" Foreground="Yellow"> <Button.Style> <Style TargetType="Button"> <Setter Property="Foreground" Value="Red"/> <Setter Property="BorderBrush" Value="Green" /> </Style> </Button.Style> </Button>
Ebben az esetben a gomb előtér színe (azaz a Content színe) sárga színű lesz. Ugyanis a stílus
az alap stílust határozza meg. Ha a fejlesztő direkt módon meghatározza, akkor annak lesz
nagyobb súlya és az érvényesül.
Erőforrások
A stílust, színt, ecsetet vagy mást általában nem inline mód definiálunk, hanem egy
elrendezévezérlő, ablak vagy app resource részében. (A példában egy stílusra fogunk
hivatkozni!)
Ha egy oldalon definiálunk például egy stílust annak hatásköre csak az oldalon lesz érvényes!
Figyeljük meg, hogy ebben az esetben a stílusnak adtunk egy Key-t is. Erre a kulcsra
hivatkozhatunk majd.
<Page.Resources> <Style TargetType="Button" x:Key="myButtonStyle"> <Setter Property="Foreground" Value="Red"/> <Setter Property="BorderBrush" Value="Green" /> </Style> </Page.Resources>
Erre az erőforrásra az alábbi módon tudunk hivatkozni. Figyeljük meg, hogy ebben az
esetben az erőforrásban meghatározott kulcsra hivatkozunk!
<Button Content="Sample" Style="{StaticResource myButtonStyle}">
Ez a stílus most csak azon az ablakon belül lesz érvényes. Ha egy újabb oldalt (Page-t)
szeretnénk létrehozni, ahol ugyan ezt a stílust szeretnénk használni, akkor ezt a stílust az
App.xaml-be helyezhetjük el. Beláthatjuk, hogy a másolás és beilesztés ugyan járható ut, de
hosszú távon kezelhetetlen és módosítások többlet munkát eredményeznek.
Ha az App.xaml-ben helyezzük el akkor a stílus az alkalmazás szintjén bárhol elérhető.
<Application.Resources> <ResourceDictionary> <Style TargetType="Button" x:Key="myButtonStyle"> <Setter Property="Foreground" Value="Red"/> <Setter Property="BorderBrush" Value="Green" /> </Style> ... </ResourceDictionary> </Application.Resources>
A stílus felhasználás ugyanolyan módon történik mint a Page esetében. Ilyen téren nincs
változás. Csak most már több oldalról is elérhető ez az erőforrás.
Természetesen van arra is lehetőségünk, hogy külön Resource Dictionary-ba helyezzük el a
stílusainkat. Így a stílusok akár projektek között is mozgathatóak. Ha tehát egynél több
alkalmazásnál használjuk ezeket az erőforrásokat akkor célszerű Resoource Dicitionary-ba
helyezni. A Resource Dictionary betöltése az App.xaml-ben történik.
Ne felejtsük, hogy a resource-okba nem csak stílusokat tehetünk! Akár ecseteket, színeket,
sablonokat és egyébb elemeket is.
Próbaváltozatú alkalmazás készítése
Ha az alkalmazásunkat el szeretnénk adni, akkor célszerű próbaváltozattal is ellátni. Azt, hogy
funkció vagy idő korlátozott változatott készítünk az már a mi döntésünk. Ehhez nem kell
külön új alkalmazást készíteni, a már meglévő “Teljes” alkalmazást kell erre felkészíteni. Ehhez
mindösszesen a Windows.ApplicationModel.Store névtérre less szükségünk.
using Windows.ApplicationModel.Store;
Ebben a névtérben vannak a Windows Store kezeléshez szükséges osztályok. Első körben két
kucslfontoságú osztállyal ismerkedünk meg. Az egyik a CurrentApp a másik pedig a
CurrentAppSimulator. A két osztály tulajdonképpen ugyan azt tudja, csak a
CurrentAppSimulator osztályt fejlesztéshez és teszteléshez kell használnunk. Tulajdonképpen
a Windows Store-t tudjuk szimulálni a fejlesztői gépen. A CurrentApp-ot pedig ha
véglegesítettük az alkalmazást akkor használhatjuk. Fontos, hogy a releaselt alkalmazásáknol
amiket beküldünk CurrentApp-nak kell szerepelnie. Amennyiben a CurrentAppSimulator-t
benne hagyjuk, a kódban visszadobják az alkalmazásunkat.
Nézzünk egy egyszerű példát arra, hogy hogyan is lehet megállapítani, hogy az
alkalmazásunk Trial módban fut-e vagy sem. Az alábbi kódsort most tegyük az oldalunk
konstruktorába. Itt megvizsgáljuk, hogy az alkalmazásunk trial módban fut-e. Ha igen akkor a
btnAdd nevezetű gombot letiltjuk. Ha nem azaz teljes módban fut akkor engedélyezzük az
adott gombot. Persze nem csak gomb lehet! Itt csak az egyszerűség kedvéért mutattuk be
egy gomb segítségével.
LicenseInformation myLic = CurrentAppSimulator.LicenseInformation; if (myLic.IsActive) { if (myLic.IsTrial) { //Trial mód - Bizonyos funkciók letiltása btnAdd.IsEnabled = false; } else { //Teljes btnAdd.IsEnabled = true; } } else { //Érvénytelen licenc }
Jogosan merülhet fel a kérdés, hogy hogyan szimulálhatjuk fejlesztési időben a Windows
Store által nyújtott lehetőségeket? Hogy lehet módosítani azt, hogy most az alkalmazás Trial
módban fut-e vagy sem. Hogy lehet befolyásolni, hogy mikor jár le? Mivel fejlesztési időben
CurrentAppSimulator-t használunk ezért a fejlesztői gépen a
%userprofile%\appdata\local\packages\<package-
moniker>\localstate\microsoft\Windows Store\Apidata mappában lesz egy
WindowsStoreProxy.xml állomány. Ebben az állományban módosíthatjuk az alkalmazásunk
licencét a fejlesztői gépen.
Alkalmazáson belüli vásárlás
Akár a próbaváltozatú alkalmazásunkból is tudunk vásárlást kezdeményezni. Tehát nem kell
külön ellátogatnunk a Windows Store-ra, hogy megvegyük az adott alkalmazást, ezt az
alkalmazásunk “belsejéből” is megtudjuk tenni. Ehhez szintén a CurrentApp és a
CurrentAppSimulator osztály less a segítségünkre.
Ha az alkalmazást szeretnénk megvásárolni, akkor a CurrentAppSimulator
RequestAppPurchaseAsync metódusát kell az alkalmazáson belül meghívni. Paraméteréül egy
Boolean változót kell átadni, hogy kérünk-e vissza számlázási információt vagy sem.
CurrentAppSimulator.RequestAppPurchaseAsync(false);
Amennyiben CurrentAppSimulator-t használunk fel erre a célra akkor az alkalmazás
futtatásakor egy “Windows-os ablak” fog felugrani, amivel szimulálhatjuk, hogy a vásárlás
sikeres volt-e vagy sem.
Bizonyos alkalmazásoknál külön-külön adhatunk el funkciókat. Tipikus példa rá egy játék,
ahol külön vásárolhatja meg a felhasználó a pályákat. Ezen is nyereséget tudunk termelni.
Ebben az esetben a vásárlás picit módosul. Itt is a a CurrentAppSimulator osztály lesz a
segítségünkre, csak épp a RequestProductPurchaseAsync metódust kell meghívni. Ennek a
metódusnak a funkció nevét kell megadni amit meg szeretnénk vásárolni. A második
parameter ugyan az mint a RequestAppPurchaseAsync esetén.
CurrentAppSimulator.RequestProductPurchaseAsync("SpaceMap", false);
Ezzen funkció definiálása szintén a WindowsStoreProxy.xml –ben történik. A vásárlás
szimulálása ugyanolyan módon történt mint korábban.