Programowanie Windows MVVM w WPF ale najpierw MVC

  • Slides: 48
Download presentation
Programowanie Windows MVVM w WPF … ale najpierw MVC i MVP Jacek Matulewski 9

Programowanie Windows MVVM w WPF … ale najpierw MVC i MVP Jacek Matulewski 9 października 2019 http: //www. fizyka. umk. pl/~jacek/dydaktyka/winprog_v 2/

Inżynieria oprogramowania – Wzorce projektowe Jacek Matulewski Instytut Fizyki, UMK WWW: http: //www. fizyka.

Inżynieria oprogramowania – Wzorce projektowe Jacek Matulewski Instytut Fizyki, UMK WWW: http: //www. fizyka. umk. pl/~jacek E-mail: jacek@fizyka. umk. pl Reklama Inżynieria oprogramowania Wzorzec architekt. MVC WWW: http: //www. fizyka. umk. pl/~jacek/dydaktyka/inzynieria/index. html semestr letni 2016

Inżynieria oprogramowania – Wzorce projektowe Główna lektura 1 Głównym materiałem źródłowym jest książka tzw.

Inżynieria oprogramowania – Wzorce projektowe Główna lektura 1 Głównym materiałem źródłowym jest książka tzw. gangu czworga pt. „Wzorce projektowe”.

Inżynieria oprogramowania – Wzorce projektowe Główna lektura 1 Głównym materiałem źródłowym jest książka tzw.

Inżynieria oprogramowania – Wzorce projektowe Główna lektura 1 Głównym materiałem źródłowym jest książka tzw. gangu czworga pt. „Wzorce projektowe”.

Inżynieria oprogramowania – Wzorce projektowe Główna lektura 2 Dodatkowo wykorzystamy adaptacje do C# wzorców

Inżynieria oprogramowania – Wzorce projektowe Główna lektura 2 Dodatkowo wykorzystamy adaptacje do C# wzorców G 4 opisane w książce S. J. Metskera

Inżynieria oprogramowania – Wzorce projektowe Inspiracja Christopher Alexander – architekt, teoretyk architektura zorientowana na

Inżynieria oprogramowania – Wzorce projektowe Inspiracja Christopher Alexander – architekt, teoretyk architektura zorientowana na człowieka np. kształtowanie przestrzeni

Inżynieria oprogramowania – Wzorce projektowe Inspiracja Władimir Propp, Joseph Cambell – konstrukcja opowieści (mit/bajka/powieść/film)

Inżynieria oprogramowania – Wzorce projektowe Inspiracja Władimir Propp, Joseph Cambell – konstrukcja opowieści (mit/bajka/powieść/film) „Wyprawa Bohatera” – zbiór stałych elementów (typy bohaterów) i budowy fabuły (etapy) Christopher Vogler – „Podróż autora”, poradnik

Inżynieria oprogramowania – Wzorce architektoniczne Przykładowy projekt: „Labirynt” • Aplikacja konsolowa zaprojektowana zgodnie ze

Inżynieria oprogramowania – Wzorce architektoniczne Przykładowy projekt: „Labirynt” • Aplikacja konsolowa zaprojektowana zgodnie ze wzorcem architektonicznym MVC, czyli Model-View-Controler • Model – dane i logika labiryntu • Widok – moduł rysujący Użytkownik labirynt w konsoli używa jest oglądany • Kontroler – przyjmuje Kontroler Widok wejście z klawiatury, modyfikuje model modyfikuje aktualizuje Model

Inżynieria oprogramowania – Wzorce architektoniczne Architektura MVC Kontrola oraz przepływ informacji między modułami aplikacji

Inżynieria oprogramowania – Wzorce architektoniczne Architektura MVC Kontrola oraz przepływ informacji między modułami aplikacji w architekturze MVC Użytkownik używa jest oglądany Kontroler Widok modyfikuje aktualizuje Model

