czwartek, 9 września 2010

Windows Phone 7 Beta - cz. 3

W sumie trochę nie pisałem, więc postanowiłem teraz napisać kilka postów o Windows Phone 7.  Sporą część sierpnia bawiłem się wersją Beta, więc z pewnością dysponuję materiałem, z którego coś na post się nada. Różne kawałki kodu pisane, jakie powstały dla wypróbowania różnych funkcjonalności pogrupowałem sobie na 3 części. Zacznijmy dziś od … końca, czyli od udostępnionych funkcjonalności od wydania Beta, w tym sporo takich, które można zobaczyć w działaniu jedynie na fizycznym telefonie albo … odblokowanym emulatorze.  Post na temat części nr.1 i nr.2 (jak działają obecnie podstawowe i bardziej zaawansowane funkcjonalności wprowadzone przed Betą) napiszę wkrótce.  Po 16 września (dzień premiery finalnej wersji ze stosunkowo niewielką liczbą zmian + 3 nowe istotne kontrolki) oczywiście pomyślimy o kolejnych postach. 

Przegląd sampli bardziej niebanalnych zaczynam od szkicu prostej konsoli, za pomocą której można zmieniać głośność, rozkład kanałów na lewy i prawy oraz pitch.  Szczególnie ta ostatnia możliwość dostarcza dużo radości, nawet przy zapętleniu dość melancholijnej muzyki, którą wybrałem sobie do zapętlenia. Od strony technicznej efekty dźwiękowe realizuje XNA użyta z poziomu Silverlight.

01_SoundEffects_01

Następna rzecz, którą chciałbym zaprezentować to tzw. aplikacja Photo Extras. Posiadacz telefonu (albo odblokowanego emulatora) przeglądając obrazki może z menu kontekstowego wybrać opcję extras.

02_PhotoExtras_02

02_PhotoExtras_03

Pojawia się wtedy lista i na niej link do naszej aplikacji, która zostanie otworzona i wczytane zostanie do niej przeglądane zdjęcie (oczywiście aplikację możemy też normalnie otworzyć i wczytać do niej obrazki przez chooser).

02_PhotoExtras_04

Jak telefon rozpozna, że nasza aplikacja jest takiego typu? Kluczowy jest tu plik Extras.xml dołączany do projektu, w warunkach produkcyjnych dodatkowo dojdą wymogi certyfikacyjne np. co do przeznaczenia aplikacji. Ciekawie rozwiązali przekazywanie fotografii do aplikacji w tym trybie – w wydaniu Beta wykorzystują parametr file w nawigacji do strony startowej aplikacji oraz Isolated Storage.

Co robi moja aplikacyjka Photo Extras? Jest to … maszyna-szarzyna-:)

02_PhotoExtras_05

Kolorowe fotki zamienia na czarno-białe, a potem umożliwia ich zapisanie do kolekcji obrazków na telefonie.

02_PhotoExtras_06

Teraz kolejny przebój, czyli … radio? Czy można słuchać radia nie mając fizycznego telefonu? Dysponując odblokowanym obrazem okazuje się, że … można. Do radia dostaniemy się przez huba music+videos. Jeśli wcześniej słuchaliśmy jakieś stacji, zostanie wyświetlona w historii odtwarzania.

04_FmRadio_01

Skacząc po częstotliwościach, na niektórych są puszczane … samplowe nagrania imitujące różne stacje radiowe !!!

04_FmRadio_02

Słuchać stacji radiowych możemy również z poziomu naszych własnych aplikacji, co sprawdziłem na poniższym przykładzie. BTW domyślnie radio się włącza, więc  jawnie go ustawiam w stan wyłączenia po starcie aplikacji.

04_FmRadio_03

Następną rzeczą, którą dziś pokażę będzie aplikacja integrująca się z hubem music+videos.  Na czym ta integracja polega? Nasza aplikacja może dodawać tile do huba z informacją o aktualnie odtwarzanym utworze,

05_VideoHub_02

odtworzonych ostatnio multimediach,

05_VideoHub_03

jak, i o nowo dodanych pozycjach multimedialnych.

05_VideoHub_04

Na podstawie faktu używania API do zarządzania pozycjami z utworami, nasza aplikacja jest klasyfikowana jako współpracująca z hubem multimedialnym. Dla celów testowych należy ustawić jeszcze pewną opcję w manifeście aplikacji wskazaną przez dokumentację. Natomiast w produkcji należy spełnić dodatkowe kryteria certyfikacyjne np. główne przeznaczenie aplikacji. Po zaklasyfikowaniu aplikacji powinna się wyświetlać jej nazwa na liście marquee w hubie music+videos.

05_VideoHub_05

