Archívum

Archive for the ‘Windows Phone 7’ Category

Windows Phone 7 kódgyűjtemény / Köszönet

2012. május 9. szerda 6 hozzászólás

Lassan 3 hónapja, hogy megírtam a Windows Phone 7 kódgyűjteményt. Eddig egyesével posztoltam ki a fejezeteket a könyvből a blogra, de íme innen is letölthető a teljes kódgyűjtemény.

Ezalatt a szűk 3 hónap alatt több mint 3000-en töltötték le a könyvet/jegyzetet. Ami nagyon szép szám szerintem. Ha összevetjük a Windows Phone 7 lépésről lépésre 6600 letöltésével akkor pláne.  Azért az mégis csak egy teljes nagy volumenű könyv.

Tisztában vagyok vele, hogy a magyar Windows Phone 7 fejlesztői közösség elég kicsi, és ez ennek tükrében is nagyon szép szám mind a két letöltés. Ráadásul a kódgyűjtemény mögött nem is volt akkora marketing mint a lépésről lépésre mögött. (ja és 5-el több “lájkot” is kaptam :). Micsoda mérvadó szám. 🙂 )

image

Mindenkinek köszönöm, aki letöltötte és visszajelzett a kódgyűjteménnyel kapcsolatban. Amikor az ember pozitív visszajelzés kap a munkájáról akkor értékeli és érzi igazán, hogy van értelme a munkájának.

Köszönöm a devportál közösségének a biztató szavakat:

image

image

image

Ezenkívül külön köszönöm Primusz Péter szavait: (Tényleg nagyon jól eset)

clip_image002

Nyelvésznek (cpctcg?) is köszönöm, hogy kijavította az olykor igencsak fura fogalmazásaimat. 🙂 Tisztában vagyok vele, hogy nem vagyok egy fogalmazó zseni, de ha közösség segít akkor kijavítom a hibáimat és tanulok és belőlük (remélem :)).

Terveim közt lesz még egy Windows 8, WPF és egy jQuery kódgyűjtemény is. Hogy mi fog belőle megvalósulni azt majd a jövő eldönti.

A könyv/jegyzet bevezetője:

Amikor valaki a kezébe 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.
Ezen könyv megírásának az alapötlete az volt, hogy érthető, a Windows Phone 7 fejlesztésében imagetapasztalatlan szakemberek számára is átlátható útmutatókat készítsünk, melyek segítenek eligazodni ezen új terület fejlesztésében. Pont ezért a Windows Phone 7 fejlesztésének lényegesebb területeit kiemelve, a legtöbb funkcióhoz találunk benne rövid, maximum 1-2 oldalas leírásokat, melyek lépésről lépésre vezetnek végig egy-egy alkalmazás megírásában, és a kódok is szerepelnek minden lépésnél.
A könyvben mindent meglelünk, amire csak szükségünk van: a rádió-alkalmazástól kezdve, a GPS kezelésen keresztül a Windows Phone 7 toolkit vezérlőkig, és az első lépésekben is nagy segítséget nyújt. A fejezetek nem kapcsolódnak szervesen egymáshoz, ahol mégis, ott jelölve van, így tetszőleges sorrendben haladhatunk, nem fontos az általunk ö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 ezen témák elméleti része komolyabban is érdekel, akkor minden kellő információt megtalálsz a Windows Phone 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.

Még egyszer köszönöm mindenkinek.

Kategóriák:Windows Phone 7 Címkék:

Webszolgáltatások elérése

2012. május 8. kedd Hozzászólás

Gyakori eset, hogy a telefonról egy külső webszolgáltatást akarunk elérni. A következő példában egy olyan alkalmazást készítünk, amely egy webszolgáltatáson keresztül megmondja a felhasználónak, hogy az általa megadott IP cím melyik országban van. Kezdjük is el!

1. Készítsünk egy Windows Phone 7 alkalmazást!

2. Dobjunk fel a felhasználói felületre egy txtbox-ot, melynek a neve legyen a txtIpAddress, a Text tulajdonsága pedig üres legyen!

3. A Textbox alá helyezzünk egy gombot, a gomb neve legyen btnGetInfo, a contentje pedig legyen az „IP meghatározása”!

image4. Kész a felhasználói felületünk, adjuk hozzá a szolgáltatás referenciáját: a solution Explorer-ben kattintsunk a Refrences-re jobb egérgombbal, és válasszuk ki az Add Service Reference menüpontot!

