Zoltán's profileÁrvai Zoltán BlogjaBlogLists Tools Help

Blog


    July 25

    Silverlight 3.0 újdonságok – Adatkötés UI elemekhez

    A WPF-en is fejlesztő kollegák roppant mód hiányoltak egy fontos fícsört a Silverlight-ból, még pedig azt, hogy nem lehetett két vezérlőt “összeadatkötni” (de szép magyarul volt ez :) ) Így közvetlenül Master-Details szituációk kialakítása pl nem lehetséges, csak közvetett property-k segítségével (mondjuk a ViewModel-ből)

    Silverlight 3.0-tól kezdve támogatott az Element to Element binding, így a WPF fejlesztők is végre elégedettek lehetnek. Íme egy nagyon egyszerű demonstratív példa:

    image

    A fenti példában egy Slider Value tulajdonságát adatkötjük a rectangle elnevezésű téglalap (ElementName tulajdonságon keresztül) Effect.DropShadow tulajdonságához (Path Property-vel meghatározva, tekintve, hogy az Effect mögött egy DropShadowEffect rejtőzik). Az eredmény a következő:

    image

    A Slider-t mozgatva a Value property-jének változása azonnal reflektálódik a rectangle-höz kapcsolt DropShadowEffect-en is a binding következtében.

    Amint látjuk, ez egy roppant egyszerűen alkalmazható, de annél lényegesebb újdonság. Képzeljük el, hogy egy datagrid vagy egy listbox SelectedItem tulajdonságához kötjük egy DataForm CurrentItem tulajdonságát, ezáltal egyfajta Master-Detail Scenario-t létrehozva.

    A kis DemoProject letölthető innen:

    July 22

    Binding Source frissítése TextBox.TextChanged esetén

    Silverlight 3.0-ban használhatjuk az Binding objektum UpdateSourceTrigger property-jét annak érdekében, hogy meghatározzuk, mikor kerüljön vissza az adat a bekötött property-be..

    Az UpdateSourceTriggernek két értéke van:

    1. Default
    2. Explicit

    Nos, ha TextBox-ról van szó, akkor rendkívül zavaró, hogy a frissítés csak akkor történhet meg, ha a vezérlő elveszíti a fókuszt. (A “Default” UpdateSourceTrigger mód gyakorlatilag LostFocus). Namost WPF-ben volt olyan mód is, hogy UpdateSourceTrigger.PropertyChanged, ami azt jelentette a TextBox-nál, hogy TextChanged esetén az adatot azonnal visszaírja a property-be. Silverlight 3.0-ban a PropertyChanged mód nem támogatott.

    Egy lehetséges workaround lehet hogy készítünk egy Behavior-t a TextBox számára.
    Az alábbi ábrán látható egy lehetséges megoldás:

    image

    És a magyarázat:

    Amikor egy Behavior-t hozzácsatolunk az objekutmhoz, ebben az eseten ez csak egy TextBox lehet, az OnAttached() metódus lefut.

    A metódus törzsében feliratkozunk a textbox TextChanged eseményére. Az AssociatedObject maga a textbox példány. Namost, amikor a TextChanged esemény bekövetkezik, az AssociatedObject_TextChanged eseménykezelő rutin lefut. Ez a metódus megszerzi a binding objektumot, amit a TextBoxunk Text property-jéhez definiáltunk, majd explicit módon kikényszeríti a forrás frissítését.

    Az OnDetaching() metódus akkor fut le, hogy ha a Behavior-t eltávolítjuk. A mi esetünkben az ehhez tartozó kódblokk, a TextChanged eseményről való leiratkozást jelenti.

    Most irány az Expression Blend 3.0. Az assets panelen keressük meg az új UpdateOnTextChangedBehavior-ünket és drag & drop-pal húzzuk rá a kiszemelt textbox-ra. Ennyi, már működik is.

    image

    A xaml a következőképp néz ki.

    image

    A kódfájl letölthető innen:

    July 20

    Silverlight 3.0 újdonságok – Navigation Framework

    Webes világban megszoktuk, hogy olyan klasszul lehet a linkeket passzolgatni egymás között, így mindig a megfelelő aloldal nyílik meg. Fontos ez a különböző WebCrawler-ek számára is. Azonban a Flash és a Silverlight jellegű alkalmazásoknál ez nem ilyen egyszerű. Az oldalon belüli navigáció nem volt köthető linkhez, adott link beírásával pedig nem jutottunk el egy silverlight aloldalhoz. Legalábbis irtó meló volt ilyen megoldásokat készíteni.

    Silverlight 3.0-ban megérkezett a Navigation Framework, aminek segítségével a fenti problémákat könnyen áthidalhatjuk.

    A Navigation Framework 2 fő objektumot tartalmaz:

    • Page – Egy adott oldal, amire navigálhatunk
    • Frame – A keret, amin belül a navigáció zajlik, ebben jelennek meg az egyes page-ek.

    Hozzunk létre egy NavigationDemo nevű Silverlight Application-t.

    A demo letölthető innen:

    Majd egy Pages Folder-be adjunk hozzá új Silverlight Page komponenseket. (HomePage, ProductsPage, ContactPage)

    clip_image001

    A MainPage-en alakítsuk ki a következő layout-ot:

    clip_image001[6]

    Megkaptuk a jobb felső sarokban a 3 menüpontot. A terület nagy érszét a frame fedi le, ebbe kerülnek majd az egyes Page-ek.
    Következő lépésben a HyperlinkButton-ok NavigateUri property-jét állítsuk be, hogy a megfelelő xaml oldalra navigáljanak el:

    clip_image001[8]

    Az egyes Page-ek belsejébe helyezzünk el egy mezei TextBlock-ot, az adott oldalra jellemző egyszerű felirattal, hogy lássuk valóban a navigáció sikerül a frame-ben.

    clip_image001[10]

     

    Na haladjunk szép sorjában:

    1. Jól látható, hogy a böngésző címsorában a Termékek szó szerepel. Ez annak köszönhető, hogy a ProductsPage.xaml-ben a Page Title Propertyjét a “Termékek” stringre állítottam.
    2. Az Url mezőben látható, hogy a Pages mappában található ProductsPage.xaml-ben vagyunk! A linket kimásolva, és egy másik böngészőben megnyitva, ugyanezt a látványt kapjuk, nem kell a HomePage-ről idenavigálnunk! Yay!
    3. Látszik a Frame contentje a megfelelő Page-re változott. Jelenesetben a ProductsPage-ben elhelyezett TextBlock látszik.
    4. A navigációs menünk pedig változatlan, hiszen a framen kívül helyezkedik el. A Products link pedig a kiválasztott!
    5. Az alábbi ábrán látható, hogy bizony a böngésző előre hátra gombjainak segítségével navigálhatunk a korábban megnyitott oldalak között, azaz van history támogatásunk is a silverlight alkalmazásunkon belül!!

    clip_image001[16]

    A link azonban elég csúnya, ennél kultúráltabb URL routingot is el lehet képzelni. Szerencsére a megoldás adott, az ún. UriMapper-ek segítségével. A csúnya URL-ünkhöz egy szép kultúrált elérési útvonalat mappelhetünk le. (meglátjuk később, hogy a szépségnél jóval nagyobb jelentősége is van a dolognak.)

    Irány hát az Application.Resources az App.xaml fájlban és készítsünk ilyen klassz kis mappingeket. Az UriMapper a System.Windows.Navigation namespace-ben található a System.Windows.Controls.Navigation assembly-ben.

    image

    Most, hogy kész a Mapping, visszamehetünk és a NavigateUri property-ket átírhatjuk a rövid verzióra:

    image

    Egy apróság maradt hátra, értesíteni kell a Frame-et, hogy használja az imént definiált UriMappert a feloldásra. Ezt a Frame UriMapper property-jének segítségével tehetjük meg. A korábban létrehozott “mapper” resource-ot hivatkozzuk meg:

    clip_image001[12]

    Az alkalmazást futtatva látjuk, hogy sokkal kultúráltabb a böngészőben megjelenő URL:

    clip_image001[14]

    Ennek az erőnek a birtokában nézzünk egy Master-Detail szituációt, amolyan “querystring-esen”. Készítsünk egy új Page-et ProductDetailsPage néven. A ProductsPage.xaml oldalon helyezzünk el egy listboxot és töltsünk bele Product-okat:

    clip_image001[18]

    A code-behind:

    image

    Na mit látunk? Loaded eseménykor betöltjük a Product-okat (lent a Product osztály definíciója).

    image

    A gombra klikkelve a listboxból kiolvassuk a kiválaszott termék id-ját. Majd a Page.NavigationService property-jének segítségével átnavigálunk a ProductDetails oldalra, mindezt úgy, hogy mögé egy “/” jel után az azonosítót odabiggyesztjük. Ez jelenleg nem sok értelemmel bír az SL alkalmazásunk számára. De most már sejtjük, hogy mi a teendő. UriMappinget kell készítenünk:

    clip_image001[22]

    Látjuk, hogy Querystring jellegű url-t mappelünk le a korábban meghivatkozott url-re. A “{}” jelek közé helyezett text, egyfajta helyettesítőként funkcionál. Jelenesetben a query string értéke az új url-ben a “Products/” után következhet.

    A navigáció megvan, mostmár csak a részletező oldalt kell elkészíteni, 3 adatkötött textblock jeleníti meg a Product adatait:

    image

    code-behind:

    image

    Az OnNavigatedTo függvény az adott oldara történő navigáció után fut le. A Page.NavigationContext property-n keresztül elérhető a QueryString! (ugye a mapping kitakarja) A mezőt kiolvasva kikeressük a megfelelő terméket, a többi pedig már csak sima adatkötés!

    Nézzük az eredményt:

    clip_image001[24]

    Böngészőből nyugodtam próbáljuk ki, hogy változtatgatjuk a linket:

    http://localhost:24764/NavigationDemoTestPage.aspx#ProductDetails/1
    http://localhost:24764/NavigationDemoTestPage.aspx#ProductDetails/2
    http://localhost:24764/NavigationDemoTestPage.aspx#ProductDetails/3

    Az adott ID-hoz tartozó termékek mind megjelennek. A Silverlight 3.0-ban megjelent Navigation Framework, így egy elég régi Silverlight problémát old meg. Talán már sejthető, hogy miként, de a következő bejegyzésben megnézzük, hogyan tudjuk mindezt alkalmazni SEO támogatásra.

    Ha van bármi kérdésetek, írjatok nyugodtan.

    Silverlight 3.0 újdonságok - Áttekintés

    Ez a kis cikk sorozat a Silverlight 3.0-ban megjelent újdonságokat igyekszik áttekinteni. Mielőtt az egyes témákba mélyebben belemennénk, nézzük miről is beszélünk. Az újdonságokat 4 csoportba sorolnám:

    1. Application Framework újdonságok
      • Navigation Framework, Search Engine Optimization
      • Adatkötés UI elemek között
      • Out of Browser képességek
      • Network Monitoring API
      • Local Messaging API
      • Új validációs támogatás
      • Assembly Caching
      • SaveFileDialog ablak
      • Szolgáltatás támogatás (Binary XML, RIA Services….)
      • Stílusok, CaretBrush és merged resource dictionary-k
    2. Tools Support
      • Blend 3.0 + SketchFlow Release Candidate
        • Blend API (Behaviors, Actions)
        • Adobe Photoshop és Illustrator Import
        • SampleDataSource
        • Intellisense és C# code editor
        • TFS Support
    3. Grafikai újdonságok
      • 3D-s támogatás
      • Pixel Effect-ek használata
      • GPU gyorsítás
      • Bitmap API
      • Szöveg kezelési újdonságok
      • Animációs újdonságok (easing)
      • Media kezelés újdonságok
        • TrueHD támogatás
        • RAW Audio és Video bitstream api
        • H.264 / AAC és MPEG-4 támogatás
        • Smooth Streaming (Smooth HD) – IIS Media Services

        És persze amellett sem mehetünk el, hogy a Silverlight 3-hoz megjelent a júliusi Silverlight Toolkit, amiben olyan nagyszerű vezélőket használatunk, mint:

        • DockPanel / WrapPanel
        • ViewBox
        • DataPager
        • DataForm
        • TreeView
        • AutoCompleteBox
        • ChildWindow
        • Accordion
        • Expander
        • Calendar

        A lista nem rövid. Remélhetőleg, mindenki talál magában benne igazi csemegét :)

        (A linkelés folyamatosan történik, ahogy az egyes postok elkészülnek!)

        July 17

        RIA Nuggets – DataPaging Issues

        Ma reggel RIA Services-t mutogattam és bátor oktató módjára demonstrálni akartam a késleltetett betöltést. (amit amúgy én nem nagyon használgattam még, mert voltak vele gondok korábbi ctp-kben) Valami ilyesmi kódom volt:

        clip_image001

        Aztán baromira meglepődtem, mert az előre betöltött 20 elemem pompásan megjelent, aztán a 3. oldalon 20-30ig és felette már semmi… Soha nem jött meg az adat. Néztem csak nagyokat. Végül elkönyveltem magamban, hogy bug :)

        Aztán hazajöttem és megpróbáltam reprodukálni… sikerült… Rá kellett döbbeni, hogy ez bizony nem megy. Aztán elkezdtem picit dühös lenni, hogy “nehogymánezmijezmá” :)

        Kicsit alaposabban beledebuggoltam, majd egy érdekes hibaüzenetet sikerült találnom:

        “The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.”

        Ó igen… Entity Framework-öt használok, a DataPager meg lapozáshoz a Skip és Take-et használja, amiket csak rendezett listán lehet hívni… defaultból pedig ez nem az… szóval, így kellet módosítani a GetCustomers műveletet a DomainService-emben:

        image

        Mostmár pompásan működik!

        De ez miért nincs sehol rendesen ledokumentálva? Vagy csak az én figyelmem kerülte el?

        July 14

        Beárazták az Azure-t

        Megjött a várva várt hír. A Microsoft bejelentette, hogy pontosan mibe is fog kerülni alkalmazásaink és adataink hosztolása az MS felhőjében. Vessünk hát egy pillantást az árlistára:

        1. Windows Azure
          • Processzor idő: 12 cent / óra
          • Azure Storage: 15 cent / GB
          • Azure Storage felé tranzakciók: 1 cent / 10.000 tranakció (CRUD)
        2. SQL Azure (SDS)
          • Web Edition 1GB tárhellyel: 9.99 dollár
          • Busines Edition 10GB tárhellyel: 99.99 dollár
        3. .NET Services
          • Service Bus és Access Control tokenek, Üzenetek: 15 cent / 100.000 üzenet
        4. Extra költségek:
          • Hálózati erőforrások használata (sávszél:D):
            • Bejövö adatforgalom: 10 cent / GB
            • Kimenő adatforgalom: 15 cent / GB

        Emellé a Microsoft 99.95%-os rendelkezésre állást ígére, valamint 99.9%-os megbízhatóságot, ami a storage-et illeti.

        Ugyanakkor szeretném felhívni minden induló, vagy friss vállalkozás vezetőit, hogy a BizSpark program keretében hozzájuthatna ingyen Azure account-hoz, ami sok ezer órát tartalmaz!

        Ti, hogy látjátok? Hogy tetszik az árfekvés?

        July 13

        RIA Services 101 – Alapok

        Blogomat tekintve, talán nem titok senki számára, hogy kiemelt fontossággal bír számomra az adatkezelés és a szolgáltatások világa. A Silverlight és a WPF előretörésével, ahol a kliens lassan kezd a szín tiszta UI-ban kimerülni és inkább egy szolgáltatás orientált megközelítéssel mindent egy szolgáltatás fölé pakolni, megjelent a “hangya probléma”. Szorgos kis hangyák módjára kell ezredszer is az adatbázisban tárolt adatokhoz valamiféle CRUD-képes (Create/Read/Update/Delete) felületet készítenünk és szolgáltatásként kipublikálni. Persze minden adott, itt a WCF, itt az Entity Framework, vagy a Linq To Sql vagy bármi más. Ahogy közeledünk a .NET 4-hez egyre inkább elvárjuk az ilyen jellegű feladatok automatizálását, szolgáltatás rétegek legenerálását. Folyton harcolunk az olyan problémákkal, mint az authentikációs, authorizációs kérdések, a middle-tier és a client-tier közötti kódmegosztás (linking?) vagy a validációs, konkurrens műveletek, illetve a tranzakciók kezelése. A fentiek szellemében egy igazi gyöngyszemet szeretnék bemutatni.

        Sokat hangsúlyozzuk, hogy a Silverlight 3.0 végre egy igazi Line Of Business alkalmazásfejlesztési platform. Azonban ezt a címet csak a fenti problémák megoldására született .NET RIA Services-zel együtt érdemelheti ki. A cikk írásának pillanatában a RIA Services July Preview az aktuális és az első olyan verzió, amely nem rendelkezik már go live megkötésekkel.

        A .NET RIA Services célja, hogy leegyszerűsítse az n-rétegű alkalmazások fejlesztését, az ASP.NET (szerveroldal) és a Silverlight(kliensoldal) egymáshoz való közelítésével.

        image_6

        A rövid bevezető után készítsük el a RIA Services “Hello World”-jét.

        Egy új Silverlight Application projectet készítünk, és az első felugró ablakunk már tartalmaz némi érdekességet. Egy checkboxot.

        clip_image001

        “Enable .NET Ria Services”. Ez az ún. RIA Link. A Silverlight kliens és a Web alkalmazás között rögzíti a köteléket.

        Az ASP.NET site-hoz adjunk egy Entity data model-t. Én a northwind adatbázis Products tábláját fogom a designer felületre húzni. Majd új elemet veszünk fel, mégpedig egy Domain Service Class-t.

        clip_image001[6]

        A következő dialógus az iránt érdeklődik, hogy mit szeretnénk publikálni a Domain Service-ünk által, és hogyan.

        clip_image001[8]

        Az Enable Client Access checkbox-ot bepipálva, a szolgáltatáshoz megfelelő kliens kontextus kerül legenerálásra. A Products entitás halmazhoz szeretnénk read-only hozzáférést biztosítani.

        A generált osztály magáért beszél:

        clip_image001[10]

        A ProductService-ünk a LinqToEntitiesDomainService<> generikus osztályból származik, ami alapvetően a DomainService ősosztályból. Tetszőleges adatforráshoz készítheztő specifikus DomainService class. Kliensből hozzáférhető ([EnableClientAccessAttribute])
        Egy tagfüggvényünk van a GetProducts, amely visszatérési értéke IQueryable<>, amely jelzi, hogy a lekérdezések összefűzhetők lesznek, valamint a metódus törzsében egy linq to entities kifejezés áll. A függvény törzse tetszőleges módon kiegészíthető egyéb logikával, szűréssel, rendezéssel, stb…

        Most jön az izgalmas rész: F6 (Build)

        clip_image001[12]

         

        A kliens oldalon kódgenerálással előállt a ProductContext osztály (DomainContext leszármazott). Ez a class közvetlen hozzáférést biztosít a szerveroldalon definiált DomainService-hez.
        A ProductContext osztályban számos érdekességre bukkanunk:

        clip_image001[14]

        Az EntityList egy adatkötéshez gazdag funkcionalitással rendelkező speciális gyűjtemény. A GetProducts DomainService műveletünkhöz készült egy GetProductsQuery() függvény, amelynek segítségével komplex lekérdezéseket készíthetünk. Minden DomainContext-hez tartozik egy EntityContainer, amely a változás követés menedzsmentjéért felelős. Az ábrán látható, hogy a container, olyan entitás listát készít a Products számára, amely az entitásokhoz csak olvasható (perzisztálás szempontjából) hozzáférést biztosít. (EntityListOperations.None)

        A generált entitás osztályok a szokásos “kellemes” módon működnek:

        1. Számos bekapcsolódási pontot kínálva partial metódusok által
          • On[PropertyName]Changing(value)
          • On[PropertyName]Changed()
        2. És a megfelelő interfaceket impelementálva Entity ősosztályból származva:
          • INotifyPropertyChanged
          • IEditableObject
          • IChangeTracking
          • IRevertibleChangeTracking

        (ez utóbbiakat szívesen használja pl a DataForm)

        Ezek után írjuk meg az első lekérdezésünket.

        MainPage.xaml.cs (Code-Behind)

        clip_image001[16]

        MainPage.xaml

        image IE8 :)

        clip_image001[18]

        Látható, hogy RIA Services segítségével lekérdezések írása nem túlságosan bonyolult. Persze még nagyobb segítséget kapunk Silverlight esetén a DomainDataSource elnevezésű objektum által. A következő bejegyzésben a DomainDataSource-ot vesszük górcső alá.

        July 10

        SL 3.0 + Blend 3 Sketchflow RC + RIA Services July Preview

        És itt van az aranyeső :)

        Nézzük sorjában Silverlight 3

        Persze ez még csak fejlesztőknek szól. Nagyon tessék vigyázni, a blend 3 preview nem megy a végleges sl3-al!!! Tessék leszedni az RC-t! :)

        Expression Blend 3 + Sketchflow Release Candidate

        És igen, benne van a sketchflow is!

        Ria Services July Preview

        Ez sem maradhat ki, az okosok azt mondják, ez már go live ready, ugyanakkor az ado data serivces-zel való integráció használata még nem javasolt éles alkalmazásban!