Zarówno kliknięcie w tile każdego rodzaju wskazujący na zasób multimedialny lub na pozycję z listy marquee powoduje uruchomienie naszej aplikacji.

Na koniec małe wyjaśnienie – w tym wypadku poszedłem na skróty i mój player jest … atrapą (nie gra!). Klikanie na piosenkach dodaje je do historii odtwarzania, a dolny link dodaje fikcyjny zasób multimedialny.

Jako ostatnią przedstawię rzecz, która powinna być … pierwszą, jeśli chodzi o istotę nowych właściwości w Becie. Bez zdjęć,  multimediów czy radia jakoś przeżyć jeszcze można, ale bez dokładnej znajomości cyklu życiowego aplikacji już nie! Na telefonie różne aplikacje nie działają tak naprawdę równocześnie, zawsze wykonuje się tylko 1 proces, co pozwala oszczędzać ograniczone zasoby mobilnego urządzenia. Użytkownicy jednak oczekują zachowania znanego im z obecnych komputerów. Co tu robić, co tu robić? A może by tak… upozorować działanie aplikacji, tak żeby po powrocie do niej użytkownika, sprawiała wrażenie, że cały czas działała. I po to wymyślono stan zombi. Przy tzw. deaktywacji proces jest ubijany, ale zostają zapamiętane związane z nim dane (np. dane w polach na formularzu, kontrolka z focusem itp.). Przy tzw. reaktywacji mamy doczynienia z innym już procesem, który wczytał dane zapamiętane przy deaktywacji. Oczywiście oprócz deaktywacji i reaktywacji mamy także uruchamianie oraz zamykanie aplikacji (które wykluczają się z tymi pierwszymi).

Kiedy aplikacja jest usypiana a kiedy zamykana, kiedy następuje jej reaktywacja, a kiedy uruchomienie w całości od nowa? Są na to precyzyjne wytyczne. Jak naciskamy klawisz Back na stronie startowej aplikacji, to ją zamykamy. Jak naciśniemy Start, to ją tylko zamieniamy w zombi. Jeśli potem powrócimy skądś klawiszem Back do tej aplikacji, to ją reaktywujemy. Jeśli aplikacja zostanie uruchomiona z linka na ekranie startowym, to zawsze jest uruchamiana od nowa. Przy okazji widzimy, że aplikacja ze stanu zombi może się już nie wybudzić.  Należy mieć też świadomość, że jeśli używamy launcher-ów i chooser-ów, to tak naprawdę ich procesy wypierają proces aplikacji, która je wywołuje i przejdzie ona w stan zombi. Po wybraniu np. zdjęć z huba Pictures nastąpi reaktywacja naszej aplikacji.

Odpowiednia obsługa chooserów wyszczególniona w dokumentacji pozwala nam z automatu otrzymywać pochodzące z nich dane tak naprawdę w innym już procesie. Do naszych zadań pozostaje zapamiętywać i odtwarzać inne dane naszej aplikacji, tak by użytkownik niczego się nie domyślił. Ciekawie w tej wydaniu wymyślili z debugowaniem. Jeśli przejdziemy w stan zombi, to debugowanie się kończy, bo nie ma już procesu. Ale jeśli nastąpi reaktywacja aplikacji, to … zobaczymy czarny ekran na emulatorze! Nie, to nie pomyłka, to celowe działanie. Jest nam dany pewien czas, abyśmy włączyli debugowanie na naszym projekcie jeszcze raz, a wtedy debugger rozpozna reaktywację i znajdzie odpowiedni proces.

Deaktywacja aplikacji występuje też jeszcze w innych sytuacjach (wygaszacz ekranu, rozmowa itd). Póki co najwięcej wiemy o sytuacji z wygaszaczem. Można też ustawić tutaj pewną zmienną, aby aplikacja nadal działała pod wygaszaczem. Pokazywano to m.in na TechEd w czerwcu.

Aby dopełnić tematyki związanej z cyklem życiowym, należy wspomnieć o sposobach przechowywania danych. Do przechowywania danych przeznaczonych do ostatecznego zapisu można używać Isolated Storage. Do przechowywania danych tymczasowych wykorzystuje się dostarczoną przez Microsoft kolekcję na poziomie całej aplikacji lub kolekcję widoku pojedynczej strony.  

Większość tych zagadnień sprawdziłem na poniższym przykładzie z formularzem, którego dane możemy zlecić do ostatecznego zapisania. Wtedy dane na formularzu pojawią się, także przy zupełnie nowym uruchomieniu aplikacji. Jeśli aplikacja zostanie uśpiona a potem reaktywowana, to nawet niezapisane dane w polach są odtwarzane.

