Pokazywanie postów oznaczonych etykietą Expression Blend. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą Expression Blend. Pokaż wszystkie posty

czwartek, 6 grudnia 2012

BUILD 2012 News (20)

Z trzech ostatnio obejrzanych najbardziej cenię prezentację o Blend oraz o EF.

 

Building Awesome HTML apps in Blend for Windows 8

Kirupa prawie od zawsze kojarzył się z narzędziem Blend. Tak więc naturalne było, że to on pokazał jego możliwości w zakresie HTML5. Prezentacja konkretna, rzeczowa, mamy pokaz, co po kolei możemy w nowym narzędziu zdziałać. Owszem w zasadzie są to znane już wcześniej możliwości i opcje, ale i tak przyjemnie było obejrzeć.

image_thumb198

image_thumb205

image_thumb208

image_thumb212

image_thumb215

image

image

image

image

image

 

Building data centric applications for web, desktop and mobile with Entity Framework 5.

Dobre podsumowanie możliwości EF5 oraz ich pokaz. Zwróćmy uwagę na zapowiadane możliwości EF6. Aplikacją desktop okazała się być… aplikacja Windows Store. Przy okazji mieliśmy pokaz, jak używać Bing API w Windows 8.

image

image

image

image

image

image

 

image

image

image

image

image

 

Tips on self-evaluating the UX of your app

Ta prezentacja wydaje się mało wnosząca, dla mnie zbyt ogólna i dotycząca materiału z innych wystąpień. Wrzuciłem z niej parę screenów, ale jakbyśmy przeglądali co jakiś czas dokumentację w MSDN, to byśmy w niej wyczytali odpowiednio wcześniej podobne informacje np. o paskach nawigacji.

design.windows.com, windowsstore.com

image

image

image

image

image

image

niedziela, 9 września 2012

WinJS na żywo - odc.5 (m.in search, własny binding)

Tym razem z poziomu WinJS dokonałem integracji z systemową wyszukiwarką, sprawiając tym samym osiągnięcie przez aplikację WinJS tej samej funkcjonalności, którą wcześniej zrealizowałem w C#. Oczywiście wiązały się z tym też mniejsze zadania…

Kontrakt Search oraz stronę z wynikami wyszukiwań najszybciej dodamy korzystając z Visual Studio 2012. Z menu kontekstowego w oknie Solution Explorer wybieramy Add New Item, a następnie szablon Search Contract. Dokumentacja opisuje wszystkie potrzebne czynności oraz co zostaje dodawane do projektu aplikacji po wybraniu szablonu. Chwilę może zająć analiza kodu wygenerowanej strony. Parę rzeczy zwróciło w praktyce moją uwagę. Code-behind strony z wynikami wyszukiwań jest zadeklarowany w default.html, zamiast w HTML tej strony. Jest to podyktowane tym, że:

  • obsłużenie zdarzenia aktywacji aplikacji przez wyszukiwarkę
  • rejestracja na wpisanie zapytania w wyszukiwarce

muszą odbywać się globalnie przy uruchomieniu aplikacji i nie zdecydowano się na modyfikację pliku z kodem globalnym. Konkretnie chodzi o kod:

WinJS.Application.addEventListener("activated", function (args) {
        if (args.detail.kind === appModel.Activation.ActivationKind.search) {
            args.setPromise(ui.processAll().then(function () {
                if (!nav.location) {
                    nav.history.current = { location: Application.navigator.home, initialState: {} };
                }                   

                return nav.navigate(searchPageURI, { queryText: args.detail.queryText });
            }));
        }
    });

appModel.Search.SearchPane.getForCurrentView().onquerysubmitted = function (args) { nav.navigate(searchPageURI, args); };

Jednocześnie HTML strony z wynikami wyszukiwania nie odwołuje się do pliku JavaScript o takiej samej nazwie, co powoduje, że strona w designerze Blenda nie prezentuje się w prawidłowy sposób. Jeśli jednak otworzymy default.html i w trybie interaktywnym przenawigujemy do strony z wynikami, to prezentuje się ona wtedy prawidłowo. Stylowanie jest wtedy przyjemnością….

W wygenerowanej stronie są przykładowe dane, które potrzebujemy z reguły zmienić. W moim przypadku potrzebuję filtrować pobrane pliki wideo, które są zapisywane w folderze lokalnym aplikacji. W definicji strony powstał w związku z tym następujący kod:

