« MVVM » : différence entre les versions
De Banane Atomic
Aller à la navigationAller à la recherche
Aucun résumé des modifications |
|||
Ligne 23 : | Ligne 23 : | ||
* la View utilise des commandes appeler des méthodes du ViewModel. | * la View utilise des commandes appeler des méthodes du ViewModel. | ||
[[File:mvvm.svg|600px]] | [[File:mvvm.svg|600px]] | ||
= Framework = | |||
* [[MVVM_Light_Toolkit|MVVM Light Toolkit]] | |||
* [https://msdn.microsoft.com/en-us/library/ff648465.aspx Prism] | |||
* [https://calcium.codeplex.com/ Calcium] | |||
* [http://caliburnmicro.com/ Caliburn] | |||
* [https://cinch.codeplex.com/ Cinch] | |||
* [http://catelproject.com Catel] | |||
= ViewModelBase = | = ViewModelBase = | ||
Ligne 84 : | Ligne 92 : | ||
} | } | ||
</kode> | </kode> | ||
= Refactoriser du code pour MVVM = | = Refactoriser du code pour MVVM = |
Version du 20 juillet 2020 à 15:44
Définition
Séparation de la Vue et du Modèle afin d'améliorer:
- la maintenabilité: tout est rangé au bon endroit, on sait où trouver ce que l'on cherche
- les tests: simuler l'utilisation de l'application en manipulant le Vue-Modèle (Unit Tests + Mock)
- l'extension du code: le code est cloisonné, on peut ajouter ou remplacer des éléments (Design Time Data pour le Designer, Plugins)
Adaptation du modèle MVC à WPF.
Model | les données clientes.
|
View | les éléments visuels.
|
ViewModel | le code logique de la vue (vérification de la saisie)
|
- échanges bi-directionnels entre View et ViewModel grâce au DataBinding.
- View n'a pas accès à Model.
- la View utilise des commandes appeler des méthodes du ViewModel.
Framework
ViewModelBase
/// <summary> /// A method to wrap the INotifyPropertyChanged interface. /// </summary> public interface IViewModel : INotifyPropertyChanged { /// <summary> /// A method to wrap the call of the INotifyPropertyChanged.PropertyChanged event. /// </summary> /// <param name="propertyName">The name of the property which changed.</param> void OnPropertyChanged(string propertyName); } /// <summary> /// An implementation of a basis ViewModel with a useful method OnPropertyChanged /// to warn that a property has changed. /// </summary> public class ViewModelBase : IViewModel { /// <summary> /// A method to wrap the call of the PropertyChanged event. /// </summary> /// <param name="propertyName">The name of the property which changed.</param> public void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } /// <summary> /// Se produit lorsqu'une valeur de propriété est modifiée. /// </summary> public event PropertyChangedEventHandler PropertyChanged; } |
RelayCommand
ViewModel first
En fonction du type de vue-modèle, le DataTemplate permet de choisir la vue.
<Window.Resources> <DataTemplate DataType="{x:Type ViewModel1}"> <View1 /> </DataTemplate> <DataTemplate DataType="{x:Type ViewModel2}"> <View2 /> </DataTemplate> </Window.Resources> <!-- en fonction du type passé à CurrentViewModel (ViewModel1 ou ViewModel2) un DataTemplate (une vue) sera appliqué aux données de CurrentViewModel (respectivement View1 ou View2) --> <ContentControl Content="{Binding CurrentViewModel}"></ContentControl> |
public class MainWindowViewModel { public object CurrentViewModel { get; set; } } |
Refactoriser du code pour MVVM
- Rendre le Model Observable (INotifyPropertyChanged)
- Créer un ViewModel
- EventHandler → Command ou Behavior
- Injecter le DataService
- Injecter les ViewServices (DisplayMessage, Navigation)
- Binder View et ViewModel
- Ajouter des Design Time Data
- DesignDataService : IDataService
- Créer des Unit Tests: simuler (Mock) les services
- TestDataService : IDataService
- ViewService : IViewService