06_LifeCycle_01 06_LifeCycle_02

Przykłady z wszystkimi wyżej opisanymi zagadnieniami, a nawet jednym więcej - komunikacja OData -  można ściągnąć tutaj:

Na zakończenie przydatne linki związane z obecnym wydaniem WP7

Blogi

Fora

Nie dodałem, że w kwestii dużych nowości w Becie wchodzą też nowe narzędzia czy nowe możliwości w dotychczasowych np. znacznie lepsze wsparcie dla designu w Blend. Odnośnie Blenda mogę polecić blog zespołu Expression, Kirupy, Jeffa Wilcoxa oraz materiały video z TechEda 2010 i Windows Phone Design Days. W kilku miejscach zostały pokazane rzeczy, które nie zostały jeszcze upublicznione (jak kontrolki Pivot, Panorama czy wczytywania flików .fxg)

piątek, 6 sierpnia 2010

WCF RIA SERVICES V1 - słów kilka …

Chciałbym napisać dziś słów kilka o WCF RIA Services. Dokładnego przeglądu standardowych scenariuszy wersji pierwszej finalnej dokonałem niejako publikując zaktualizowane przykłady w dwóch częściach (patrz cz.I i cz.II). I chociaż jest tam wiele fajnych funkcjonalności, to dziś napiszę o trochę mniej standardowych, rzadziej spotykanych rzeczach. 

Mam tu na myśli takie zagadnienia jak korzystanie z NHibernate, MVVM (jest to typowe podejście dla Silverlight, ale nie zawsze przykłady czy prezentacje wykorzystują ten wzorzec, choć ostatnio jakby częściej), lookupy, szablony T4, fluent metadata czy synchronizacja off-line. Na te tematy też można sporo powiedzieć, co udowodniłem w moim ostatnio napisanym poście o WCF RIA Services, gdzie je dokładnie przedstawiam. Teraz natomiast zasygnalizuję dwie rzeczy z tego posta, które mogą okazać się hitami, jeśli trafią do następnej wersji WCF RIA Services. Zresztą każda z wyżej wymienionych rzeczy byłaby hitem, ale te wybrałem …

No właśnie, a co może trafić do WCF RIA Services V2?  Team założył forum, na którym rozpisane są propozycje funkcjonalności. Można na nie głosować, tak więc zachęcam do głosowania, bo inaczej ktoś wybierze za nas i znów będzie ktoś narzekać -:)

Rzecz pierwsza – lookupy. Kto dysponuje uniwersalnym komponentem ładującym asynchronicznie dane dla lookupa dla dowolnego DomainContext-u, z obsługą kaskad (co przekłada się na ładowanie z parametrami w zależności od innych lookupów)  i powiązań między encjami (wartości nie-encyjnych oczywiście też)?

Każdy kto skorzysta z ComboboxDataSource, rozszerzenia dla lookupów opublikowane przez team WCF RIA Services! Co ciekawe jest to bardzo proste w użyciu, można wręcz całość zapisać w kilku linijkach XAML-a, nie kodu! 

02_Lookup_03

A gdzie view modele, dobre praktyki zakrzykną zwolennicy takich? A nie ma tutaj takich, ale czy przeszkadza się nam to cieszyć prostotą użycia powszechnie implementowanej funkcjonalności???  Zresztą niekoniecznie tak być musi, Jeff Handley opisał jak używać w view modelach kontrolkę DomainDataSource (jedynie AutoLoad i Element Binding nie działają) i trwają nad tym jakieś prace, więc pewnie podobnie będzie można powiedzieć o ComboBoxDataSource.

Rzecz druga – fluent metadata. A co to takiego? Ale najpierw, trochę wstępu …

Standardowo jak definiujemy metadane dla encji (walidacja, wygląd, itd.) w WCF RIA Services wyraża się je w większości w postaci standardowych atrybutów .NET i Silverlight. Następnie na ich podstawie są generowane atrybuty w encjach po stronie klienta (najczęściej 1:1, ale nie zawsze). Mamy też możliwość definiowania własnych reguł walidacji dzięki atrybutowi CustomValidation, któremu podaje się nazwę naszej klasy i metodę. Jeśli kod tej klasy współdzielimy pomiędzy warstwami, to atrybut ten wygeneruje się też po stronie klienta.

Dodatkowo w WCF RIA Services jest możliwość definiowania metadanych także w oddzielnych klasach (tzw. buddy classes). Jest to rozwiązanie przypadku, gdy kod encji po stronie serwera jest generowany. Aby developer nie tracił swoich metadanych pisze partial class i wiąże ją z buddy class. Wynika to z ułomności C# – póki co nie mamy innego sposobu na wyrażenie metadanych do składowych zdefiniowanych w drugiej połówce. Jest to sposób definiowania danych współdzielony z ASP.NET Dynamic Data i ASP.NET MVC.