5. A megjelenő ablakban adjuk meg a webszolgáltatásunk címét (ez most a http://www.webservicex.net/geoipservice.asmx címen érhető el), majd kattintsunk a Go gombra! Az elinduló folyamat néhány másodpercet igénybe vehet. Oldjuk fel az IpService névteret, majd kattintsunk az OK gombra!

image

6. Térjünk vissza a MainPage dizájn nézetéhez, és kattintsunk kétszer a btnGetInfo gombra! A klikk esemény törzsében példányosítsuk a GeoIpServiceSoapClient osztályt! Gyakorlatilag webszolgáltatás elérésénél azt a látsztatot keltjük, hogy ez az osztály helyben szerepel és a metódusai is olyanok, mintha helyi metódusok lennének, miközben ez egy csontváz. Amikor meghívjuk például a GetGeoIpAsync metódust, akkor egy távoli szolgáltatáshívás keletkezik, és ez a metódus egy távoli szerveren fog lefutni. Mivel minden hívás aszinkron, ezért értesíteni kell a felhasználót, hogy az eredmény megérkezett, ezért iratkozunk fel a GetGeoIpCompleted eseményre:

private void btnGet_Click(object sender, RoutedEventArgs e)

{

IpService.GeoIPServiceSoapClient ipClient = new IpService.GeoIPServiceSoapClient();

 

ipClient.GetGeoIPCompleted += new EventHandler<IpService.GetGeoIPCompletedEventArgs>(ipClient_GetGeoIPCompleted);

 

ipClient.GetGeoIPAsync(txtIpAddress.Text);

}

7. A Completed esemény törzsét most egy egyszerű MessageBox-szal látjuk el, ami megjeleníti az IP cím országát (GeoIP osztállyal tér vissza a hívás. További információk is kinyerhetők a visszatérési értékből.).

void ipClient_GetGeoIPCompleted(object sender, IpService.GetGeoIPCompletedEventArgs e)

{

    MessageBox.Show(e.Result.CountryName);

}

8. Indítsuk el az alkalmazást, adjunk meg egy valós IP címet, és nézzük meg, hogy valóban sikerül-e megmondani a szolgáltatásnak, hogy melyik országban található az IP cím!

image

Önnálló feladat: írjunk egy olyan alkalmazást, ami a napi euró, dollár árfolyamokat megmondja. Ehhez használjuk fel a Magyar Nemzeti Bank Árfolyam szolgáltatását! Ez a következő címről érhető el: http://www.mnb.hu/arfolyamok.asmx.

Kategóriák:.NET, Windows Phone 7 Címkék: , ,

Read-Only adatbázis létrehozása

2012. május 7. hétfő 2 hozzászólás

Bár elég egyszerű létrehozni adatbázist úgy, hogy van egy entitás osztályunk és egy DataContext példányunk, mégis egy bonyolultabb adatbázis szerkezetének létrehozása sok munkával járhat, különösen, ha nagyon sok táblánk van, és a táblák között kapcsolatok is vannak. Nemcsak létre tudunk hozni adatbázist, arra is van lehetőségünk, hogy már meglévő adatbázist (sdf) hozzáadjunk a projekthez és kezeljük azt. Nézzük meg ezt az esetet lépésről lépésre! A célunk tehát az, hogy létrehozzunk egy SQL Server CE adatbázist, előállítsuk hozzá az entitás osztályokat és a DataContextet, majd felhasználjuk egy WP7 alkalmazásban.

1. Indítsuk el az SQL Server Mangement Studio 2008 Express változatát (ha ez az alkalmazás nincs meg, akkor legegyszerűbben a Web Platform Installer-rel telepíthetjük fel)!

2. Indítás után egy Login képernyő fogad. Itt a Server type-nál válasszuk az SQL Server Compact –ot!

image

3. A Database file-nál válasszuk a <New Database…> menüpontot, ekkor felugrik a Create New SQL Server Compact Database ablak. A fájl neve ebben az esetben a D meghajtó TestDb mappájára mutat, ebben a mappában fogja a MyMusic.sdf adatbázist létrehozni a Management Studio.

image

Most nem foglalkozunk a titkosítással, így az Encryption mode maradhat UNENCRYPTED. Ezt követően kattintsunk az OK gombra! Ugyan most kapunk egy figyelmeztetést, hogy az adatbázisunk nem lesz levédve, de ezzel most ne törődjünk, és kattintsunk a Yes gombra! A későbbiek folyamán a titkosítással is fogunk foglalkozni.

4. Ezt követően visszaugrunk a Connect To Server ablakhoz, itt kattintsunk a Connect gombra, ekkor az SQL Server Management Studio-ból kezelhetjük ezt az adatbázist.

5. Az Object Explorer-ben kattintsunk a Tables elemre jobb egérgombbal, majd a megjelenő helyi menüben válasszuk ki a New Table menüpontot!

6. A megjelenő New Table ablakban definiáljuk a Musics adattáblát. Az ID oszlop egy int típusú elsődleges kulcs, True értékre állított Identity tulajdonsággal és annak alapértelmezett értékeivel. Az Artist és a Title mezők nvarchar típusúak, a Rating mező int típusú. Kattintsunk az OK gombra!

image

7. Most már elkészült az adatbázisunk, bezárhatjuk az SQL Server Management Studio-t. Az adatbázist Windows Phone alól viszont csak Linq To SQL-lel érhetjük el. Ehhez létre kell hoznunk az entitásokat reprezentáló osztályokat. Persze itt is megtehetnénk, hogy kézzel generáljuk az entitás osztályokat és a DataContextet, de van szerencsére egy SQLMetal nevezetű eszköz is, ami bár hivatalosan még mindig nem támogatott eszköz, a Windows Phone 7 fejlesztés során mégis nagy hasznát tudjuk venni.

8. Indítsuk el a Visual Studio 2010 Command prompt-ot!

9. A Command Prompt-ban az egyszerűség kedvéért navigáljunk el abba a mappába, ahol az adatbázist elkészítettük (ez jelen esetben a D:\TestDb mappa), majd indítsuk el az SqlMetal.exe alkalmazást az alábbi paraméterekkel:

sqlmetal MyMusic.sdf /code:MyMusic

Ebben az esetben a MyMusic.sdf-ből készítünk MyMusic.cs fájlt. A forrásfájlban lesznek az entitásosztályaink, valamint a DataContext is. Ez a forrásfájl jelenleg az adatbázis mellett található.

image

10. Most már kész az adatbázisunk és a hozzá tartozó osztályok is elkészültek. Itt az ideje használatba venni ezeket: indítsuk el a Visual Studio-t, és készítsünk egy új Windows Phone Application projektet (legyen a neve DatabaseSample)!

11. Amint elkészült az alkalmazás sablonja, adjuk hozzá az adatbázist és az SqlMetal által generált forrásfájlt! Ehhez a Solution Explorer-en kattintsunk jobb egérgombbal, majd a megjelenő helyi menüben válasszuk ki az Add Existing Item menüpontot, és válasszuk ki a fentebb említett fájlokat!

12. Adjuk hozzá a projekthez a System.Data.Linq assembly-t is! Kattintsunk jobb egérgombbal a References-re a Solution Explorerben, és válasszuk ki az Add Reference menüpontot!

13. A megjelenő ablakban kattintsunk a .Net fülre, és válasszuk ki a System.Data.Linq névteret!

14. Ezt követően, ha megpróbálnánk lefordítani az alkalmazást, a következő hibaüzenetet kapnánk:

The type or namespace name ‘IDbConnection’ does not exist in the namespace ‘System.Data’ (are you missing an assembly reference?)

15. Ez azért van, mert a Windows Phone 7 System.Data névterében valóban nem létezik IDbConnection, az SqlMetal viszont legenerálta azt. Mint korábban is említettük, az SqlMetal nem generál teljesen kompatibilis kódot a Windows Phone 7-tel, hivatalosan nem is támogatott eszköz, mégis megkönnyíti a fejlesztést. Ahhoz, hogy ez a DataContext helyes legyen, alakítsuk át a két konstruktort az alábbi módon:

public MyMusic(System.Data.IDbConnection connection) :

    base(connection, mappingSource)

{

    OnCreated();

}

 

public MyMusic(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :

    base(connection, mappingSource)

{

    OnCreated();

}

Ettől a ponttól kezdve már használatba vehetjük az adatbázist. Igen ám, de ha megpróbálnánk elérni azt, akkor az alábbihoz hasonló hibát kapnánk:

MyMusic db = new MyMusic("isostore:/MyMusic.sdf");

image

16. Ezt a hibát azért kapjuk, mert az IsolatedStorage-ban nem szerepel ez az adatbázis. Bár Content-re van állítva az adatbázis Build Action tulajdonsága, és az XAP-ban is benne van ez az adatbázis, mégsem található az Isolated Storage-ban. Ahhoz, hogy ezt az adatbázist használjuk (Reference Database), egy speciális connection string-et kell megadnunk:

MyMusic db = new MyMusic("Data Source = ‘appdata:/MyMusic.sdf’; File Mode = read only");

17. Az adatbázist most már elérhetjük, de csak lekérdezéseket fogalmazhatunk meg rajta, azaz csak olvasható az adatbázis tartalma. Amint módosítani szeretnénk, azonnal egy Permission Denied hibaüzenetet kapnánk. (Az adatok módosításáról és hozzáadásáról a következő alfejezetben olvashatunk)

image

18. Ahhoz, hogy ezt elkerüljük, az adatbázist át kell másolnunk az Isolated Storage-ba. Ehhez használhatjuk például az alábbi segédmetódust:

public class DatabaseHelper

{

    public static void MoveReferenceDatabase()

    {

        IsolatedStorageFile iso = IsolatedStorageFile.GetUserStoreForApplication();

 

        using (Stream input = Application.GetResourceStream(new Uri("MyMusic.sdf",

            UriKind.Relative)).Stream)

        {

            using (IsolatedStorageFileStream output = iso.CreateFile("MyMusic.sdf"))

            {

                byte[] readBuffer = new byte[4096];

                int bytesRead = -1;

                while ((bytesRead = input.Read(readBuffer, 0, readBuffer.Length)) > 0)

                {

                    output.Write(readBuffer, 0, bytesRead);

                }

            }

        }

    }

}

19. Amint meghívjuk a MoveReferenceDatabase metódust, az átmásolja az adatbázist az Isolated Storage-ba, és ezek után a megszokott módon tudjuk lekérdezni, módosítani az adatbázis tartalmát. Ne felejtsük el, hogy ebben az esetben a connection string-et a hagyományos isostore értékre kell visszaállítanunk:

MyMusic db = new MyMusic("isostore:/MyMusic.sdf");

Láthattuk, hogy milyen lépéseket kell megtennünk ahhoz, hogy már meglévő adatbázist használjunk fel a Windows Phone 7 készülékünkön. Bár ez a módszer nem teljesen támogatott, mégis nagyon sokszor hasznos lehet. Ha csak olvasható adatbázist akarunk használni, akkor egyszerűen csak hozzáadjuk az adatbázist, és az legenerál egy forrásfájlt a projektünkhöz, ha azonban módosítani is szeretnénk, akkor egy segédmetódust is definiálnunk kell az adatbázis mozgatásához.

Az adatbázisunk még üres, ezt követően töltsük fel adatokkal!

Kategóriák:.NET, Windows Phone 7 Címkék: , ,

Adatbázis létrehozása

2012. május 4. péntek Hozzászólás

Ahhoz, hogy létrehozzunk egy adatbázist, egy DataContext típust és legalább egy entitás osztályt létre kell hoznunk. Ezek az osztályok lesznek felelősek a mapping-ért, ennek megfelelően ezeket az objektumokat el kell látni a megfelelő attribútumokkal. A leképezéshez szükségünk lesz a System.Data.Mapping.Linq névtérre.

Az adatbázist úgy tudjuk létrehozni, hogy készítünk egy egyszerű osztályt, és ellátjuk a megfelelő attribútumokkal. Például ha szeretnénk létrehozni egy táblát az ügyfeleink nyilvántartására, ehhez létrehozunk egy Customer osztályt, amibe felveszünk néhány tulajdonságot.

Nézzünk egy konkrét példát az adatbázis leképezésére! Létrehozzuk a Customer osztályt, amelyet ellátunk egy Table attribútummal. Ebben meghatározzuk, hogy ez az osztály a Customers táblához fog kapcsolódni. Az osztályban elhelyezhetünk saját tulajdonságokat, melyeket a Column attribútummal rendelünk az adatbázis oszlopaihoz.

using System.Data.Linq.Mapping;

 

namespace PhoneDatabase

{

    [Table(Name = "Customers")]

    public class Customer

    {

        [Column(IsPrimaryKey = true)]

        public int CustomerID { get; set; }

        [Column]

        public string CompanyName { get; set; }

        [Column]

        public string ContactName { get; set; }

        [Column]

        public string City { get; set; }

    }

}

A CustomerID tulajdonságot a tábla elsődleges kulcsaként jelöljük meg. Ahhoz, hogy létrehozzuk vagy lekérdezéseket fogalmazzunk meg ezen a táblán, szükségünk lesz egy DataContext-re is. 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.Data.Linq névtérben található). Hozzuk létre a Customers tulajdonságot, amely legyen Table<Customer> típusú! Ez reprezentálja a Customers táblában lévő adatokat. A tulajdonságot a konstruktorban inicializáljuk. Ennek a konstruktornak paraméterként átadjuk az adatbázis eléréséhez szükséges connectionString paramétert, amelyet átadunk a DataContext konstruktorának:

using System.Data.Linq;

 

namespace PhoneDatabase

{

    public class CustomerDataContext : DataContext

    {

        private Table<Customer> customers;

        public Table<Customer> Customers

        {

            get { return customers; }

        }

 

        public CustomerDataContext(string connectionString) : base (connectionString)

        {

            customers = GetTable<Customer>();

        }

    }

}

Most már kész az entitás osztályunk, és kész a DataContext is. Itt az ideje az adatbázist fizikailag is létrehozni! Ehhez a DataContext példány CreateDatabase metódusát kell meghívnunk. Célszerű az adatbázis létrehozása előtt ellenőrizni, hogy az adott adatbázis létezik-e. DataContext példányosításakor meg kell adnunk a connection stringet, ami ebben az esetben isostore:/Customer.sdf, azaz az Isolated Storage legfelső mappájában egy Customer.sdf fájlra hivatkozunk.

public CustomerDataContext(string connectionString) : base (connectionString)

{

     customers = GetTable<Customer>();

}

Most már van egy adatbázisunk, amiben van egy Customer tábla, de macerás munka ezt minden esetben manuálisan létrehozni. Nincs lehetőség valami kényelmesebb, megszokottabb módszerre? De van! A következő részben ezzel fogunk megismerkedni.

Kategóriák:.NET, Windows Phone 7 Címkék: , ,

Jegyzetfüzet alkalmazás készítése

2012. május 3. csütörtök Hozzászólás

A következő gyakorlatban egyszerű jegyzetelő alkalmazást fogunk elkészíteni (6-4 ábra). Az alkalmazás felhasználói felülete előre el van készítve. A projekt kiindulási anyagát a következő oldalról tölthetjük le: http://devportal.hu/wp7 (Példakódok.zip).

image

A gyakorlatban csak az adattárolással kapcsolatos kódokat fogjuk közösen megírni, az alábbi lépésekben:

1. Nyissuk meg az IsolatedStorageDemo.sln fájlt (Begin mappa)! Ha valamit a gyakorlat lépései során nem sikerülne pontosan követnünk, az End mappában megtalálható és kipróbálható az alkalmazás végleges formája.

2. Fordítsuk le, és indítsuk el az alkalmazást! Egyszerű jegyzetelő felületet kapunk, de jelenleg még nem tudjuk sem elmenteni, sem betölteni jegyzeteinket.

3. Itt az ideje ezeket a funkciókat megvalósítani! Zárjuk be a futó alkalmazást, és térjünk vissza a projekthez! Nyissuk meg az App.xaml.cs fájlt, és navigáljunk el az Application_Startup eseményhez, itt fogjuk a jegyzeteink számára elkészíteni a „Notes” mappát. Az alkalmazás minden indulásakor megvizsgáljuk a DirectoryExist metódussal, hogy a Notes mappa létezik-e. Ha nem létezik (pl. első indulás), akkor a CreateDirectory metódussal létrehozzuk:

IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

if (!isf.DirectoryExists("Notes"))

{

    isf.CreateDirectory("Notes");

}

4. Nyissuk meg a MainPage.xaml.cs fájlt, és oldjuk fel a System.IO és a System.IO.IsolatedStorage névteret (a feladatban a többi lapjához már hozzáadtuk ezeket a névtereket)!

using System.IO;

using System.IO.IsolatedStorage;

5. A MainPage.xaml.cs-ben navigáljunk el a btnSave_Click eseményhez, ugyanis itt fogjuk elmenteni a jegyzetünket a fájlrendszerbe. 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, és .dat lesz a kiterjesztésük. Ezt követően létrehozunk egy IsolatedStorageFileStream-et. Ezt legegyszerűbben a StreamWriter-rel tudjuk írni, így a mySw példány WriteLine metódus paraméterének átadjuk a txtDocument.Text tulajdonságának értékét. Ha minden sikeresen lezajlott, akkor egy MessageBox-ban ezt megüzenjük a felhasználónak.

string path = "Notes\\" + txtTitle.Text + ".dat";

IsolatedStorageFile myISFile = IsolatedStorageFile.GetUserStoreForApplication();

using (IsolatedStorageFileStream myFs = new IsolatedStorageFileStream(path, FileMode.Create, FileAccess.Write, myISFile))

{

    using (StreamWriter mySw = new StreamWriter(myFs))

    {

        mySw.WriteLine(txtDocument.Text);

        mySw.Flush();

    }

}

MessageBox.Show("A jegyzetedet elmentettük!", "Isolated Storage Demo", MessageBoxButton.OK);

6. Most már elkészítettük az alkalmazásunk jegyzet (Notes) mappáját, és el is tudjuk menteni a jegyzeteinket. Itt az ideje megírni azt is, hogy a korábban elmentett jegyzeteinket vissza tudjuk tölteni. Nyissuk meg a Pages/SavedItems.xaml.cs fájlt, és navigáljunk el a SavedItems konstruktorába: itt fogjuk kiolvasni a fájlrendszerről, hogy jelenleg milyen jegyzeteink vannak mentve. 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.GetUserStoreForApplication();

lstMyNotes.ItemsSource = isf.GetFileNames("Notes\\*.dat");

A GetFileNames visszatérési értéke egy String tömb, ezt adjuk át az lstMyNotes listának.

7. Az előző pontnál megjelenítettük a jegyzeteink fájljait egy listában, most pedig megírjuk azt az egyszerű funkciót, amivel a kiválasztott fájlt átadjuk a MainPage-nek, ami majd megnyitja az adott jegyzetet. Navigáljunk el az lstMyNotes_SelectionChanged eseményhez, és a metódus törzsébe írjuk a következőt:

string selectedItem = lstMyNotes.SelectedItem as string;

if (selectedItem != null)

{

    NavigationService.Navigate(new Uri("/MainPage.xaml?OpenFile=" + selectedItem, UriKind.Relative));

}

Itt egyszerűen a kiválasztott fájl nevét átadjuk a MainPage-nek, méghozzá a QueryString átadási mintát követve.

8. Természetesen, ha átadtuk ezt a paramétert, akkor azt le is kell kérdeznünk, és az átadott értéknek megfelelően megnyitni az adott fájlt. Térjünk vissza a MainPage.xaml.cs –hez, és navigáljunk el az OnNavigatedTo eseményhez, és itt létrehozunk egy fileName nevű string változót. A NavigationContext.QueryString.TryGetValue metódusával megpróbáljuk elérni az OpenFile paraméter értékét. A fájl olvasása a fájlírás analógiájára történik, itt azonban az IsolatedStorageFileStream FileMode felsorolt típusából az Open értéket választjuk, és StreamWriter helyett StreamReader-t használunk. A StreamReader ReadToEnd metódusának segítségével a fájl teljes tartalmát kiolvassuk, ezt követően átadjuk a txtDocument-nek. A txtTitle esetén a fileName szövegből eltüntetjük a .dat kiterjesztést, hogy elegánsabban jelenjen meg a fejléc:

string fileName = string.Empty;

if (NavigationContext.QueryString.TryGetValue("OpenFile", out fileName))

{

    IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

    using (IsolatedStorageFileStream myFs = new IsolatedStorageFileStream("//Notes//" + fileName, FileMode.Open, isf))

    {

        using (StreamReader sr = new StreamReader(myFs))

        {

            txtTitle.Text = fileName.Replace(".dat", "");

            txtDocument.Text = sr.ReadToEnd();

        }

    }

}

9. Ezzel elkészült az alkalmazásunk. Fordítsuk le a forráskódot (Ctrl+Shift+B), és ha valamilyen hibát tapasztalunk, nézzük át újra a kódot és javítsuk azt! Ha minden rendben lezajlott, akkor indítsuk el az alkalmazásunkat (F5), és az megjelenik kezdőképernyőjén a jegyzeteink listájával.

image

10. Az alkalmazás betöltése után írjunk egy jegyzetet, majd kattintsunk a mentés gombra! Készítsünk egy új jegyzetet (+), ezt követően kattintsunk a megnyitás gombra! A megjelenő ablakban a jegyzeteink lesznek láthatók. Válasszunk ki egy jegyzetet, é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, akkor eddig a feladatot helyesen oldottuk meg. Zárjuk be az alkalmazást, és térjünk vissza a Visual Studio-hoz!

11. A fájlkezeléshez hozzátartozik a beállítások kezelése is. A következőkben a jegyzetelő alkalmazásunkat kiegészítjük egy olyan beállítással is, melynek segítségével a felhasználó meghatározhatja, hogy a jegyzetek betűszíne milyen legyen. Nyissuk meg a Pages/Settings.xaml.cs fájlt, és navigáljunk el az lpForeground_SelectionChanged metódushoz, majd a feltételbe írjuk a következő kódsorokat:

IsolatedStorageSettings.ApplicationSettings["Foreground"] = selectedItem.Key;

NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));