ready: function (element, options) {
            …

      this._handleQuery(element, options);

      …

},

_handleQuery: function (element, args) {

           …
           this._searchData(element, this._queryText);

           …
},

_searchData: function (element, queryText) {
            if (window.Data) {
                var folder = Windows.Storage.ApplicationData.current.localFolder;
                var queryOptions = new Windows.Storage.Search.QueryOptions(Windows.Storage.Search.CommonFileQuery.defaultQuery, [".mp4"]);
                queryOptions.folderDepth = Windows.Storage.Search.FolderDepth.deep;
                queryOptions.indexerOption = Windows.Storage.Search.IndexerOption.useIndexerWhenAvailable;

                if (queryText !== "")
                    queryOptions.userSearchFilter = queryText;

                var fileQuery = folder.createFileQueryWithOptions(queryOptions);

                var dataSourceOptions = {
                    mode: Windows.Storage.FileProperties.ThumbnailMode.picturesView,
                    requestedThumbnailSize: 95,
                    thumbnailOptions: Windows.Storage.FileProperties.ThumbnailOptions.useCurrentScale
                };

                var dataSource = new WinJS.UI.StorageDataSource(fileQuery, dataSourceOptions);

                var listView = element.querySelector(".resultslist").winControl;
                listView.itemDataSource = dataSource;
            }
        }

By cieszyć się widokiem:

jstube_11

dokonanałem jeszcze trochę zmian w kodzie i stylach strony. Na łamach krótkiego postu nie wydają się one aż tak istotne, by je omawiać, z wyjątkiem kolorowania wyszukiwanej frazy na elementach ListView.

Wygenerowana strona otrzymuje już taką funkcjonalność w postaci zdefiniowanej funkcji konwertera  _markText. W czym więc problem? Pułapka tkwi w klasie StorageDataSource. Jak już ostatnio w swoich postach pisałem, wymaga ona bindingów onetime. Jak zdefiniować w WinJS binding onetime, który korzysta z konwertera? Nie jest to tak oczywiste jak… w XAML-u. Sprawę zakończyło zdefiniowanie nowego bindingu zawierającego w sobie także logikę konwertera:

_bindMarkedText: function (source, sourceProperty, destination, destinationProperty) {
            var element = destination;
            var text = source && source[sourceProperty];
            if (!text) return;
            if (this._lastSearch)
                destination[destinationProperty] = text.replace(this._lastSearch, "<mark>" + this._lastSearch + "</mark>");
            else
                destination[destinationProperty] = text;
        },

Większa powszechność tworzenia własnych bindingów i ich większa otwartość jest typowa także dla innych bibliotek JS (np. Knockout’a). W ich logice oprócz konwersji mogą znajdować się także operacje na elementach wizualnych, w tym animacje. Wracając do naszego przypadku chciałbym zwrócić uwagę na funkcję WinJS.Binding.initializer, której użyłem do zadeklarowania, że funkcja _bindMarkedText może być stosowana w deklaratywnym data bindingu.

_handleQuery: function (element, args) {
            …
            WinJS.Namespace.define("searchVideos", { bindMarkedText: WinJS.Binding.initializer(this._bindMarkedText.bind(this)) });            
            …

        },

Teraz wystarczy dopilnować, by w HTML tekst w szablonie listy był zbindowany tak:

<div class="itemtemplate" data-win-control="WinJS.Binding.Template">
        <div class="item">

            …
            <div class="item-content">
                <h3 class="item-title win-type-x-small" data-win-bind="innerHTML: name searchVideos.bindMarkedText"></h3>               
            </div>
        </div>
    </div>

Na koniec zmieniłem sobie w CSS kolor zaznaczonego tekstu z domyślnego niebieskiego na pomarańczowy:

.searchVideos section[role=main] .resultslist .item .item-content mark {
                    background: transparent;
                    color: #D8512B;

     }

Do usłyszenia.

czwartek, 6 września 2012

WinJS na żywo - odc.4 (m.in Flyout, progress, stylowanie, binding, transfer w tle)