Metadane w WCF RIA Services zostały pomyślane tak, aby także można było dostarczać je z dowolnego źródła przez własne providery danych (dodajemy własny atrybut nad domain servicem wskazując mu skąd ma czerpać metadane).

Atrybuty w encjach czy w powiązanych z nimi klasami buddy nie muszą się wszystkim podobać (już słyszę te narzekania). Buddy classes trudniej refaktoryzować, wiązanie po nazwach ma swoje wady… Ale okazuje się, że możemy sprowadzić lubiane przez niektórych reguły pisane imperatywnie w postaci wyrażeń LINQ (mają wyrażenia lambda, dobrze się je refaktoryzuje) do postaci atrybutowej przyjmowanej przez WCF RIA Services. To właśnie jest fluent metadata! I to w taki sposób że ten, kto pisze reguły nie musi wiedzieć, że to się w rzeczywistości mapuje na dodawanie atrybutów. Dokonał tego Nikhil Kothari i to już stosunkowo dawno, ale ta implementacja przy pewnych stosunkowo niewielkich zmianach działa także z finalną pierwszą wersją.

03_FluentMetadata_03

Do usłyszenia!

wtorek, 6 lipca 2010

Nowy SketchFlow - kontrolki mockup i coś ponadto

Co nowego w SketchFlow, który obecnie trafił do pakietu Expression Studio Ultimate? Nie ma już nic nowego interesującego? A nieprawda mój kolego!

Zacznijmy od najbardziej godnej uwagi moim zdaniem nowości, która … nie jest wymieniana przez oficjalną dokumentację. Jednak osobowości takie jak John Papa czy Tim Heuer mówiąc o nowościach w SketchFlow piszą o niej w pierwszej kolejności. Sprawa dotyczy kontrolek mockup. Pewne zamieszanie wynika z tego, że domyślnie są udostępnione jedynie w przykładzie MockupDemonstration. Postępując według wskazówek podanych na blogu zespołu zajmującego się linią Expression, jesteśmy w stanie bardzo łatwo udostępnić tę funkcjonalność dla dowolnego projektu SketchFlow.

01_SketchFlow_01

Czym są kontrolki mockup? Są to szkielety dobrze nam znanych z życia codziennego kontrolek. Dzięki nim możemy jeszcze szybciej zamodelować UI. Kontrolki mockup nie zawierają w zasadzie same w sobie logiki, bardziej są to szablony, których składowym możemy dopiero nadać konkretne działanie - najczęściej za pomocą odpowiednich zachowań. 

Tworząc obecnie prototyp w SketchFlow nie musimy wyważać wyważonych już drzwi m.in w przypadku dłuższego kawałka tekstu, ikon, kursorów, przycisków z ikonami, menu, okien dialogowych, formularza do logowania, odtwarzacza multimedialnego, przycisków do stronicowania, oraz …  pulpitu, okna przeglądarki internetowej i eksploatora Windows…

Źródła biblioteki kontrolek mockup zostały udostępnione na codeplex. Stanowią one dobrą bazę szkoleniową z pisania rozszerzeń na czas designu dla Blenda np. własnych edytorów propercji. 

Wokół kontrolek mockup powstało kilka interesujących projektów, z których najbardziej interesujący jest Sketchables - rozwiązanie do szybkiego tworzenia bardziej złożonych kontrolek tego rodzaju, np. różnego rodzaju list czy tabelek DataGrid. Jej autor, człowiek związany z Blendem,  pokazuje na YouTube edycję UI kontrolek za pomocą paru słów czy specyficznego języka. Niestety, na razie nie udostępnił jeszcze publicznie tego projektu …

01_SketchFlow_02

Z innych nowości w SketchFlow chciałbym wspomnieć o nowych możliwościach w animacjach SketchFlow. Obecnie możemy podczas definiowania animacji określić, że na danej ramce ma nastąpić pauza w odtwarzaniu.

Dysponujemy też nowym SketchFlowAnimationTrigger, który pozwala reagować na zmianę ramki, pauzę lub zakończenie animacji SketchFlow. W moim przykładzie animuję puzon, który zatrzymuje się w największym powiększeniu na środku ekranu i wydaje wtedy dźwięk -:)

Animacja SketchFlow technicznie bazuje na stanach wizualnych, a tranzycje między stanami w Blend 4 posiadają efekty tranzycji. Mamy więc możliwość definiowania efektów przejścia pomiędzy ramkami animacji. W moim przypadku puzon rozpływająco przechodzi z pozycji startowej na środek ekranu.