Itt az IsolatedStorageSettings.ApplicationSettings Foreground kulcsához hozzáadjuk a kiválasztott szín kulcsának értékét, majd visszanavigálunk a MainPage oldalra.

12. Ha már kiválasztottunk egy színt, és el is van tárolva, 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, és töltsük be a használt szín indexét:

IsolatedStorageSettings.ApplicationSettings.TryGetValue<int>("Foreground", out currentIndex);

13. Itt az IsolatedStorageSettings.ApplicationSettings.TryGetValue metódusát használjuk. Használhatnánk az indexeres formát is, de a TryGetValue egyik nagy előnye az, hogy ha az adott kulcs (esetünkben Foreground) még nem létezik, akkor sem jelez hibát, a változó pedig az alapértelmezett értékét kapja (ebben az esetben a 0-t, ami kötés után a fekete színt reprezentálja).

IsolatedStorageSettings.ApplicationSettings.TryGetValue<int>("Foreground", out foregroundColorIndex);

Csakúgy, mint a Settings page-nél, itt is kiolvassuk a foreground tulajdonságot, majd alkalmazzuk a szövegdobozon.

14. Immár kész a teljes alkalmazás. Fordítsuk le a forráskódot (Ctrl+Shift+B), és ha valamilyen hibát tapasztalunk, nézzük át újra a kódot, és javítsuk azt! Ha minden rendben lezajlott, akkor indítsuk el az alkalmazásunkat (F5)!