Tym razem padło na wizualizację dla pobieranych plików. Wzorowałem się na wcześniej powstałej wersji w C#, ale niektóre zagadnienia rozwiązałem inaczej i nieco przestylowałem wygląd… Jak zwykle Blend okazał się bardzo pomocny, a tryb interaktywny nieoceniony… Pewnej przebudowy wymagała też implementacja pobierania plików, tak że obecnie dostarcza listę bindowalnych obiektów z informacjami o transferach… Ale po kolei.

Jak zrobić coś ala-dropdownbutton w aplikacji Windows 8? Najbardziej odpowiednia wydaje się do tego kontrolka Flyout. W jej wnętrzu umieściłem pole tekstowe z nagłówkiem oraz ListView z layoutem listy. HTML wygląda następująco:

  <div id="statusFlyout" data-win-control="WinJS.UI.Flyout">
        <div>
            <div id="progressheader">
                <span>Downloading&nbsp;</span><span id="downloadscount">3</span><span>&nbsp;files</span>
            </div>           
            <div id="progresslist" data-win-control="WinJS.UI.ListView"
                data-win-options="{layout:{type:WinJS.UI.ListLayout}, selectionMode:'none', tapBehavior:'none'}">
            </div>
        </div>
    </div>  

Kontrolka Flyout wraz z zawartością nie jest domyślnie widoczna. Chcemy pokazywać ją pod przyciskiem statusButton wyświetlającym informacje o ilości pobieranych plików, który ma także powodować jej wyświetlenie. Do tego przycisku podpinamy więc handler:

function showStatusFlyout() {
        var statusButton = document.getElementById("statusButton");    
        document.getElementById("statusFlyout").winControl.show(statusButton, "bottom", "right");     
    }

W tym przypadku metodzie show przekazałem:

  • obiekt, do którego chcemy się doczepić (statusButton)
  • krawędź doczepienia (bottom)
  • wyrównanie (right - do prawej krawędzi statusButton)

Dotknięcie każdego punktu poza obszarem popup’a spowoduje jego zamknięcie.

ListView umieszczony we Flyout zachowuje się nieco inaczej. Jeśli ustawimy źródło danych na ListView, w momencie, gdy nie jest widoczne, to po otwarciu Flyout… lista będzie pusta. Podyktowane jest to pewną optymalizacją, która zaszła w wersji finalnej - niewidoczne kontrolki nie podlegają przetwarzaniu. Możemy jednak przed pokazaniem ListView wymusić przetworzenie jego layoutu:

var statusFlyout = element.querySelector("#statusFlyout");
            statusFlyout.addEventListener("beforeshow", function (event) {               
                var progresslist = element.querySelector("#progresslist").winControl;               
                progresslist.forceLayout();               
            });

Teraz trochę o stylowaniu.

jstube_9

HTML szablonu elementu listy wizualizującej transfery plików wygląda następująco:

<div class="progressitemtemplate" data-win-control="WinJS.Binding.Template">
        <div class="progressitem">          
            <h4 class="progressitem-title" data-win-bind="textContent: fileName"></h4>               
            <progress class="progressitem-progress" max="100" data-win-bind="value:progress"></progress>
            <div class="progressitem-details">               
                <span data-win-bind="textContent: bytesReceived"></span>
                <span class="text-part">of</span>
                <span class="text-part" data-win-bind="textContent: totalBytesToReceive"></span>
                <span class="text-part">KB</span>
            </div>
            <button class="progressitem-cancelbutton" type="button"></button>          
        </div>
    </div>

Nie sposób w tym dość krótkim poście przedstawić wszystkie szczegóły związane ze stylowaniem, zwrócę jedynie uwagę na pewne aspekty związane z ListView oraz na kontrolkę <progress>.

Aby ustawić przezroczyste tło na ListView, wyłączyć standardową wizualizację na najeżdżanie,  zrobić odpowiedni margines wystarczy:

#progresslist .win-container:not(.footprint):not(.hover)
{
    background-color: transparent;
}

#progresslist .win-container:hover {
    outline: transparent solid 0px;
}

#progresslist > .win-vertical .win-container {
    margin: 5px;
}

Przy okazji mała dygresja odnośnie animacji w WinJS. Jakby komuś przyszło do głowy wyłączyć standardowo wbudowane animacje w ListView, to okaże się, że przełącznika w CSS do tego… nie ma. Jest natomiast możliwość globalnego wyłączenia/włączenia efektów animacyjnych dla całej aplikacji (to trochę bardziej złożone zagadnienie, odsyłam do opisów metod WinJS.UI.enableAnimations() i WinJS.UI.disableAnimations() w MSDN). Tutaj nie wyłączałem animacji…

