Często podczas użytkowania programów zachodzi konieczność pokazania dodatkowego okna, służącego do interakcji z użytkownikiem. Najczęściej okno takie należy pokazać w określonym przypadku. Jak już wcześniej zostało wspomniane cała logika powinna być umieszczona w ViewMoedlu, zatem nasuwa się pytanie, w jaki sposób z ViewModelu pokazać okno modalne - przecież ViewModel nie powinien mieć żadnych informacji o widoku. Rozwiązanie tego problemu polega na oddelegowaniu pokazywania widoków lub MessageBox-ów do wyspecjalizowanych klas tzw. serwisów. Ponadto w przypadku gdy chcemy pokazywać proste komunikaty możemy również skorzystać z Interaction/Interactivity oraz klasy Prisma InteractionRequest<T>. 1. InteractionRequest<T>Jak już wcześniej wspomniano klasa InteractionRequest<T>...
środa, 30 listopada 2011
wtorek, 29 listopada 2011
Prism cz. 6 - Interactivity oraz Interaction
Interactions oraz Interactivity są to dwie dll-ki, które poszerzają sposób komunikacji pomiędzy widokiem oraz ViewModelem. Wprowadzają one nowy typ EventTriggerów(w Silverlighcie nie ma triggerów, natomiast w WPF-ie event triggery można praktycznie używać jedynie do animacji) oraz dodatkowo wprowadzają ciekawe sposoby(funkcje) na interakcję widoku z ViewModelem. Pierwszym z tych sposobów jest użycie właściwości InvokeCommandAction.Jak sama nazwa wskazuje można wywołać komendę z ViewModelu. Jaka jest różnica między wywołaniem komendy poprzez InvokeCommandAction, a Command="{Binding CommandName}" ? InvokeCommandAction ma tą przewagę nad normalnm bindowaniem do property Command,że pozwala wywołać daną komendę w odpowiedzi na zajście jakiegoś zdarzenia na widoku. Przykładowe użycie może wyglądać...
Prism cz.5 - CommandBehaviors
Analizując wcześniejsze przykłady pokazujące użycie DelegateCommand można odnieść wrażenie, że mimo tego iż są one bardzo użyteczne,ich użycie jest niestety bardzo ograniczone. Jedynie niektóre komponenty WPF-a i Silverlight-a mają właściwość Command do której można zbindować nasz obiekt DelegateCommand.Ponadto właściwość ta reaguje jedynie na wybrane zahardcodowane w kontrolce zdarzenie (zdarzenie Click). Co w przypadku gdybyśmy chcieli zareagować np. na zdarzenie MouseMove za pomocą komendy? Nasz problem możemy rozwiązać poprzez:InteractivityInteractionsCommandBehaviorsW tym poście zostanie przedstawione rozwiązanie trzecie - CommandBehaviorsPierwszą rzeczą jaką należy zrobić w celu stworzenia komendy reagującej na inne zdarzenie niż Click jest stworzenie klasy dziedziczącej po CommandBehaviorBase....
Prism cz.4 - Komendy

1. DelegateCommandsDelegateCommands w Prismie są to obiekty, które implementują interfejs ICommand, służą one do interakcji widoku z ViewModelem. Korzystając z Prisma nie musimy już pisać własnej klasy implementującej ten interfejs (tak jak to zrobiliśmy tutaj). Konstruktor klasy DelegateCommand przyjmuje dwa parametry:Action execteMethod - funkcja odpalania przy wywołaniu komendy,Func<bool> canExecuteMethod - funkcja sprawdzająca czy daną komendę można wywołaćDelegateCommands z Prisma używamy w taki sam sposób w jaki używaliśmy komend w tym poście.2. CompositeCommandsCompositeCommands są to obiekty, które przechowują kolekcją obiektów...
Prism cz. 3 - Regiony