15. Készítsünk egy jegyzetet, majd mentsük el! Válasszuk ki a beállítások menüpontot, és a megjelenő ablakban válasszunk ki egy nekünk tetsző színt! Ha kiválasztottunk egy új színt, akkor az alkalmazás rögtön visszanavigál a MainPage oldalra, ahol láthatjuk, hogy a jegyzetünk betűszíne megegyezik az általunk kiválasztott színnel.

image

Ezen a gyakorlaton keresztül is láthattuk, hogy a fájlkezelés rendkívül egyszerű a Windows Phone –on. Minden alkalmazás rendelkezhet IsolatedStorage-dzsal, ahol fájlműveleteket végezhet, de ebből a kontextusból nem tud kibújni.

Kategóriák:.NET, Windows Phone 7 Címkék: , ,

Alkalmazás beállítások

2012. május 2. szerda Hozzászólás

Amikor csak egyszerű alkalmazás beállításokat szeretnénk elmenteni vagy lekérdezni, akkor az ApplicationSettings kulcs/érték-pár tárolási módszer a legcélravezetőbb megoldás. 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, akkor a mobilon a munkát egyszerűbbé tehetjük számára azzal, hogy ha már egyszer beírta, a háttérben eltároljuk ezt a felhasználónevet. Ha később újra elindítja az alkalmazást, akkor a korábban megadott és eltárolt felhasználónévvel automatikusan ki lesz töltve az adott szövegdoboz.