Kontrolka <progress> jest standardowa dla HTML5, tutaj ma domyślny wygląd w stylu Modern UI/Metro. Styl CSS dla niej przyjął u mnie ostatecznie postać:

#progresslist .progressitem .progressitem-progress {
    width: 100%;
    color: #D8512B;
    background-color: #3D3D3D;
    -ms-grid-row: 2;
    margin-top: 10px;
    margin-bottom: 10px;
    margin-left: 1px;
}

Co potrzebujemy jeszcze zrobić, by cieszyć się widokiem, takim jak poniżej?

jstube_10

Z pewnością potrzebujemy powiązać informacje o transferach z UI. Możemy w WinJS.Binding.List trzymać bindowalne obiekty, które możemy sobie budować na podstawie obiektów DownloadOperation:

function makeListEntryFromDownload(download, existing) {
       
        var entry = {};       
      
        entry.guid = download.guid;
        entry.fileName = download.resultFile.name.replace(".mp4","");
        entry.bytesReceived = download.progress.bytesReceived;
        entry.totalBytesToReceive = download.progress.totalBytesToReceive;
        entry.progress = (entry.bytesReceived / entry.totalBytesToReceive) * 100.0;
       
        if (existing) {
            entry.promise = download.attachAsync();
        }
        else {           
            entry.promise = download.startAsync();
        }

        entry.promise = entry.promise.then(
            function () {
                downloadComplete(entry, download);
            },
            function (e) {
                downloadError(entry, e);
            },
            function () {
                downloadProgress(entry, download);
            }
        );
       
        entry.cancelDownload = function (e) {
            entry.promise.cancel();
        }

        return (entry);
    }

Metoda WinJS.Binding.as(data) robi z podanego obiektu bindowalny obiekt. 

Przedstawiony wyżej kod wykorzystujemy dla obiektów DownloadOperation aktualnie zakolejkowanych transferów w serwisie w następujący sposób:

var entry = makeListEntryFromDownload(download, true);
bindingList.push(WinJS.Binding.as(entry));

BindingList to WinJS.Binding.List, którą możemy powiązać z ListView. W przypadku zlecenia nowego transferu napisaną przez nas metodą wywołujemy z parametrem false zamiast true.

Bindowalne obiekty możemy uaktualniać w następujący sposób:

function downloadProgress(entry, download) {
        var bound = WinJS.Binding.as(entry);
        bound.bytesReceived = download.progress.bytesReceived;
        bound.totalBytesToReceive = download.progress.totalBytesToReceive;
        bound.progress = (bound.bytesReceived / bound.totalBytesToReceive) * 100.0;
    }

Całość kodu zorganizowałem sobie podobnie jak w przykładzie Mike Taulty'ego, który ostatnio przypadł mi do gustu. Polecam zapoznać się z nim.

Przy okazji mała dygresja odnośnie transferu plików w tle. W trakcie rozwijania Windows 8, ostatecznie stanęło na tym, że transfery plików są kontynuowane przy uśpionej aplikacji. Jeśli proces aplikacji po jej uśpieniu zostanie zakończony, to przy ponownym uruchomieniu aplikacji, transfery plików są restartowane (zapamiętywana jest lista plików do transferu).

Stay tuned!

niedziela, 26 sierpnia 2012

WinJS na żywo - odc. 1 (Wstęp & Blend)

Po napisaniu prototypu aplikacji pobierającej clipy z YouTube w C# na Windows 8 (a także ostatnio na WP*), postanowiłem przepisać to co już powstało na WinJS w Windows 8. Przeglądałem jakiś czas temu niemal całą dokumentację msdn na ten temat, ale myślę, że jednak najlepiej pobawić się w praktyce. W międzyczasie przyswoiłem pewną ilość wiedzy na temat samego HTML5, JavaScript, CSS3, jQuery, Knockout oraz innych nowych standardów i frameworków dla aplikacji Web, więc teraz to spojrzenie na WinJS będzie myślę bardziej dojrzałe. Jako, że zawsze bardzo lubiłem narzędzie Blend, więc również i tym razem będę go używał.