01_SketchFlow_03

To nie wszystko. W nowym SketchFlow odnajdziemy różne przydatne usprawnienia m.in. publikowanie na SharePoint z obsługą feedbacku z dostępem współdzielonym, eksport feedbacku do Worda, ulepszenia w SketchFlow Player. Dla prototypowania w SketchFlow bardzo przydatne są warunkowe zachowania oraz data store.

Opis nowych elementów w SketchFlow w innym nieco ujęciu, przydatne linki oraz praktyczny przykład opublikowałem tutaj.

wtorek, 29 czerwca 2010

Blend 4 - ułatwienia dla MVVM i w designie

By zrobić show z Blenda 4 można zawsze na pierwszy ogień rzucić kontrolkę PathListBox, dynamiczny layout, efekty przejść, warunkowe zachowania… Rzeczy związane z codziennym pisaniem aplikacji, różnymi problemami w designie nie wydają się już tak ciekawe… A tymczasem niesłusznie, bo … są to sprawy, które dotyczą … prawie każdego programisty, który ma współpracować z grafikiem lub … jeśli sam pełni podwójną rolę, chce zyskać na czasie i na wygodzie.

Zacznijmy od wzorców projektowych, a konkretne od MVVM, który stał się wręcz standardem w przypadku aplikacji w Silverlight i WPF. W nowym Blend poczyniono różne udogodnienia w tym kierunku.

Jeśli chodzi o predefiniowane szablony, to dostajemy nowy rodzaj projektu WPF/Silverlight Databound Application. Dostajemy stworzony na wstępie szkielet view modelu, widok, przykładowe dane, wywołanie metody… View modele nie zakładają konkretnej platformy do ich budowania.  Jak dla mnie bardziej przydatnym na co dzień i w pełni wystarczającym jest szablon elementu UserControl with ViewModel. Za jego pomocą tworzymy, to co w wyżej wymienionym szablonie projektu jest predefiniowane na przykładzie, czyli szkielet view modelu i związany z nim widok. Aplikacja nie musi być koniecznie rodzaju DataBound Application

01_MVVM_02

Wzorzec MVVM zakłada wywoływanie logiki poprzez bindowanie komend w widoku. W Silverlight 4 tylko Button, HyperlinkButton i MenuItem w menu kontekstowym przewidują komendę jako swoją propercję do zbindowania. A co z innymi zdarzeniami? A co z innymi kontrolkami i obiektami wizualnymi? A co jak programista nie miał specjalnej ochoty pisać komend i część funkcjonalności mamy tylko w postaci metod? W Blendzie 4 wystarczy…  zrobić drag & drop obiektu komendy lub metody z panelu Data na obszar roboczy.

01_MVVM_06 - Mod

Bardzo szybko i prosto się to robi, ale … nie ma w tym żadnej magii. Jeśli sprawa nie dotyczy odpowiedniej kontrolki i komendy, to designer zamiast bindingu do komendy wstawia nam akcję wywołania komendy lub metody wyzwalaną triggerem na typowym dla danego obiektu zdarzeniu (które - podobnie jak i cały trigger - możemy szybko zmienić na inny rodzaj). Każdy to sobie może sam oczywiście zrobić, ale od tego mamy właśnie narzędzia, by ten proces sobie maksymalnie skrócić …

01_MVVM_07

Przykładowe dane - kolejne zagadnienie, które pojawi się na pewno na styku programista-designer. Grafik potrzebuje przykładowych danych, aby zobaczyć jak będzie wyglądać całościowo UI, bez tego nie widzi w pełni swojego końcowego dzieła zanim nie uruchomi aplikacji, a to jest dość uciążliwe. Przykładowe dane możemy łatwo tworzyć od Blenda 3, ale w typowym scenariuszu nie jest to najwygodniejsze… Dlaczego? Bo zazwyczaj mając napisaną przez kogoś aplikację nie potrzebujemy definiować już struktur, a raczej wykorzystać już istniejące, ale z przykładowymi, niekoniecznie nawet poprawnymi biznesowo wartościami. Po drugie programiści często skupiają się wyłącznie na pisaniu kodu i nie przykładają wagi do tego, aby tworzone przez nich struktury danych i view modele były przyjazne grafikowi w czasie designu. 

Możemy tym wszystkim … nie martwić się, jeśli używamy nowego Blenda. Została dodana opcja tworzenia przykładowych danych na podstawie danej klasy. Co więcej propercje nie muszą mieć setterów, a klasy publicznych konstruktorów, … Programiści nie muszą myśleć o przyjazności dla designu, wszelkie braki wyrównuje narzędzie. Generowany jest xaml z instancjami obiektów odpowiadających naszym strukturom danych wypełnionych przykładowymi wartościami, które możemy też edytować. Dla bindingu w czasie designu jest to w pełni wystarczające.