Nézzük meg példákon keresztül:

Először is szükségünk lesz a System.IO.IsolatedStorage névtérre:

using System.IO.IsolatedStorage;

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, ebben az esetben az első paraméter egy kulcs, aminek egyedinek kell lennie. Ha már létezik a kulcs, akkor egy System.ArgumentException-t kaphatunk, a második paraméter pedig egy tetszőleges objektum lehet. Az alábbi példában egy egyszerű stringet láthatunk:

// Felhasználónév hozzáadása – Új kulcs létrehozása

IsolatedStorageSettings.ApplicationSettings.Add("UserName", "Attila");

Mivel ez egy Dictionary, ezért a rá vonatkozó szabályok élnek, í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). Az indexeres megoldásnál, ha az adott kulcs nem létezik, akkor az létrejön; abban az esetben, ha már létezik a kulcs, akkor a tartalmát felülírja a meghatározott értékkel.

// Felhasználónév mentése /vagy módosítása

IsolatedStorageSettings.ApplicationSettings["UserName"] = "Attila";

Az adott kulcsok értékét persze le is kérdezhetjük, ehhez is használhatunk két módszert: az egyik az itt bemutatott indexeres módszer:

var userName = IsolatedStorageSettings.ApplicationSettings["UserName"];

A másik lehetőség a TryGetValue metódus használata:

string userValue;

IsolatedStorageSettings.ApplicationSettings.TryGetValue<String>("Kulcs", out userValue);

Az Indexeres módszer esetén, ha a kulcs nem található meg a szótárban, akkor egy KeyNotFoundException-t fogunk kapni, míg ha a TryGetValue metódust használjuk, nem kapunk hibát. Ebben az esetben, ha a kulcs nem létezik, akkor a userValue változó értéke üres (null) lesz. A TryGetValue nagyon hasonlít a TryParse metódusokra, amit a .NET-es típusoknál használhatunk. Ez is egy Boolean értékkel tér vissza: ha sikerült a kulcsot megtalálni és kiolvasni a tartalmát, akkor true-val, egyébként false-szal.