Trzecią część tryptyku rozpocząłem od stworzenia nowego projektu z dwiema stronami z przykładowymi danymi, z których drugą przedstawiam poniżej:

jstube_1

Zaraz, zaraz czy takiego screenshota już tutaj nie było? Owszem, jak ktoś przepatrzy historię, to może znaleźć nawet taki z tymi samymi zdjęciami (gdy używałem na początku w C# przykładowych danych, były takie same).

mks_01_C 

Aplikacje w C# i w HTML5 na WinRT nie różnią się wizualnie ani zachowaniem, co świadczy o sporym postępie jeśli chodzi o wykorzystanie technologii Web do pisania natywnych aplikacji.

Teraz parę słów o Blendzie. Nie będę pisał kolejnego tutoriala, jak obsługiwać w nim HTML, JS i CSS, można znaleźć to wszystko w sieci. Ze swojej strony mogę powiedzieć, że jeśli ktoś zna Blenda pod XAML, to tutaj trzeba… chwilki czasu, by się oswoić. Twórcy postanowili odzwierciedlić HTML i CSS takimi jakimi są, bez upiększeń, nie mamy w zasadzie żadnej abstrakcji. Na początku może nam brakować pewnych paneli aplikacji jakie znamy z XAML, ale w miarę używania poczujemy bardzo dużą wygodę korzystania mimo odmiennej filozofii działania. Bardzo wiele rzeczy można zrobić z poziomu designera czy wykorzystując inne pomocnicze narzędzia. W pewnej mierze jest to wzorowane na narzędziach z przeglądarek webowych czy narzędziach dla aplikacji Web w Visual Studio 2012, ale część mechanizmów znanych z Blenda dla XAML zostało tutaj osadzonych.

Zwrócę teraz uwagę na kilka wybranych rzeczy. Layout odpowiadający Grid-owi z XAML, możemy robić … tak samo. Jest to zasługą specyfikacji Grid Layout w CSS3 (szkoda że przy “otwartych” aplikacjach webowych to zagadnienie jest bardziej złożone z uwagi, że na razie chyba jedynie IE10 implementuje ten standard). Na razie używałem grid i flex w paru miejscach… Na screenshocie grid w AppBar z niestandardową zawartością… (btw AppBar pod WinJS jest na większym poziomie organizacyjnym, ma też wygodniejszą obsługę z poziomu Blenda).

jstube_2

Warto powiedzieć, że w designerze wykonuje się kod JS na żywo, z reguły do obserwowania zmian automatyczne odświeżanie jest wystarczające. Z dużą łatwością ustalimy, dlaczego np. dany element ma taki kolor a nie inny. Widzimy jakie reguły CSS z jakich plików odnoszą się do danego elementu, która reguła zwyciężyła, jakie wartości są ostatecznie wyliczane.

jstube_3

Przy okazji mała dygresja na temat gwiazdek. W C# użyłem dla celów demonstracyjnych jedynie napisu, w WinJS mamy kontrolkę Rating, której parametr pozwoliłem sobie zbindować. Trochę też ją przestylowałem, pomniejszając nieco gwiazdki i zmieniając im kolor… Miałem tutaj chwilkę na wyczajenie jednego parametru z layoutu flex. Kontrolka mi się niepotrzebnie rozciągała horyzontalnie, nawet wbrew innym ustawieniom. Pomogło ustawienie w stylu dla gwiazdki ms-flex: 0 0 auto …

Koniecznie należy wspomnieć o przycisku ze “strzałką z kreseczkami” nad prawą górną krawędzią designera. Otwiera nam okno trybu interaktywnego, w którym możemy coś zrobić w naszej aplikacji, a potem wrócić z powrotem wrócić do designera. Mi się to bardzo przydało, gdy edytowałem wygląd zaznaczonego elementu.

jstube_4

W przeciwieństwie do kontrolki z C# zamiast docelowego wyglądu, jaki chciałem osiągnąć w WinJS zastałem domyślnie niewidoczne obramowanie oraz check z przezroczystym tłem przy domyślnej zmianie tła całego elementu na niebieski. Taki styl spotkamy w części wbudowanych aplikacji np. Skydrive. Wszędzie tam stawia się na mały obrazek, jakiś napis i przezroczyste tło, które zmieni kolor. Mi jednak bardziej pasowało by to obrazek był tłem, chciałem więc mieć wygląd taki jaki jest domyślny w C# i … trochę mi to zajęło. Ponieważ nie jest to takie oczywiste więc podam sposób, w jaki osiągnąłem pomarańczową ramką i check w pomarańczowym trójkącie.

Pomarańczowa ramka: ramka … już jest, wystarczy zmienić tylko jej kolor definiując regułę nadpisującą (u mnie były takie zagnieżdżenia jak poniżej, w każdym razie należy zwrócić uwagę na zagnieżdżenie klas .win-selected .win-selectionborder w kontrolce ListView):

.addnewvideospage .groupeditemslist .win-selected .win-selectionborder {
                background-color: #D8512B;   
            }

Z pomarańczowym trójkątem było już gorzej, bo po zmianie koloru tła elementu z checkiem w kontrolce okazał się … prostokątem. Posiłkując się stronami w sieci na temat otrzymywania figur z bordera (np. http://css3shapes.com/, http://www.howtocreate.co.uk/tutorials/css/slopes), ustawiłem regułę:

.addnewvideospage .groupeditemslist .win-selected .win-selectioncheckmarkbackground {
                width: 0px;
                border-top: 20px solid #D8512B;
                border-right: 20px solid #D8512B;
            }

Teraz mała dygresja o tym, jak zrobiłem formatowanie daty. W XAML był to konwerter do bindingu (w przeciwieństwie do Silverlight nie ma StringFormat), w WinJS też mamy podobną koncepcję. Definiujemy funkcję w JavaScript:

var formatDate = WinJS.Binding.converter(function (date) {       
        var dateTimeFmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("{day.integer(2)}/{month.integer(2)}/{year.full}‎ {hour.integer(2)}: {minute.integer(2)}");
        return dateTimeFmt.format(date);
    });

Rejestrujemy ją w przestrzeni nazw (w sumie jest to jakaś implementacja w WinJS jednego z polecanych wzorców projektowych dla JS):

WinJS.Namespace.define("Data", {
        formatDate: formatDate, …
});  

W data bindingu po ścieżce dopisujemy zdefiniowaną funkcję konwertującą:

<h6 class="item-subtitle" data-win-bind="textContent:pubDate Data.formatDate"></h6>

Inną małą dygresją jest wyświetlanie automatyczne wyświetlanie … w przypadku, gdy napis okaże się za długi. W XAML czy Silverlight był na to parametr w TextBlock, w HTML na Windows 8 wystarczy użyć predefiniowanej klasy win-type-ellipsis np.

<h4 class="item-title win-type-ellipsis" data-win-bind="textContent: title"></h4>

W sumie to nasunął mi się jeden komentarz odnośnie data bindingu w WinJS po tych dwóch dygresjach. Używa data-* więc jest zgodny z HTML5 i przypomina Knockouta.

Wiadomo, nie opiszę wszystkiego-;)  Myślę że jak na ten post to już wystarczy.

Ciąg dalszy nastąpi.

niedziela, 19 sierpnia 2012

Windows 8 RTM & Visual Studio 2012 RTM - pierwsze wrażenia

W ostatnich dniach ukazały się Windows 8 w wersji finalnej dla deweloperów (kompilacja 9200) oraz finalne Visual Studio 2012 (wraz z finalnym .NET 4.5). Dziś parę zdań na ich temat.

Linki do pobrania wszystkiego (systemu i wszystkich narzędzi) zostały umieszczone na stronie Downloads for Metro style app development. Jeśli chodzi o podstawowe narzędzia, czyli Visual Studio 2012 z Blendem, to oprócz domyślnej wersji Visual Studio Express 2012 for Windows 8, można też korzystać z jednej z wersji Visual Studio 2012.

win8_rtm

Jeśli chodzi o sam Windows, to w stosunku do wcześniejszych wersji mamy inną domyślną kolorystykę, znacznie ładniejsze tapety na pulpit i na lock screen (nie widziałem tego rysunku już gdzieś na jakiejś konferencji MS?) oraz możliwość konfigurowania tapet i kolorystyki ekranu startowego. W aplikacjach też można zauważyć różne zmiany w designie i w funkcjonalnościach…

image

Jeśli chodzi o Visual Studio 2012, to można zauważyć, że zgodnie z ostatnią polityką odchodzenia od terminu Metro, projekty aplikacji dla Windows 8 znajdują się obecnie pod kategorią “Windows Store”. Inną ciekawostką jest nie działający jeszcze link do doinstalowania Windows Phone 8 SDK pod kategorią Windows Phone. Blend for Visual Studio 2012 zawiera jedynie projekty dla Windows 8.

Jeśli chodzi o migrację aplikacji z wersji Release Preview na RTM, to są to niewielkie zmiany. Całość opisuje Migration guide. Najwięcej stosunkowo zmian zaszło w API pod C++ i JS. Ja swoją aplikację w .NET już zmigrowałem, działa!

piątek, 29 kwietnia 2011

Subiektywne spojrzenie na sesje MIX11

Trudno byłoby obejrzeć 120 sesji (o ile mnie pamięć nie myli), więc musiałem dokonać jakiegoś wyboru. Zarówno wybór, jak i opinie nie będą tutaj obiektywne, reprezentuję obóz związany z Silverlight i Windows Phone –:) Nie oznacza to, że napiszę tylko o sesjach związanych z tą tematyką, ale będą stanowiły one najliczniejszą grupę w podsumowaniu.