Regiony są podstawą aplikacji napisanych za pomocą Prism'a. Ułatwiają nawigację po programie i pozwalają na dynamiczną lokację widoków w naszej aplikacji. Regiony dzielą graficzny interfejs użytkownika na obszary, do których wczytywane są odpowiednie widoki. Wystarczy w kodzie wpisać że do Regionu A trzeba załadować Widok B. Prosty podział standardowej aplikacji na regiony może wyglądać tak:W xaml'u wyglądałoby to mniej więcej w ten sposób:<Grid ...> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="4*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> ...
Prism cz. 2: Moduły
Czym tak naprawdę jest moduł? Moduł jest to zbiór widoków i funkcji aplikacji, które można odseparować od reszty. Moduł może być równie dobrze jedynie serwisem bez graficznego interfejsu użytkownika. Poszczególne moduły powinny móc komunikować się pomiędzy sobą, jednak komunikacja nie powinna naruszać ich niezależności. Sam użytkownik nie powinien mieć świadomości modularności aplikacji, która jest dla niego spójna i łatwa w użyciu.No dobra, ale po co pisać aplikacje modułowe? Jeżeli stworzyliśmy aplikację modułową zgodnie ze sztuką, wówczas jest ona łatwa do testowania, utrzymania i rozwijania w przyszłości. Można bezproblemu dodawać nowe funkcjonalności nie ingerując w istniejący kod i rozwiązania. Każdy moduł może być osobno testowany wdrażany i rozwijany, ponieważ jest niezależną jednostką.Bardzo...
poniedziałek, 28 listopada 2011
ListViewCollection oraz PagedCollectionView
1. ListViewCollection (WPF)ListViewCollection jest to kolekcja wprowadzona do WPF-a, która wspiera sortowanie, grupowanie oraz filtrowanie. Kolekcję taką tworzymy w następujący sposóbList<Player> palyerList = new Player { new Player(),new Player()};public ListViewCollection<Player> PlayerListCollectionView {get;set;}ListViewCollection<Player> PlayerListCollectionView= new ListViewCollection<Player>(playerList);czyli po prostu w konstruktorze przesyłamy obiekt implementujący interfejs IEnumerableFiltrowanieW celu przefiltrowania kolekcji wystarczy podać odpowiedni obiekt typu Predicate<object>(czyli tak naprawdę wystarczy napisać funkcję zwracającą bool oraz przyjmującą w parametrze obiekt). Załóżmy, że chcemy pokazać na widoku jedynie tych graczy, który nazywają...
WPF: Tworzenie własnych kontrolek
Tworzenie własnych kontrolek w WPF jest z pozoru łatwym zadaniem, klikamy Add-> new UserControl-> i wrzucamy do Contentu nowo powstałej kontrolki co nam się tylko podoba :) kontrolka działa, jest piękna i wszystko jest git. Nie jest to jednak najlepsze rozwiązanie.Wady:- w 99% przypadków stworzymy "ciężki" obiekt, który ma masę funkcjonalności do niczego nie potrzebnych.- zaszywamy całą logikę w code-behind (odwołania przez Name do elementów w xaml'u). Co się stanie gdy musimy zmienić coś w xamlu, np podmienić ListBox'a na Grida. Nagle połowa naszych metod, które odwoływały się do tego ListBoxa musi zostać usunięta i napisana od nowa (trudniej skalowalny komponent).Zalety:- Często szybsza implementacja.Na szczęście Microsoft zaopatrzył nas w całą gamę klas, które mogą nam posłużyć za...
Walidacja
Walidacja jest to technika sprawdzająca, czy dany obiekt spełnia pewne założenia poprawności danych. W WPF-ie oraz Silverlighcie istnieją trzy sposoby walidacji obiektów:walidacja poprzez rzucanie wyjątków,walidacja z użyciem interfejsu IDataErrorInfo,walidacja z użyciem interfejsu INotifyDataErrorInfo1. Walidacja poprzez rzucanie wyjątkówWalidacja poprzez rzucanie wyjątków odbywa się w następujący sposób. W seterze danej właściwości dodajemy warunek sprawdzający czy wpisane dane są poprawne. Jeżeli nie to najzwyczajniej w świecie rzucamy wyjątek, w którym podajemy komunikat błędu. Przykładowy properties z walidacją może wyglądać w ten sposób: private string _name; public string Name { get { return _name; } set { _name = value;...
Routed Events - nowy rodzaj zdarzeń w WPF-ie
RoutedEvent jest to nowy typ zdarzeń, który po raz pierwszy został zaprezentowany w WPF-ie. Głównym założeniem RoutedEventów jest to, że w momencie wywołania takiego zdarzenia może ono podróżować w górę, lub w dół drzewa wizualnego oraz drzewa logicznego. Każdy RoutedEvent może przyjmować jedną z trzech strategii poruszania się po drzewie:Bubbling- zdarzenie najpierw jest wywoływane w elemencie źródłowym, a następnie podróżuje ono w górę drzewa wizualnego (od naszego elementu do korzenia drzewa), aż do roota (lub do momenty gdy nie zostanie obsłużone poprzez e.Handled = true)Tunelling - zdarzenie wywoływane jest w korzeniu drzewa, a następnie podróżuje w dół drzewa, aż osiągnie element źródłowy (lub gdy nie zostanie obsłużone poprzez e.Handled = true)Direct - zdarzenie jest wywoływane tylko...
Triggers - Trigery
Trigery jest to mechmizm WPF-a służący reakcji UI na jakieś zdarzenie. Wyróżniamy cztery rodzaje triggerówProperty triggers - używane do zareagowanie na zmiany dependency property w danej kontrolce, Data triggers - używane do zareagowanie na zmiany w bindowanych obiektach- można podłączyć się do właściwości z DataContextu jak i z danej kontrolki,MultiDataTriggers - używane do reagowania na zmiany kilku właściwości,MultiTrigger - używane do reagowania na zmiany kilku dependecy property w danej kontrolce,Event triggers - używane do reagowania na jakieś zdarzenie - służą do odpalania animacji1. Property triggers Oto przykład wykorzystania Property Triggera. W ResourceDictionary tworzymy styl, który zostanie przypisany do przycisku.<Style TargetType="{x:Type Button}"> <Style.Triggers>...
WPF - Templates
DataTemplateW kontrolkach, typu ItemsControl (np. ListBox, ComboBox), które wyświetlają wiele obiektów, można zdefiniować szablon, który definiuje jak ma wyglądać pojedynczy wyświetlany obiekt. Robimy to za pomocą property ItemTemplate, do której przypisujemy obiekt typu DataTemplate....Resources> <DataTemplate x:Key="ItemTemplateKey"> <TextBlock Text="item"/> </DataTemplate></...Resources>…<ListBox ItemTemplate="{StaticResource ItemTemplateKey}" ItemsSource="{Binding Items}"/>W takim wypadku, każdy Item w listboxie będzie napisem “item”. Dla DataTemplate’a można ustawiać triggery i odwoływać się do elementów wewnątrz za pomocą TargetName.<DataTemplate.Triggers> <SomeTrigger... <Setter Property="BorderBrush" Value="Red" TargetName="border"...
Style
Style jest to mechanizm wprowadzony w WPF-ie, a następnie w Silverlighcie, dzięki któremu w łatwy sposób można ujednolicić wygląd elementów naszej aplikacji.Style z reguły definiowane są w zasobach. Mogą to być zarówno zasoby całej aplikacji, danego okna lub nawet wybranej kontrolki. Przykładowy styl może wyglądać w następujący sposób:<Style x:Key="przycisk"> <Setter Property="Button.FontSize" Value="22" /> <Setter Property="Button.Background" Value="Orange" /> <Setter Property="Button.Width" Value="60" /> </Style>Każdy styl jest rozpoznawany dzięki unikalnemu kluczowi - parametr x:Key. Możliwe jest pominięcie klucza, w przypadku gdy ustawiona zostanie właściwść TargetType. Jednakże zdefiniowanie właściwości TargetType spowoduje, że dany styl...
WPF - Resources
Właściwość Resources jest zdefiniowana w klasie FrameworkElement i jest dostępna we wszystkich klasach jej pochodnych. Właściwość ta zawiera dostępne dla danego widoku zasoby. Property Resources jest typu ResourceDictionary i możemy tam wrzucić dowolny obiekt dostępny w .NET. ResourceDictionary jest to słownik gdzie kluczem jest string lub typ, natomiast wartością może być dowolny obiekt. W xamlu Resources definiujemy w następujący sposób:<Window.Resources> <System:String x:Key="hulk">meHulk</System:String> <Style TargetType="Button"/> <Style TargetType="{x:Type ListBox}"/></Window.Resources>W przypadku gdy kluczem jest typ możemy go zdefiniować na dwa sposoby ( z użyciem x:Type lub z jego pominięciem) tak jak widać w przykładzie powyżej....
Hands on mocking1. WprowadzenieDokument przybliża idee i metody stosowane przy tworzeniu testów jednostkowych, do symulowania obiektów. Tytuł wynika z popularności pojęcia "Mock", ale nie oznacza, że opisane zagadnienia ograniczają się do tej techniki. Precyzyjne uwagi dotyczące terminologii znajdą się punkcie 2. Pierwsza część opisuje powody stosowania takich rozwiązań w testach jednostkowych i zyski, które można dzięki nim osiągnąć. W dalszej części przedstawię dwa ogólne podejścia do wykorzystania mocków w procesie wytwarzania oprogramowania. 2. "Doubles" - why do we need them?a. Terminologia Zanim przedstawione zostaną motywacje stosowania mockowania i innych technik, konieczne jest usystematyzowanie terminologii, używanej w dalszej części artykulu. Określenie "double" zastosowane w tytule...