Abban az esetben, ha meg akarunk győződni arról, valóban létezik-e a kulcs, a Contains metódust használhatjuk fel. Ez a metódus true értékkel tér vissza, ha létezik az adott kulcs, false értékkel, ha nem.

if (IsolatedStorageSettings.ApplicationSettings.Contains("UserName"))

{

    //Létezik a UserName kulcs. Olvassuk ki pl. a tartalmát és irassuk ki

    MessageBox.Show(IsolatedStorageSettings.ApplicationSettings["UserNme"].ToString());

}

else

{

    //Nem létezik

    MessageBox.Show("Nincs ilyen kulcs!");

}

Az előző példákban csak egy egyszerű string adatot tároltunk el, de természetesen komplex objektumokat is eltárolhatunk az ApplicationSettings-ben. A következő példában egy saját osztályt hozunk létre, és azt tároljuk el, majd olvassuk ki. Ebben az esetben nem kell törődnünk az adatsorosítással, ezt az ApplicationSettings saját maga megoldja.

public class Person

{

    public string Name { get; set; }

    public int Age { get; set; }

}

 

Person myPerson = new Person()

{

    Name = "Jhon",

    Age = 32  

};

//Adat mentése

IsolatedStorageSettings.ApplicationSettings["PersonData"] = myPerson;

 

// Adat lekérdezése

Person newPerson = IsolatedStorageSettings.ApplicationSettings["PersonData"] as Person;

MessageBox.Show(newPerson.Name);

Az ApplicationSettings az alkalmazás bezárásakor elmenti az adatokat, viszont ha az alkalmazás futása közben nem várt hiba történik, és az alkalmazás leáll, ezek az információk nem kerülnek elmentésre. Ha biztosra szeretnénk menni, akkor ki kell kényszerítenünk a mentést az ApplicationSettings Save metódusával.

IsolatedStorageSettings.ApplicationSettings.Save();

A mentett adatokat persze el is távolíthatjuk az ApplicationSettings-ből. Eltávolíthatunk például egy kulcsot, ilyenkor a Remove metódust kell használnunk:

IsolatedStorageSettings.ApplicationSettings.Remove("UserName");

Ha az összes értéket el akarjuk távolítani, akkor a Clear metódust kell meghívnunk:

IsolatedStorageSettings.ApplicationSettings.Clear();

Mivel az ApplicationSettings egy szótár, ezért mind a kulcsokon, mind az értékeken végig tudunk haladni a foreach utasítással:

foreach (var key in IsolatedStorageSettings.ApplicationSettings.Keys)

{

    // Feldolgozás

}

 

foreach (var value in IsolatedStorageSettings.ApplicationSettings.Values)

{

    // Feldolgozás

}

Kategóriák:.NET, Windows Phone 7 Címkék: , ,

I/O műveletek

2012. május 1. kedd Hozzászólás

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. Ahogy a neve is mutatja, ez egy tárhely (Storage), ahol az alkalmazásunk képes írni, olvasni, valamint az általános fájlműveleteket is el tudja végezni. Minden alkalmazás kérhet magának egy-egy ilyen elkülönített tárhelyet, vagyis az alkalmazások nem férhetnek hozzá egymás tárhelyéhez. Minden alkalmazás csak a saját Isolated Storage-ében tud garázdálkodni, ott viszont úgy, ahogy csak szeretné. Közvetlen módon tehát nem érhetjük el a teljes fájlrendszert, csak és kizárólag az alkalmazásunk által használt Isolated Storage-ünket, így más alkalmazások semmilyen módon nem befolyásolhatják az alkalmazásunk működését, ezzel növelve a biztonságot és a fájlkárosodás elkerülését. A Windows Phone 7 Isolated Storage megoldása nagyon hasonló a Silverlightos Isolated Storage megoldásához, mindössze annyi a különbség, hogy itt nincs megszabva kvóta, mint a Silverlightnál, vagyis itt egy alkalmazás korlátlanul gazdálkodhat a tárhellyel.

De sok szóbeszéd helyett, nézzünk egy példát:

Minden I/O műveletet használó alkalmazásnál szükségünk lesz a System.IO és a System.IO.IsoltedStorage névtérre.

using System.IO.IsolatedStorage;

using System.IO;

Fájl írása: ahhoz, hogy egy új fájlt létrehozzunk, az IsolatedStorageFileStream osztályra lesz szükségünk. Ennek az osztálynak a példányosításakor kell meghatároznunk a fájl nevét és annak elérési módját (FileMode enumeráció), valamint át kell adnunk egy IsolatedStorage példányt is. Ebben az egyszerű példában egy fájlt hozunk létre, mely a „Hello World” szöveget tartalmazza:

IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

 

using (IsolatedStorageFileStream myFileStream = new IsolatedStorageFileStream("data.txt", FileMode.Create, isf))

{

    StreamWriter sw = new StreamWriter(myFileStream);

    sw.WriteLine("Hello World");

    sw.Flush();

    sw.Close();

}

A GetUserStoreForApplication metódus egy IsolatedStorageFile példányt ad vissza. A fájlba egy StreamWriter példány segítségével írhatunk. Ennek kell átadnunk egy Stream-et, ez ebben az esetben egy IsolatedStorageFileStream, majd a StreamWriter példány WriteLine metódusával írhatunk egy sort a fájlba.

A fájlból való olvasás hasonlóan egyszerű, annyi a különbség, hogy a FileMode ebben az esetben az Open értékét viseli, valamint egy StreamReader példányt használunk az olvasáshoz.

IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

 

using (IsolatedStorageFileStream myFileStream = new IsolatedStorageFileStream("data.txt", FileMode.Open, isf))

{

    StreamReader sr = new StreamReader(myFileStream);

    string text = sr.ReadToEnd();

    MessageBox.Show(text);

}

Nézzünk további gyakori I/O műveleteket:

Könyvtár létrehozáshoz a CreateDirectory metódust használhatjuk fel, ahol a metódusnak a könyvtár nevét adjuk át:

IsolatedStorageFile myISF = IsolatedStorageFile.GetUserStoreForApplication();

myISF.CreateDirectory("UjKonvtar");