Zacznijmy od najlepszych (spośród obejrzanych/przejrzanych przeze mnie) pozycji.

W kategorii Windows Phone są to:

W kategorii Silverlight są to:

Przejdźmy teraz do sesji, które nie są dla mnie topowe, ale mogą poszerzyć horyzonty, przynajmniej część z nich warto obejrzeć:

Sesje, które nie wzbudziły we mnie większego entuzjazmu lub wydały mi się dość słabe:

Do tej całej rozpiski załączam plik, w którym robiłem oceny i krótkie komentarze do poszczególnych pozycji. Nie obejrzałem wszystkiego w 100%, co zamierzyłem, trochę sesji w końcu sobie odpuściłem –:)

Ten post napisałem by jakoś utrwalić swoje subiektywne opinie o MIX 11, by gdzieś w szufladzie nie zaginęły, jak było w przypadku poprzednich eventów. Od połowy tego tygodnia jestem myślami w szczegółach Silverlight 5, ale o tym będą już inne posty.

poniedziałek, 18 kwietnia 2011

Mango i Silverlight 5 Beta !!!

Zainspirowany nowościami na MIX 11 postanowiłem reaktywować szybko bloga (a także drugiego w późniejszym czasie). Dla mnie najbardziej istotne są Mango (kodowa nazwa następnej wersji Windows Phone) oraz Silverlight 5 Beta. Obejrzałem na razie blisko 30 nagrań (robocze notatki w postaci screenshotów), z czego większość na temat tych dwóch zagadnień.

