Podyplomowe Studium Programowani i Zastosowa Komputerw Wydzia Fizyki

  • Slides: 29
Download presentation
Podyplomowe Studium Programowani i Zastosowań Komputerów Wydział Fizyki, Astronomii i Informatyki Stosowanej Uniwersytet Mikołaja

Podyplomowe Studium Programowani i Zastosowań Komputerów Wydział Fizyki, Astronomii i Informatyki Stosowanej Uniwersytet Mikołaja Kopernika w Toruniu MVVM … ale najpierw MVC i MVP Jacek Matulewski 7 maja 2020 http: //fizyka. umk. pl/~jacek/dydaktyka/spdypl_net/

Architektura MVC • Model-View-Controler • Oryginalnie dla aplikacji konsolowych • Ostatnio też do aplikacji

Architektura MVC • Model-View-Controler • Oryginalnie dla aplikacji konsolowych • Ostatnio też do aplikacji internetowych (ASP. NET MVC, ASP. NET Core) Użytkownik • Model – dane i logika programu używa jest oglądany • Widok – moduł obsługujący wyświetlanie w konsoli Kontroler Widok • Kontroler – przyjmuje modyfikuje aktualizuje wejście z klawiatury, Model modyfikuje model

Architektura MVC Kontrola oraz przepływ informacji między modułami aplikacji w architekturze MVC Użytkownik używa

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

Architektura MVC • Jest wiele wersji samego MVC • Często używana wersja z pasywnymi

Architektura MVC • Jest wiele wersji samego MVC • Często używana wersja z pasywnymi modelem i widokiem (passive) oraz nadzorującym kontrolerem (supervising) Użytkownik używa Kontroler jest oglądany aktualizuje modyfikuje Model Widok

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

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}}" />

Warstwy wzorca MVVM

Warstwy wzorca MVVM