Megadhatunk összetett könyvtár útvonalat is:

myISF.CreateDirectory("Folder1/Folder2/Folder3/UjKonvtar");

Egy könyvtár törlése is legalább ilyen egyszerű, ehhez a DeleteDirectory metódust használhatjuk fel:

myISF.DeleteDirectory("UjKonvtar");

Kategóriák:.NET, Windows Phone 7 Címkék: , ,

Pivot és Panoráma

2012. április 30. hétfő Hozzászólás

A Pivot és a Panoráma két nagyon gyakran használatos vezérlő. Lehetőséget biztosít, hogy a tartalmakat kategorizálva horizontálisan elnyújtsuk.

image

A két vezérlő használata nagyon hasonló, így ezt egy panoráma vezérlőn keresztül fogjuk megnézni. Ez a két vezérlő annyira népszerű, hogy külön elrendezési sablonja van.

A következő példában egy egyszerű panoráma vezérlőn alapuló alkalmazást fogunk létrehozni, de annyival megspékeljük a dolgot, hogy egy animációt is elhelyezünk benne, mégpedig a panoráma hátterét fogjuk módosítani, ráadásul most az animációt kódból fogjuk létrehozni!

1. Készítsünk egy új Windows Phone Panorama Aplication-t!

image

2. Az alkalmazássablon már eleve tartalmaz egy Panoráma vezérlőt. Mivel a háttér képét is szeretnénk módosítani, készítsünk egy új mappát a solution explorer-ben! A mappa neve legyen „Images” (Add -> New Folder)! A mappába helyezzünk el két képet! Az én esetemben ez most img1.jpg és img2.jpg. A képek Build Action-jét állítsuk Content-re!

3. Nyissuk meg a MainPage.xaml fájlt! A griden belül (LayoutRoot) látható, hogy van egy panoráma control. Ennek a vezérlőnek adjuk a „panorama” nevet, a Title pedig legyen most a „Windows Phone” szöveg!

<controls:Panorama x:Name="panorama" Title="Windows Phone">

Ez a panoráma vezérlő legfelső címkéjét cseréli. Figyeljük meg, hogy a Panoráma vezérlő egy vagy több PanoramaItem-et tartalmazhat! Ezek a PanoramaItem-ek egy vezérlőt tudnak magukba foglalni, ami persze lehet egy elrendezésvezérlő is.

4. Vegyük szemügyre az első PanoramItem-et! A Header-jét írjuk át beállításokra, és a benne található vezérlőt töröljük, majd helyezzünk el benne egy gridet, amibe egy egyszerű gombot dobjunk fel! A gomb content-je legyen a „Háttér módosítása” szöveg! Kattintsunk kétszer a gombra, hogy betöltsük a klikk eseményét! A XAML valahogy így fog kinézni:

<controls:PanoramaItem Header="Beálltítások">

    <Grid>

<Button Content="Háttér módosítás" Height="72" HorizontalAlignment="Left" Margin="20,215,0,0" Name="button1" VerticalAlignment="Top" Width="307" Click="button1_Click" />

    </Grid>

</controls:PanoramaItem>

Az esemény törzsét még hagyjuk üresen, és térjünk vissza a MainPage.xaml-jéhez!

5. A Panoráma vezérlőnknek most változtassuk meg a hátterét, és az alapértelmezett kék kép helyett állítsuk be a korábban hozzáadott img1.jpg-t!

<controls:Panorama.Background>

    <ImageBrush ImageSource="/Images/img1.jpg"/>

</controls:Panorama.Background>

6. Most már kipróbálhatjuk az alkalmazást. Indítsuk el, és nézzük meg, mi lesz ennek az eredménye!

7. Szép ez az alkalmazás, de szeretnénk kicsit látványosabbá varázsolni. Nyissuk meg a MainPage.xaml.cs fájlt! Első körben oldjuk fel a System.Windows.Media.Imaging névteret:

using System.Windows.Media.Imaging;

8. Készítsünk egy Fade In / Out animációt! Ezt kódból a következőképpen fogjuk megtenni:

private void FadeInOut(DependencyObject target, Storyboard sb, bool isFadeIn)

{

    Duration d = new Duration(TimeSpan.FromSeconds(1));

    DoubleAnimation daFade = new DoubleAnimation();

    daFade.Duration = d;

    if (isFadeIn)

    {

        daFade.From = 1.00;

        daFade.To = 0.00;

    }

    else

    {

        daFade.From = 0.00;

        daFade.To = 1.00;

    }

    sb.Duration = d;

    sb.Children.Add(daFade);

    Storyboard.SetTarget(daFade, target);

    Storyboard.SetTargetProperty(daFade, new PropertyPath("Opacity"));

    sb.Begin();

}

9. A gomb klikk esemény törzsébe példányosítsunk egy Storyboard-ot! Iratkozzunk fel annak a Completed eseményére, majd hívjuk meg a FadeInOut metódust (első paramétere egy DependencyObject, ami ebben az esetben a panoráma háttere, második paramétere a storyboard, harmadik pedig egy bool, amivel az animáció típusát határozzuk meg (FadeIn true vagy FadeOut false)).

Storyboard sbFadeIn = new Storyboard();

sbFadeIn.Completed += new EventHandler(sbFadeIn_Completed);

FadeInOut(panorama.Background, sbFadeIn, true);

10. Most már csak a storyboard Completed eseményének a törzsét kell megírnunk. Itt létrehozunk egy BitmapImag-et, amit átadunk egy ImageBrush-nak. Ezt követően megint készítünk egy Storyboard-ot, és meghívjuk a FadeInOut metódust, csak most FadeOut rész fog lefutni.

void sbFadeIn_Completed(object sender, EventArgs e)

{

    BitmapImage bmp = new BitmapImage(

        new Uri("/Images/img2.jpg", UriKind.Relative));

    ImageBrush imgBrush = new ImageBrush();

    imgBrush.ImageSource = bmp;

 

    this.panorama.Background = imgBrush;

    Storyboard sbFadeOut = new Storyboard();

    FadeInOut(this.panorama.Background, sbFadeOut, false);

}

11. Indítsuk el az alkalmazást, és nézzük meg működés közben!

image

Kategóriák:.NET, Windows Phone 7 Címkék: , ,

Animáció létrehozása – Kódból

2012. április 27. péntek Hozzászólás