Postanowiłem sobie roboczo spisać nowe funkcjonalności i zmiany w Mango:

mangoSystem operacyjny

  • 16 dodatkowych języków (w tym polski)
  • Wyszukiwanie na liście aplikacji
  • Multitasking
  • Search Extras
  • IE9 z HTML5
  • Zarządzanie aplikacjami w tle
  • Lepsza wydajność (w tym nowy wątek Touch Thread)

Multitasking

  • Szybkie przełączanie między aplikacjami
    • aplikacja po dezaktywacji najczęściej pozostaje w pamięci (tylko to, zasoby są wtedy odpinane, wątki i timery usypiane)
  • Serwisy w tle
    • ScheduledActionService
      • Alarmy
      • Przypominacze
    • Zune Service (audio w tle - przeglądarka, własna aplikacja, obsługa panelu audio poprzez agenta audio)
    • BackgroundTransferService (pobieranie i upload)
  • Agenci w tle
    • periodic (PeriodicTask + ScheduledActionService)
    • on idle
  • Zarządzanie zasobami (na poziomie frameworka - odpinanie, przypinanie)

Taski

  • Numer telefonu
  • Adres
  • E-mail
  • Bing Map
  • Dzwonki

Sensory i kamera

  • GPS
  • Akcelerometr
  • Kompas
  • Żyroskop
  • Motion Sensor (na podstawie innych sensorów)
  • Kamery
    • Scenariusze
      • rozszerzona rzeczywistość
      • analiza obrazu np. wykrywanie kodu kreskowego
      • robienie zdjęć
      • nagrywanie video i audio
    • Nagrywanie
    • Bezpośrednia obsługa (w tym przycisku, focusa, flash, możliwość napisania własnej aplikacji do robienia zdjęcia/nagrania filmu, zdjęcie można zapisać w kategorii kamery)
    • 2 sposoby obsługi
      • PhotoCamera
      • Silverlight 4 API