01_MVVM_09

Jeśli korzystając z powyższej metody utworzyliśmy sobie instancję naszego view modelu, to możemy przeciągnąć ją na korzeń danego widoku. Utworzy się d:DataContext, czyli DataContext obowiązujący tylko na okres designu. Jest to wygodne, bo jest w pełni transparentne dla działania aplikacji w runtime.

01_MVVM_13 - Mod

Jeden ruch i widzimy wszystkie potrzebne dane w czasie designu.

01_MVVM_14

Kolejne zagadnienie - resourcy dostępne tylko w czasie designu. Pewnie wielu bez entuzjazmu powie, że nie widzi zastosowania czegoś takiego u siebie w codziennej pracy. Nic bardziej mylnego! Ileż to razy piszemy złożone aplikacje, w których pewne dane są doczytywane w czasie runtimu z innych modułów. MEF i wszelkiej maści kontenery są nieocenione, jeśli chodzi o elastyczność i luźne powiązanie architektury. Jednak to co jest powodem to zadowolenia programisty, nie musi być już powodem zadowolenia dla grafika. Grafik zacznie tutaj przeklinać, jeśli okaże się, że słownik ze skórką aplikacji jest doczytywany w kodzie w runtimie (który nie jest analizowany) i nie widać go w czasie designu, a Blend sypie wyjątkami i ostrzeżeniami.

Co zrobić? Zawsze można pogonić programistę, by nam takich przekombinowań nie robił, ale używając nowego Blenda możemy sprawić, że wilk będzie syty i owca cała. Wystarczy, abyśmy załączyli sam słownik ze skórką jako element projektu. Blend po wykryciu nie rozwiązanych odniesień do zasobów i widząc słowniki w projekcie, sam … wyświetli okienko dialogowe, czy nie chcielibyśmy widzieć, któregoś z dostępnych słowników na czas designu.  Wtedy dołączy wybrany przez nas słownik do specjalnego słownika DesignTimeResources.xaml trzymanego w katalogu Properties. Tu chciałbym jeszcze raz podkreślić, że cały zabieg nie wpływa w żaden sposób na działającą w runtime aplikację, jest to tylko udogodnienie na czas designu.

Jakieś przykłady z życia wzięte? Ze swojej autobiografii mogę wspomnieć problem jaki wiązał się z pobieraniem z weba skórek i ładowanie ich w czasie runtime do aplikacji. W ówczesnych czasach kończyło się na ingerencji w App.xaml i kopiowaniem skórki do projektu. Dziś też ją byśmy ją skopiowali (nie ma wszak cudów, by pracować na skórce bez jej importu), ale byłoby to zrobione doskonalej. Mało tego, podmieniając załączone słowniki w słowniku dla designu możemy w designie podmieniać różne skórki bez ingerencji w działanie aplikacji. Inny przykład to sytuacja właśnie z MEF, gdy po jego zastosowaniu definicja słownika z App.xaml została zamieniona na dodawanie słownika w kodzie. Tej funkcjonalności użyłem jako jednej z pierwszych w Blend 4, co zostało wymuszone przez zaistniałą sytuację.

01_MVVM_15

A oto moja prosta aplikacyjka w pełnej krasie, w której użyłem opisane wszystkie w tym poście nowe funkcjonalności Blenda. Jak widać dane w runtime różnią się nieco od danych pokazywanych w designerze. Przyciski natomiast wyglądają tak samo dzięki słownikowi dodanemu na czas designu.

01_MVVM_17

Źródła prezentowanego przykładu, jak i opis powyższych zagadnień w nieco innej postaci zostały opublikowane tutaj.

piątek, 25 czerwca 2010

Zachowania w Blend 4 - więcej możliwości, mniej kodu!

Pragnę dzisiaj poruszyć tematykę behaviorów w nowym Blendzie. W stosunku do Blenda 3 mamy więcej predefiniowanych zachowań, możemy bindować ich propercje, określać warunki kiedy się mają wykonywać.

Warunkowe zachowania pozwalają nam zaoszczędzić pisania kodu w pewnych przypadkach. Ważna nowość, ale ja dziś poświęcę więcej uwagi innej nowości – Data Store.

Data Store pozwala nam łatwo współdzielić dane między różnymi częściami aplikacji (np. różnymi ekranami w przypadku nawigacji). Zarówno jego definiowanie, jak i korzystanie z niego (dzięki odpowiednim zachowaniom) nie wymaga pisania żadnego kodu! Teraz designer może dużo więcej! Ma to zwłaszcza duże znaczenie  przy szybkim budowaniu prototypu aplikacji w SketchFlow, choć jest to w pełni uniwersalny mechanizm.

