poniedziałek, 21 marca 2016

MVVM epizod 2

VIEW
Komunikacja pomiędzy View i ViewModel odbywa się poprzez
-data binding
-commands
-change notification event

ViewModel uaktualnia Model, konwertuje dane ,jest odpowiedzialny z validacje i łączenie danych aby wyświetlić je w View.

View jest odpowiedzialny za wygląd czyli to co widzi użytkownik. Idealny przypadek to gdy View zawiera wszystko w pliku XAML, a kod w C# posiada tylko konstruktor z metodą InitializeComponent().

Jednak kod w C# może zawierać elementy które ciężko jest zaimplementować w XAML-u takie jak animacje.

W View dataContext zawiera ViewModel. ViewModel implementuje właściwosci i commands które są wiązane z View.

View jest powiadamiane o zmianach poprzez changeNotificationEvents.

Przeważnie View jest klasą pochodną klasy Control lub UserControl ale w niektórych przypadkach view jest stworzony z data template.

Data template służy m.in do wiązania naszego view z viewModel. Data template może być zdefiniowany w controlce która go używa, lub w resource.dictionary .

Podsumowując:
-Głównym elementem View może być Window, Page, UserControl, DataTemplate.
-View jest połączone z ViewModel poprzez właściwośc DataContext.
-View może używać walidacji do sprawdzania wpisywanych danych.


<Window.Resources>
<DataTemplate DataType="{x:Type local:ProductViewModel}">
<DockPanel Margin="20">
<TextBox Text="{Binding Path=WarsztatId, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="Get Product" Command="{Binding Path=GetProductCommand}"/>
</DockPanel>
</DataTemplate>
</Window.Resources>
Powyżej prosty przykład mniej wiecej jak to ma wygladać ;D a wiecej info razem z kodem do pobrania znajdziecie na tej stronce.
ViewModel

ViewModel implementuje właściwosci, i commands które są powiązane z View dzięki data binding.

ViewModel jest odpowiedzialny z interakcję View z Model.

ViewModel nie posiada bezpośredniej referencji do View , ale informacja o zmianie danych jest komunikowana poprzez change notification events , dlatego musi dziedziczyć interfejs INotifyPropertyChanged lub INotifyCollectionChanged w przypadku gdy występuje kolekcja danych.

Co zawiera klasa ViewModel:
public class WarsztatViewModel : ObiektZImplemetacjaINCH
{
private WarsztatModel warsztat;
private int warsztatId;
private ICommand getProductCommand;
private ICommand saveProductCommand;

public int WarsztatId
{
get{return warsztatId};
set
{
if(value! = warsztatId)
{
warsztatId = value;
ZgloszenieZmianyValueDlaView("WarsztatId");
}
}
public WarsztatModel Warsztat
{
get{return warsztat};
set
{
if(value! = warsztat)
{
warsztat = value;
ZgloszenieZmianyValueDlaView("Warsztat");
}
}
}
public ICommand GetProductCommand
{
get
{
if(getProductCommand == null)
{
getProductCommand = new RelayCommand(
param => GetProduct(),
param => WarsztatId > 0
);
}
return getProductCommand;
}
}
private void GetProduct()
{

}
}


W kodzie powyżej nasza klasa dziedziczy po klasie w której został zaimplementowany interfejs INotifyPropertyChanged, ale kod tej klasy pokaże w następnym poście.
WarsztaViewModel zawiera obiekt WarsztatModel. Widzimy że przy modyfikacji tego obiektu zostanie najpierw sprawdzony warunek czy faktycznie coś się zmieniło a jeżeli się zmieniło to zostaje wywołana metoda ZgloszenieZmianyValueDlaView("Warsztat") czyli jak sama metoda mówi za siebie zostaje wysłanie info dla View że coś się zmieniło i że trzeba aktualizować wartość naszego pola w View.
Obiekty typu ICommand posłuża do wywoływania metod np gdy naciśniemy buttona.
Po kliknieciu buttona którego właściwosc Command jest bindowana do GetProductCommand tworzyny jest nowy obiekt RelayCommand, a
parametry konstruktora to kolejno funkcja która się wykona, i warunek który jeżeli jest spełniony pozwoli na wykonanie funkcji.

<Button> Content="Get" VerticalAlignment="Center"
Command="{Binding Path=GetProductCommand}" Width="100"/>
Model

Model jest odpowiedzialny za zarządzanie danymi.

Nie posiada referencji do View ani do ViewModel i nie jest zależny od ich implementacji.

Model tak jak ViewModel dziedziczy po INotifyPropertyChanged. Dzięki temu może być również powiązany poprzez binding w View.

Jest również wykorzystywany do uzyskiwania danych z baz danych itp.

Brak komentarzy:

Prześlij komentarz