Animációt nemcsak XAML-ben lehet készíteni, bár fontos megemlíteni, hogy legtöbbször XAML-ben tesszük. Kódból leginkább csak elindítunk egy-egy animációt, viszont olykor előfordulhat, hogy mégis kódból kell animációt létrehoznunk. Ez ugyan körülményesebb, mint a XAML, de olykor ez kifizetődő. Az animáció tulajdonképpen időegység alatt bekövetkezett tulajdonságváltozás. Annak, hogy mit változtatunk, nagyon fontos szerepe van: ha méretet, áttetszőséget vagy olyan tulajdonságot, ami double típusú, akkor a DoubleAnimation osztályt fogjuk használni. Ha például színt szeretnénk animálni (azaz olyan tulajdonságot, ami valamilyen színnel kapcsolatos), akkor a ColorAnimation osztályt fogjuk használni erre a célra. Persze ezenkívül még jó néhány animációs osztály áll a rendelkezésünkre.

A következő példában egy gombot fogunk animálni.

1. Készítsünk egy új Windows Phone 7 alkalmazást!

2. A felhasználói felületre dobjunk fel egy gombot, a gomb neve legyen a btnAnim, a Content-je pedig az „Animáció” szöveg! Kattintsunk kétszer a gombra!

3. A klikk esemény törzsébe először példányosítsunk egy DoubleAnimation példányt, ez az animáció a btnAnim méretét (szélességét) fogja befolyásolni. Először megmondjuk, hogy 1-től (From) megy 200-ig (To) (ebben az esetben pixelig) az animáció. A Duration tulajdonságnál megmondjuk, hogy ez az animáció ebben az esetben három másodpercig fog tartani.

DoubleAnimation dAnimation = new DoubleAnimation();

dAnimation.From = 1;

dAnimation.To = 200;

dAnimation.Duration = TimeSpan.FromSeconds(3);

4. Ezt követően készítsünk egy Storyboard példányt, aminek átadjuk az általunk készített animációt, valamint beállítjuk, hogy az animációt melyik vezérlőn akarjuk elindítani (SetTarget) és a vezérlőnek melyik tulajdonságát akarjuk majd változtatni, (SetTargetProperty), végül meghívjuk a Begin metódust, amivel az animáció elindul.

Storyboard sb = new Storyboard();

sb.Children.Add(dAnimation);

Storyboard.SetTarget(dAnimation, btnAnim);

Storyboard.SetTargetProperty(dAnimation, new PropertyPath("Width"));

sb.Begin();

5. Indítsuk el az alkalmazást, és próbáljuk ki működés közben!

Kategóriák:.NET, Windows Phone 7 Címkék: , ,

Animáció létrehozása – XAML (ProgressBar)

2012. április 26. csütörtök Hozzászólás

Amikor elkezdünk fejleszteni Windows Phone 7 alá, a kezdő fejlesztő gyakran belefut abba a hibába, hogy szeretne animációs gif-et használni a felületen, ezt viszont a Windows Phone 7 nem támogatja. Megjeleníti ugyan a képet, de csak az első képkockáját. Sokszor a fejlesztő a weben ajax és jQuery világában megismert folyamat jelzéseket szeretné alkalmazni, de nem tudja.

image

Hogyan lehetne ezt a problémát megoldani? Itt bizony kreativitásra és kitartásra lesz szükségünk! Az alábbi példán egy körbe-körbe futó progressbar-t készítünk el. Ezt egy Canvas-en fogjuk megrajzolni, majd ezt fogjuk elforgatni. Itt látható a pörgő loading készen, XMAL-ben (ezt célszerű egy külön vezérlőbe elhelyezni). Figyeljünk rá, hogy most fekete színű körökből épül fel, ezt az alkalmazásunknak megfelelően változtatni kell!

<Canvas RenderTransformOrigin="0.5,0.5" Width="120" Height="120">

                <Ellipse Width="21.835" Height="21.862" Canvas.Left="20.1696" Canvas.Top="9.76358" 

        Stretch="Fill" Fill="#E6000000"/>

                <Ellipse Width="21.835" Height="21.862" Canvas.Left="2.86816" Canvas.Top="29.9581" 

        Stretch="Fill" Fill="#CD000000"/>

                <Ellipse Width="21.835" Height="21.862" Canvas.Left="5.03758e-006" Canvas.Top="57.9341" 

        Stretch="Fill" Fill="#B3000000"/>

                <Ellipse Width="21.835" Height="21.862" Canvas.Left="12.1203" Canvas.Top="83.3163" 

        Stretch="Fill" Fill="#9A000000"/>

                <Ellipse Width="21.835" Height="21.862" Canvas.Left="36.5459" Canvas.Top="98.138" 

        Stretch="Fill" Fill="#80000000"/>

                <Ellipse Width="21.835" Height="21.862" Canvas.Left="64.6723" Canvas.Top="96.8411" 

        Stretch="Fill" Fill="#67000000"/>

                <Ellipse Width="21.835" Height="21.862" Canvas.Left="87.6176" Canvas.Top="81.2783" 

        Stretch="Fill" Fill="#4D000000"/>

                <Ellipse Width="21.835" Height="21.862" Canvas.Left="98.165" Canvas.Top="54.414" 

        Stretch="Fill" Fill="#34000000"/>

                <Ellipse Width="21.835" Height="21.862" Canvas.Left="92.9838" Canvas.Top="26.9938" 

        Stretch="Fill" Fill="#1A000000"/>

                <Ellipse Width="21.835" Height="21.862" Canvas.Left="47.2783" Canvas.Top="0.5" 

        Stretch="Fill" Fill="#FF000000"/>

   <Canvas.RenderTransform>

      <RotateTransform x:Name="SpinnerRotate" Angle="0" />

   </Canvas.RenderTransform>

   <Canvas.Triggers>

     <EventTrigger RoutedEvent="ContentControl.Loaded">

      <BeginStoryboard>

       <Storyboard>

        <DoubleAnimation Storyboard.TargetName="SpinnerRotate" 

          Storyboard.TargetProperty="(RotateTransform.Angle)" 

          From="0" To="360" Duration="0:0:01" 

          RepeatBehavior="Forever" />

       </Storyboard>

     </BeginStoryboard>

  </EventTrigger>

 </Canvas.Triggers>

</Canvas>

Az eredménye:

image

Kategóriák:.NET, Windows Phone 7 Címkék: , ,