Spójrzmy na poniższe 2 screenshoty pokazujące aplikację przed i po zalogowaniu do niej użytkownika.

01_ConBehDataStore_03 01_ConBehDataStore_06

Odpowiem teraz krótko na dwa pytania. Jak przekazać nazwę użytkownika z pola tekstowego po zalogowaniu do następnego ekranu? Jak wykryć, że użytkownik się zalogował i w odpowiedzi na to wyświetlić górne menu?

Aby przekazać nazwę użytkownika trzeba w momencie kliknięcia na przycisk Login zapisać napis w zmiennej w Data Store. Realizuje to SetDataStoreValueAction, w której wskazujemy (bądź kontekstowo tworzymy) interesującą nas propercję w Data Store oraz podajemy dla niej wartość (tutaj poprzez binding do propercji Text TextBox’a z nazwą użytkownika).

01_ConBehDataStore_02

Zapamiętaną informację chcemy teraz wyświetlić na stronie Home. Nic prostszego! Najszybciej osiągniemy to przeciągając nazwę propercji Data Store z panelu Data na miejsce w UI, gdzie chcemy to wyświetlać. Jeśli upuścimy propercję na kontrolce, to Blend nam zaproponuje utworzenie bindingu dla domyślnie bindowanej propecji kontrolki z możliwością wybrania innej. Jeśli miejscem upuszczenia będzie kontener layout’u, to Blend sam stworzy TextBlock’a i zbinduje jego propercję Text.

01_ConBehDataStore_05 - Mod

Nasuwa się tutaj pytanie, czym fizycznie jest Data Store? Kod klasy DataStore (w tym jej definicje propercji i wartości)  jest generowany przez kreator Blend’a. Następnie Blend sam automatycznie  tworzy sobie obiekt tej klasy globalnym resource’m na poziomie całej aplikacji. Klikając użytkownik może tego wszystkiego nie być świadomy! Tu wielu pewnie powie, że to nic nadzwyczajnego i że sami mogli zawsze to sobie zrobić. Zgoda, ale to właśnie dzięki wygodnej automatyzacji możemy mówić o nowej jakości! Dodatkowo zawsze mamy możliwość dokonywania zmian w definicji Data Store poprzez panel Data.

01_ConBehDataStore_01

Teraz odpowiem na pytanie jak wykryć zmianę wartości danej propercji w Data Store. Należy w interesującym nas miejscu w UI użyć DataStoreChangeTrigger i wskazać mu interesującą nas propercję Data Store. W naszym przypadku ten trigger monitoruje zmianę logicznej propercji mówiącej czy użytkownik jest zalogowany (jest ustawiana na True przy logowaniu). Następnie wykonywana jest akcja ustawienia propercji Visibility panelu menu na wartość Visible, pod warunkiem, że nasza propercja IsAuthenticated w Data Store ma wartość True.

01_ConBehDataStore_04

Poruszane dziś zagadnienia (ale nieco w innym ujęciu), związane z nimi linki oraz prezentowany przykład opublikowałem także tutaj.

niedziela, 20 czerwca 2010

Blend 4 - zaskakujące efekty z FluidMoveBehavior

Dzisiaj chciałbym napisać o tym, o czym nieraz wspominałem od czasów ostatniego MIX’a, ale nie było okazji tego w szerszym gronie wyartykułować. Mianowicie chodzi mi o efekt, który nazwałem “wyskakującym krzesłem” od przykładu, który zazwyczaj go demonstruje.  

O co chodzi z tym krzesłem, czyż nie umiem już posługiwać się Blendem?  Tak zapewnie niejeden czytający tego posta sobie pomyśli. Już wyjaśniam.

Chodzi o wyjeżdżające krzesło na szczegółach elementu, po tym jak wybierze się dany element na liście. Nie byłoby w tym nic zaskakującego, gdyby nie to, że krzesło szczegółów wyjeżdża wprost z … krzesła na elemencie listy! Skąd krzesło szczegółów zna dokładnie i precyzyjnie pozycję odpowiadającego mu krzesła na danym elemencie listy? To są zupełnie inne obszary UI!

01_FluidMoveBehavior_MasterDetails_03 - Mod