Inżynieria oprogramowania – Wzorce architektoniczne Architektura MVC • Jest wiele wersji samego MVC (+

Inżynieria oprogramowania – Wzorce architektoniczne Architektura MVC • Jest wiele wersji samego MVC (+ MVP) • My zaimplementujemy wersję z pasywnymi modelem i widokiem (passive) oraz nadzorującym kontrolerem (supervising) lepiej pasujący do konsoli Użytkownik (bez zdarzeń) używa jest oglądany • Kontrolera zredukujemy do funkcji main aktualizuje Kontroler Widok modyfikuje Model

Inżynieria oprogramowania – Wzorce architektoniczne Przykładowy projekt: „Labirynt”

Inżynieria oprogramowania – Wzorce architektoniczne Przykładowy projekt: „Labirynt”

Inżynieria oprogramowania – Wzorce architektoniczne Model (klasa Labirynt) Pasywny model przechowujący stan aplikacji VC++:

Inżynieria oprogramowania – Wzorce architektoniczne Model (klasa Labirynt) Pasywny model przechowujący stan aplikacji VC++: Solution Explorer, View Class Diagram

Inżynieria oprogramowania – Wzorce architektoniczne Model (klasa Labirynt) Klasy modelu (C++) class Miejsce. WLabiryncie

Inżynieria oprogramowania – Wzorce architektoniczne Model (klasa Labirynt) Klasy modelu (C++) class Miejsce. WLabiryncie { public: virtual Rezultat. Próby. Wejścia Spróbuj. Wejść() = 0; virtual int Wejdź(int indeks. Bieżącej. Komórki) { return -1; } virtual bool Otwórz() { return false; } }; class Komórka : public Miejsce. WLabiryncie {. . . enum Rezultat. Próby. Wejścia { Nieokreślony = 0, Powodzenie, Nie. Można. Wejść, Zamknięte }; enum Kierunek { Północ = 0, Południe = 1, Wschód = 2, Zachód = 3 }; enum Stan. Gry { Niezakończona = 0, Śmierć, Wygrana };

Inżynieria oprogramowania – Wzorce architektoniczne Model (klasa Labirynt) Klasy modelu (C++) class Komórka :

Inżynieria oprogramowania – Wzorce architektoniczne Model (klasa Labirynt) Klasy modelu (C++) class Komórka : public Miejsce. WLabiryncie { private: int indeks; Miejsce. WLabiryncie* sąsiednie. Miejsca[4]; public: Komórka(int indeks); Miejsce. WLabiryncie* Pobierz. Miejsce. Po. Stronie(Kierunek kierunek) const; void PowiążZMiejscem(Kierunek kierunek, Miejsce. WLabiryncie* miejsce); virtual Rezultat. Próby. Wejścia Spróbuj. Wejść(); virtual int Wejdź(int indeks. Bieżącej. Komórki); int Pobierz. Indeks(); bool Otwórz. Drzwi(Kierunek kierunek); bool Otwórz. Drzwi(); };

Inżynieria oprogramowania – Wzorce architektoniczne Model (klasa Labirynt) Klasy modelu (C++) class Labirynt {

Inżynieria oprogramowania – Wzorce architektoniczne Model (klasa Labirynt) Klasy modelu (C++) class Labirynt { private: int liczba. Komórek; PKomórka* komórki; int indeks. Bieżącej. Komórki, indeks. Celu; Stan. Gry stan. Gry = Niezakończona; public: Labirynt(int liczba. Komórek, int indeks. Początkowej. Komórki, int indeks. Celu); ~Labirynt(); void Dodaj. Komórkę(int indeks, Komórka* komórka); Komórka* Pobierz. BieżącąKomórkę(); Rezultat. Próby. Wejścia PrzejdźWKierunku(Kierunek kierunek); void Zakończ(); Stan. Gry Pobierz. Stan. Gry(); };

Inżynieria oprogramowania – Wzorce architektoniczne Widok (klasa Widok) Klasa widoku (zbiór funkcji bez własnego

Inżynieria oprogramowania – Wzorce architektoniczne Widok (klasa Widok) Klasa widoku (zbiór funkcji bez własnego stanu) #pragma once #include "Model. h" class Widok { private: Labirynt* model; public: Widok(Labirynt* model); static void Wyświetl. InformacjęOKomórce(Komórka* komórka); void Wyświetl. InformacjęOBieżącej. Komórce() const; static void Wyświetl. InformacjęOPróbie. Przejścia. WKierunku(Kierunek kierunek); void Wyświetl. InformacjęORezultacie. Próby. Przejścia(Rezultat. Próby. Wejścia) const; void Wyświetl. InformacjęOPróbie. Otwarcia. Drzwi() const; void Wyświetl. InformacjęORezultacie. Próby. Otwarcia. Drzwi(bool wynik) const; void Wyświetl. InformacjęOStanie. Gry() const; };

Inżynieria oprogramowania – Wzorce architektoniczne Kontroler (funkcja main) #pragma once #include "Model. h" #include

Inżynieria oprogramowania – Wzorce architektoniczne Kontroler (funkcja main) #pragma once #include "Model. h" #include "Widok. h" class Kontroler { protected: Labirynt* model; Widok* widok; void Spróbuj. Przejść(Kierunek kierunek); void Spróbuj. OtworzyćDrzwi(); public: Kontroler(void); ~Kontroler(void); void Uruchom(); };

Inżynieria oprogramowania – Wzorce architektoniczne Funkcja main widzi tylko kontroler. Kontroler tworzy instancje modelu

Inżynieria oprogramowania – Wzorce architektoniczne Funkcja main widzi tylko kontroler. Kontroler tworzy instancje modelu i widoku: #include "Kontroler. h" int main(int argc, char* argv[]) { Kontroler kontroler; kontroler. Uruchom(); return 0; }

Wzorzec MVP (model-view-presenter) - wzorzec architektoniczny dla aplikacji z graficznym interfejsem użytkownika (GUI) stworzony

Wzorzec MVP (model-view-presenter) - wzorzec architektoniczny dla aplikacji z graficznym interfejsem użytkownika (GUI) stworzony w Microsoft na potrzeby aplikacji Windows Forms Model – przechowuje dane (stan aplikacji), które mogą być prezentowane lub edytowane w GUI Widok – pasywny moduł prezentujący dane i przyjmująca żądania użytkownika poprzez kontrolki W projekcie być wiele widoków, Presenter – świadomy modelu i widoku, może pośredniczy między nimi ma swój jeden presenter – wiąże model wazkażdy widokiem rozszerzając zakres kodu, który może być objęty Widoktestami nie znajednostkowymi, źródła danych, tworzy wiązania. umie je tylko pokazywać. Danymi zapełnia go presenter.

Wzorzec MVP ? http: //msdn. microsoft. com/en-us/library/ff 647859. aspx

Wzorzec MVP ? http: //msdn. microsoft. com/en-us/library/ff 647859. aspx

MVC, MVP, MVVM https: //tomyrhymond. wordpress. com/2011/09/16/mvc-mvp-and-mvvm/

MVC, MVP, MVVM https: //tomyrhymond. wordpress. com/2011/09/16/mvc-mvp-and-mvvm/

Warstwy wzorca MVVM

Warstwy wzorca MVVM

Warstwy wzorca MVVM Widok – kod XAML (bez własnego kodu C#!) Model – czysty

Warstwy wzorca MVVM Widok – kod XAML (bez własnego kodu C#!) Model – czysty kod C# (nie jest świadomy ani wzorca, ani wyższych „technologii”)

Warstwy wzorca MVVM Model widoku – reprezentuje model przed widokiem (filtrowanie, przekształcanie i udostępnianie

Warstwy wzorca MVVM Model widoku – reprezentuje model przed widokiem (filtrowanie, przekształcanie i udostępnianie danych). Jednocześnie jest abstrakcją widoku.

Warstwy wzorca MVVM Odpowiedzialność grafika (kod XAML) Osobne narzędzie Blend for VS 2017 Nie

Warstwy wzorca MVVM Odpowiedzialność grafika (kod XAML) Osobne narzędzie Blend for VS 2017 Nie wymaga VM, a jedynie wiązań (kontrakt) Odpowiedzialność programisty C# Testy jednostkowe (także VM) Model może być pasywny lub aktywny Rozwój M i VM nie wymaga widoku (ustalane są tylko udostępniane w VM własności i polecenia). Mniejsza zależność i liczba kontaktów

Przykład aplikacji MVVM Model using System; namespace Asystent. Zakupów. WPF. Model { public class

Przykład aplikacji MVVM Model using System; namespace Asystent. Zakupów. WPF. Model { public class Sumowanie. Kwot { public decimal Limit { get; private set; } public decimal Suma { get; private set; } public Sumowanie. Kwot(decimal limit, decimal suma = 0) { this. Limit = limit; this. Suma = suma; }. . . } }

Przykład aplikacji MVVM Model using System; namespace Asystent. Zakupów. WPF. Model { public class

Przykład aplikacji MVVM Model using System; namespace Asystent. Zakupów. WPF. Model { public class Sumowanie. Kwot {. . . public bool Czy. Kwota. Jest. Poprawna(decimal kwota) { bool czy. Dodatnia = kwota > 0; bool czy. Przekroczy. Limit = Suma + kwota > Limit; return czy. Dodatnia && !czy. Przekroczy. Limit; }. . . } }

Przykład aplikacji MVVM Model using System; namespace Asystent. Zakupów. WPF. Model { public class

Przykład aplikacji MVVM Model using System; namespace Asystent. Zakupów. WPF. Model { public class Sumowanie. Kwot {. . . public void Dodaj(decimal kwota) { if (!Czy. Kwota. Jest. Poprawna(kwota)) throw new Argument. Out. Of. Range. Exception( "Kwota zbyt duża lub ujemna"); Suma += kwota; } } }

Przykład aplikacji MVVM Widok Text. Block Text. Box, tb. Kwota Button, btn. Dodaj

Przykład aplikacji MVVM Widok Text. Block Text. Box, tb. Kwota Button, btn. Dodaj

Przykład aplikacji MVVM Widok <Window x: Class="Asystent. Zakupów. WPF. Main. Window" xmlns="http: //schemas. microsoft.

Przykład aplikacji MVVM Widok <Window x: Class="Asystent. Zakupów. WPF. Main. Window" xmlns="http: //schemas. microsoft. com/winfx/2006/xaml/presentation" xmlns: x="http: //schemas. microsoft. com/winfx/2006/xaml" xmlns: d="http: //schemas. microsoft. com/expression/blend/2008" xmlns: mc="http: //schemas. openxmlformats. org/markup-compatibility/2006" xmlns: local="clr-namespace: Asystent. Zakupów. WPF" mc: Ignorable="d" Resize. Mode = "No. Resize" Title="Asystent zakupów" Height="200" Width="200"> <Grid. Row. Definitions> <Row. Definition Height="1*" /> </Grid. Row. Definitions>. . . </Grid> </Window>

Przykład aplikacji MVVM Widok <Window x: Class="Asystent. Zakupów. WPF. Main. Window". . . >

Przykład aplikacji MVVM Widok <Window x: Class="Asystent. Zakupów. WPF. Main. Window". . . > <Grid. Row. Definitions>. . . </Grid. Row. Definitions> <Text. Block Horizontal. Alignment="Left" Grid. Row="0" Font. Size="25" Foreground="Navy" Margin="10"> Suma: <Run Foreground="Black" Font. Family="Courier New" Text="0" /> </Text. Block> <Text. Box x: Name="tb. Kwota" Font. Size="30" Font. Family="Courier New" Text. Alignment="Right" Margin="10" Grid. Row="1" Text="0" /> <Button x: Name="btn. Dodaj" Content="Dodaj" Font. Size="20" Margin="10" Grid. Row="2" /> </Grid> </Window>

Przykład aplikacji MVVM Model widoku using System. Windows; using System. Windows. Input; using System.

Przykład aplikacji MVVM Model widoku using System. Windows; using System. Windows. Input; using System. Component. Model; namespace Asystent. Zakupów. WPF. Model. Widoku { using Model; Instancja modelu public class Model. Widoku : INotify. Property. Changed { private Sumowanie. Kwot model = new Sumowanie. Kwot(1000); public string Suma { get { return model. Suma. To. String(); } } Udostępnianie danych modelu Zamiast konwersji konwerter!

Przykład aplikacji MVVM Model widoku using. . . namespace Asystent. Zakupów. WPF. Model. Widoku

Przykład aplikacji MVVM Model widoku using. . . namespace Asystent. Zakupów. WPF. Model. Widoku { using Model; Powiadamianie widoku o zmianach własności public class Model. Widoku : INotify. Property. Changed {. . . public event Property. Changed. Event. Handler Property. Changed; private void on. Property. Changed(string nazwa. Własności) { Property. Changed? . Invoke( this, new Property. Changed. Event. Args(nazwa. Własnoscinazwa. Własności)); }

Przykład aplikacji MVVM Model widoku public class Model. Widoku : INotify. Property. Changed {.

Przykład aplikacji MVVM Model widoku public class Model. Widoku : INotify. Property. Changed {. . . private ICommand dodaj. KwotęCommand; public ICommand Dodaj. Kwotę { get { if (dodaj. KwotęCommand == null) dodaj. KwotęCommand = new Relay. Command(. . . ); return dodaj. KwotęCommand; } } Polecenie (reagowanie na działania użytkownika w widoku) } Klasa Relay. Command (nie ma w. NET) Jej implementacja będzie na ćwiczeniach

Przykład aplikacji MVVM Model widoku using. . . namespace Asystent. Zakupów. WPF. Model. Widoku

Przykład aplikacji MVVM Model widoku using. . . namespace Asystent. Zakupów. WPF. Model. Widoku { using Model; public class Model. Widoku : INotify. Property. Changed {. . . Metoda pomocnicza private bool czyŁańcuch. Kwoty. Jest. Poprawny(string s) { if (string. Is. Null. Or. White. Space(s)) return false; decimal kwota; if (!decimal. Try. Parse(s, out kwota)) return false; else return model. Czy. Kwota. Jest. Poprawna(kwota); }

Przykład aplikacji MVVM Model widoku public class Model. Widoku : INotify. Property. Changed {.

Przykład aplikacji MVVM Model widoku public class Model. Widoku : INotify. Property. Changed {. . . private ICommand dodaj. KwotęCommand; public ICommand Dodaj. Kwotę { get { if (dodaj. KwotęCommand == null) dodaj. KwotęCommand = new Relay. Command(execute, can. Execute); return dodaj. KwotęCommand; } } Polecenie (reagowanie na działania użytkownika w widoku) }

Przykład aplikacji MVVM Model widoku Wyrażenia Lambda: () => { } dodaj. KwotęCommand =

Przykład aplikacji MVVM Model widoku Wyrażenia Lambda: () => { } dodaj. KwotęCommand = new Relay. Command( Przekazanie działania do modelu (model odpowiada za stan aplikacji) (object argument) => //execute { decimal kwota = decimal. Parse((string)argument); model. Dodaj(kwota); on. Property. Changed("Suma"); }, (object argument) => //can execute { return CzyŁańcuch. Kwoty. Jest. Poprawny((string)argument); } ); Weryfikacja możliwości wykonania działania (wynik zwracany poprzez własność Can. Execute → informacja zwrotna w widoku)

Przykład aplikacji MVVM Widok – wiązania <Window x: Class="Asystent. Zakupów. WPF. Main. Window" xmlns="http:

Przykład aplikacji MVVM Widok – wiązania <Window x: Class="Asystent. Zakupów. WPF. Main. Window" xmlns="http: //schemas. microsoft. com/winfx/2006/xaml/presentation" xmlns: x="http: //schemas. microsoft. com/winfx/2006/xaml" xmlns: d="http: //schemas. microsoft. com/expression/blend/2008" xmlns: mc="http: //schemas. openxmlformats. org/markup-compatibility/2006" xmlns: local="clr-namespace: Asystent. Zakupów. WPF" xmlns: mw="clr-namespace: Asystent. Zakupów. WPF. Model. Widoku" mc: Ignorable="d" Title="Asystent zakupów" Height="200" Width="200"> <Window. Data. Context> <mw: Model. Widoku /> </Window. Data. Context> <Grid>. . . </Grid> </Window> Instancja modelu widoku w widoku

Przykład aplikacji MVVM Widok – wiązania <Grid>. . . <Text. Block Horizontal. Alignment="Left" Vertical.

Przykład aplikacji MVVM Widok – wiązania <Grid>. . . <Text. Block Horizontal. Alignment="Left" Vertical. Alignment="Top" Font. Size="25" Foreground="Navy" Grid. Row="0" Margin="10, 10, 10"> Suma: <Run Foreground="Black" Font. Family="Courier New" Text="{Binding Path=Suma, Mode=One. Way}" /> </Text. Block> <Text. Box x: Name="tb. Kwota" Font. Size="30" Font. Family="Courier New" Text. Alignment="Right" Margin="10, 10, 10" Grid. Row="1" Text="0" /> <Button x: Name="btn. Dodaj" Content="Dodaj" Font. Size="20" Margin="10, 10, 10" Grid. Row="2" Command="{Binding Dodaj. Kwotę}" Command. Parameter="{Binding Element. Name=tb. Kwota, Path=Text}" /> </Grid>

Przykład aplikacji MVVM Widok – konwerter namespace Asystent. Zakupów. WPF { class Bool. To.

Przykład aplikacji MVVM Widok – konwerter namespace Asystent. Zakupów. WPF { class Bool. To. Brush. Converter : IValue. Converter { public object Convert(object value, Type target. Type, object parameter, System. Globalization. Culture. Info culture) { bool b = (bool)value; return b ? Brushes. Black : Brushes. Red; } public object Convert. Back(object value, Type target. Type, object parameter, System. Globalization. Culture. Info culture) { throw new Not. Implemented. Exception(); } } } Konwertery także można testować testami jednostkowymi

Przykład aplikacji MVVM Widok – konwerter <Window x: Class="Asystent. Zakupów. WPF. Main. Window" xmlns="http:

Przykład aplikacji MVVM Widok – konwerter <Window x: Class="Asystent. Zakupów. WPF. Main. Window" xmlns="http: //schemas. microsoft. com/winfx/2006/xaml/presentation" xmlns: x="http: //schemas. microsoft. com/winfx/2006/xaml" xmlns: d="http: //schemas. microsoft. com/expression/blend/2008" xmlns: mc="http: //schemas. openxmlformats. org/markup-compatibility/2006" xmlns: local="clr-namespace: Asystent. Zakupów. WPF" xmlns: mw="clr-namespace: Asystent. Zakupów. WPF. Model. Widoku" mc: Ignorable="d" Title="Asystent zakupów" Height="200" Width="200"> <Window. Resources> <local: Bool. To. Brush. Converter x: Key="bool. To. Brush" /> </Window. Resources>. . . <Text. Box x: Name="tb. Kwota" Font. Size="30" Font. Family="Courier New" Text. Alignment="Right" Margin="10, 10, 10" Grid. Row="1" Text="0" Foreground="{Binding Element. Name=btn. Dodaj, Path=Is. Enabled, Mode=One. Way, Converter={Static. Resource bool. To. Brush}}" />. . . Multibinding – IMulti. Value. Converter → na ćwiczeniach

Wiązania Text="{Binding Source={Static. Resource źródło}, Path=Własność, Mode=One. Way, Converter={Static. Resource konwerter} String. Format=Cena (zł):

Wiązania Text="{Binding Source={Static. Resource źródło}, Path=Własność, Mode=One. Way, Converter={Static. Resource konwerter} String. Format=Cena (zł): {0: C}}" Path – własność (zależności) obiektu „dowiązywanego” (źródło wiązania, binding source); nazwa atrybutu może być pominięta Source – jawne wskazanie na źródło wiązania (np. z zasobów); domyślnie odczytywany z Data. Context Relative. Source – źródło w drzewie widoku np. {Binding Relative. Source={Relative. Source Self}, Path=Własność}" Element. Name – wskazanie na element XAML/kontrolkę (zamiast użycia kontekstu danych); wiązanie w obrębie widoku Mode = Two. Way (domyślne WPF) | One. Way (domyślne UWP) | One. Way. To. Source | One. Time Fallback. Value – wartość domyślna Update. Source. Trigger = Lost. Focus | Property. Changed | Explicit (tylko w powiadamianiu z widoku do źródła wiązania)

Wiązania Text="{Binding Source={Static. Resource źródło}, Path=Własność, Mode=One. Way, Converter={Static. Resource konwerter} String. Format=Cena (zł):

Wiązania Text="{Binding Source={Static. Resource źródło}, Path=Własność, Mode=One. Way, Converter={Static. Resource konwerter} String. Format=Cena (zł): {0: C}}" Liczba {0} to numeru wiązanej własności, ważne przy multibindingu – kolejne własności 1, 2, … String. Format – formatowanie łańcuchów (por. string. Format) np. String. Format="{}{0} + {1}" Przykłady: String. Format=Liczba: {0} metrów String. Format=Liczba: {0: F 2} //1234. 56 String. Format=Liczba: {0: F 0} //1235 String. Format=Liczba: {0: N 2} //1, 234. 56 String. Format=Liczba: {0: #, #. 0} z przecinkiem String. Format=Cena: {0: C} zł String. Format=Data: {0: dddd, MMMM dd}, Converter. Culture=pl-PL String. Format=Czas: {0: HH: mm} String. Format={}{0: #, #. 0} <-- gdy nie ma dodatkowe tekstu z przodu!! IData. Error. Info (od. NET 3. 5), INotify. Data. Error (od. NET 4. 5) umożliwiają monitorowanie danych w ramach wiązań <Text. Block Text="{Binding Source={x: Static system: Date. Time. Now}, Converter. Culture='pl-PL', String. Format=Polska data: {0: D}}" />

Przykład aplikacji MVVM Model widoku – standard (powtórzenie) public class Model. Widoku : INotify.

Przykład aplikacji MVVM Model widoku – standard (powtórzenie) public class Model. Widoku : INotify. Property. Changed { private Sumowanie. Kwot model = new Sumowanie. Kwot(1000); public string Suma { get { return model. Suma. To. String(); } }. . .

Przykład aplikacji MVVM Model widoku – alternatywa 1 (gorsza, ale kolekcje…) public class Model.

Przykład aplikacji MVVM Model widoku – alternatywa 1 (gorsza, ale kolekcje…) public class Model. Widoku : INotify. Property. Changed //niezmieniony interfejs klasy { public Model. Widoku() { //model nie jest trwale przechowywany Sumowanie. Kwot model = Sumowanie. Kwot. Czytaj(); Suma = model. Suma; //kopiowanie stanu z do modelu widoku } public string Suma { get; private set; }. . . public void Zapisz() { Sumowanie. Kwot model = new Sumowanie. Kwot(Suma); model. Zapisz(); } }

Przykład aplikacji MVVM Model widoku – alternatywa 2 (czyste zło) public class Model. Widoku

Przykład aplikacji MVVM Model widoku – alternatywa 2 (czyste zło) public class Model. Widoku : INotify. Property. Changed { private readonly Sumowanie. Kwot model = Sumowanie. Kwot. Czytaj(); public Sumowanie. Kwot Model { get { return model; } } Wiązanie do Model. Suma → model musiałby implementować interfejs INotify. Property. Changed . . . public void Zapisz() { model. Zapisz(); } }

Warstwy wzorca MVVM

Warstwy wzorca MVVM

Wzorce architektoniczne http: //geekswithblogs. net/dlussier/archive/2009/11/21/136454. aspx

Wzorce architektoniczne http: //geekswithblogs. net/dlussier/archive/2009/11/21/136454. aspx