Dostęp do danych

  • Lokalne baza danych na SQL CE
    • Generacja i upgrade bazy z poziomu kodu
  • Dostęp do kontaktów i spotkań
    • Tylko do odczytu
    • Asynchroniczne wyszukiwanie
  • LINQ to
    • SQL (DataContext, generacja bazy z poziomu kodu - tabele, kolumny, klucze, indeksy)
    • User Data
    • OData

Kafelki

  • API do lokalnej modyfikacji (pełna kontrola nad wszystkimi parametrami)
  • Wiele kafelków dla danej aplikacji (kafelki kontekstowe do danej strony w aplikacji, programowe dodawanie/usuwanie, dedykowane zdarzenia)
  • Kafelki dwustronne (strona background)

Notyfikacje push

  • Tile (dodatkowe pola dla strony background, precyzyjne wskazywanie kafelka po adresie)
  • Deep toast (wskazanie adresu do otwarcia w danej aplikacji)
  • Wydajność
  • Niezawodność
  • Limit powiększony do 30 endpointów
  • Przykłady dla Azure

Silverlight

  • Silverlight 4
    • engine
    • ogólne ulepszenia (style niejawne, rozszerzenia bindingu, komendy)
    • tekst (IME, zdarzenia TextBox)
    • media (obsługa kamery i audio, VideoBrush, poprawione oszczędzanie baterii przez MediaElement)
    • kontrolki (lepsza wydajność, RichTextBox, ViewBox, WebBrowser z IE9, ulepszenia w toolkicie)
    • schowek
    • komunikacja
      • sokety (TCP, UDP Unicast i Multicast)
      • inne (dostęp do pełnego nagłówka, obsługa wątków przez WebClient)
  • Ulepszenia w nawigacji
    • Możliwość usunięcia wpisu back z dziennika (co jest potrzebne w niektórych przypadkach)
  • Wsparcie dla wszystkich języków na telefonie
  • Podkreślanie niepoprawnych wyrazów na czerwono
  • Gesty na poziomie zdarzeń (Tap, DoubleTap, Hold)
  • Media (tryb 32 bit/pixel – co poprawia rysowanie gradientów, domyślnie 16)
  • Integracja z XNA
    • na poziomie strony i elementu
    • zaawansowane przypadki (nawigacja, texbox + klawiatura, wyświetlanie obrazu video i z kamery)
  • Wydajność (m.in listy)

Extras

  • Search
  • Muzyka
  • Zdjęcia

Narzędzia

  • Emulator
    • Emulacja akcelerometru i lokalizacji
    • Obsługa multi-touch
    • Screenshoty
    • Ingestion tool
    • Odtwarzanie H.264, AAC
    • Emulacja pamięci bardziej zbliżona do urządzenia
  • VS 2010
    • Multi-targeting
    • Nowy szablon dla multitaskingu
    • Debugowanie agentów w tle
    • Isolated Storage Explorer
    • Profiler (analizator wydajności)
  • Expression Blend
    • Multi-targeting
    • Wsparcie dla Visual Basic
    • Blend SDK
      • PathListBox
      • Shapes
      • Nowe zachowania
    • SketchFlow for Windows Phone (działa na desktopowym Silverlight)

Inne

  • ShellToast (możliwość wywołania systemowego komunikatu z ikoną, napisem i adresem który ma otwierać)
  • Visual Studio Async CTP
  • Klasa DeviceStatus (parametry urządzenia i aplikacji)
  • Klasa dla systemowego paska postępu (możliwość włączenia na pasku systemowym) 
  • MarketPlace Services
  • Pickers (?)

MarketPlace

  • Nowe formy dystrybucji
    • Beta (bez certyfikacji, do 100 osób, na 90 dni, kontrola dostępu, bez aktualizacji, darmowe)
    • Private (link wysyłany do wybranych ludzi, aplikacja nie jest znajdowana w publicznej wyszukiwarce, bez kontroli dostępu, darmowe/płatne)
  • Inne ulepszenia

O Silverlight 5 Beta napiszę później. Ten post będzie z pewnością aktualizowany (m.in w celu wprowadzania poprawek, uzupełnień).

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.