Cały patent kryje się w nowych możliwościach FluidMoveBehavior, który potrafi animować teraz nie tylko sam element, ale także zbindowane dane. Pozycja konkretnych obiektów danych jest znajdowana na ekranie i to ona jest uwzględniana w animacji. Widzimy, że jak będziemy animować dany obiekt z danymi, a nie jego konkretną wizualną reprezentację, to nasze zadanie stanie się dużo prostsze. FluidMoveBehavior używany jest w gridzie ze szczegółami elementu i trzeba mu przekazać pozycję startową, którą jest położenie krzesła na danym elemencie listy. Pozycję startową krzesła dla danego obiektu danych rejestrujemy za pomocą FluidMoveSetTagBehavior w szablonie elementu listy. Ta informacja jest umieszczana niejawnie w data store, a potem jest wyciągana przez FluidMoveBehavior, który wtedy już wie, jak ma animować krzesło reprezentujące dany obiekt. W tym miejscu trzeba dodać, że możemy przebieg animacji modyfikować za pomocą dowolnej easing function, a całość odbywa się bez napisania linijki kodu ze strony użytkownika!  Jest to piękny przykład, pokazujący jak w uniwersalny sposób można zamknąć kawałek kodu, by innym żyło się lepiej.

A jak zrobić, by elementy wyjeżdżały płynnie z jednej listy i w wjeżdżały w odpowiednie miejsce na drugiej?  Nic prostszego! Wystarczy tylko w obu listach w szablonie panelu umieścić FluidMoveBehavior, tak by animował dzieci kontenera pobierane z data context’u.

02_FluidMoveBehavior_ListToList_03

Ciekawe efekty można osiągnąć używając LayoutStates na elementach listy, w której w kontenerze osadzony jest FluidMoveBehavior. Wtedy wszystko jest w ruchu, wszystko żyje, wszystko się zmienia. Zmienia się tworzony element przy jego dodawaniu do listy, ale także sama lista stopniowo rezerwuje dla niego miejsce. Podobnie może się dziać przy usuwaniu elementu z listy.

Więcej praktycznych szczegółów, przydatne linki oraz wszystkie przykłady zamieściłem tutaj.

środa, 16 czerwca 2010

Blend 4 - niebanalny layout bez linijki kodu!

Pisanie o nowym Blendzie rozpocznę od rzeczy moim zdaniem bardzo istotnej i dość przełomowej w stosunku do dotychczasowych możliwości - od layoutu wzdłuż dowolnego kształtu.

Do tej pory grafik musiał prosić programistę, aby ten napisał mu kod realizujący layout wzdłuż zadanej krzywej. Miał też utrudniony podgląd, by od razu móc wypróbować swoje pomysły. Jak się zmieniała koncepcja designu, programista znów musiał zmieniać kod. Czy nie lepiej przerzucić tworzenie złożonych krzywych na grafika, który najlepiej będzie wiedział, co chce osiągnąć i by mógł sobie łatwo zmieniać wygląd bez żadnego pośrednika?

Otóż w nowym Blendzie można, a jest to realizowane przy użyciu kontrolki PathListBox.

PathListBox układa elementy wzdłuż ścieżki lub ścieżek (a dokładniej mogą być to: Path, Shapes - dotychczasowe i nowe lub … dowolny wręcz element). Poprzez różne parametry mamy dość duży wpływ na efekt końcowy naszej pracy.

02_MultiplePaths

PathListBox (Blend SDK) uzupełnia też braki w samym Silverlight. Dzięki niemu wreszcie łatwo zrobimy animację i napis po dowolnej ścieżce.

Animacja po ścieżce polega na animowaniu parametru Start dla ścieżki w PathListBox. Dzięki temu widzimy, że obiekty na ścieżce się przesuwają.

03_MotionPath

Rozmieszczenie napisu wzdłuż ścieżki robimy poprzez zbindowanie stringa do ItemsSource PathListBox’a. W .NET string to kolekcja liter, ot cała tajemnica sukcesu! Jak dodatkowo wprawimy w ruch ścieżkę, to możemy tanio uzyskać całkiem niezły bajer.

04_TextOnPath

Bardzo łatwo możemy też sprawić, by np. rozmiary i przezroczystość elementów zależały od ich położenia na ścieżce.

05_PathListBoxItem_02

To nie wszystko! Usiądź, weź krzesło, zrób karuzelę nowoczesną! Dzięki rozszerzeniom dla PathListBox’a opublikowanym przez team Blenda można łatwo osiągać jeszcze bardziej zaawansowane efekty wizualne!  Teraz zrobienie np. nowoczesnej przeglądarki produktów to kwestia kilku kliknięć. Pamiętajmy, że PathListBox obsługuje dane podobnie jak ListBox, elementy nie muszą być podawane “na sztywno”, można bindować do kolekcji dowolnych obiektów.

Kto nie kupi krzesła w taakim sklepie?

06_PathListBoxUtils_03

Więcej szczegółów, przydatne linki oraz przykłady zamieściłem tutaj.