mvvm Tutoriel
Démarrer avec mvvm
Recherche…
Remarques
Cette section fournit une vue d'ensemble de ce qu'est mvvm et pourquoi un développeur peut vouloir l'utiliser.
Il devrait également mentionner tous les sujets importants au sein de mvvm, et établir un lien avec les sujets connexes. La documentation de mvvm étant nouvelle, vous devrez peut-être créer des versions initiales de ces rubriques connexes.
C # MVVM Résumé et exemple complet
Résumé:
MVVM est un modèle architectural représenté par trois composants distincts, le modèle , la vue et ViewModel . Afin de comprendre ces trois couches, il est nécessaire de définir brièvement chacune d’elles, puis d’expliquer comment elles fonctionnent ensemble.
Le modèle est la couche qui pilote la logique métier. Il récupère et stocke les informations de toute source de données pour consommation par ViewModel .
ViewModel est la couche qui sert de pont entre la vue et le modèle . Il peut ou non transformer les données brutes du modèle en une forme présentable pour la vue . Un exemple de transformation serait: un indicateur booléen du modèle à la chaîne de «True» ou «False» pour la vue.
View est la couche qui représente l'interface du logiciel (c'est-à-dire l'interface graphique). Son rôle est d'afficher les informations du ViewModel à l'utilisateur et de communiquer les modifications des informations au ViewModel .
Ces trois composants fonctionnent ensemble en se référant comme suit:
- La vue fait référence au ViewModel .
- Le ViewModel fait référence au modèle .
Il est important de noter que View et ViewModel sont capables de communications bidirectionnelles connues sous le nom de liaisons de données .
Un ingrédient majeur de la communication bidirectionnelle (liaison de données) est l'interface INotifyPropertyChanged .
En utilisant ce mécanisme, View peut modifier les données dans ViewModel via une entrée utilisateur et ViewModel peut mettre à jour View avec des données qui peuvent avoir été mises à jour via des processus dans le modèle ou avec des données mises à jour à partir du référentiel.
L'architecture MVVM met fortement l'accent sur la séparation des préoccupations pour chacune de ces couches. La séparation des couches nous profite comme:
- Modularité: l'implémentation interne de chaque couche peut être modifiée ou échangée sans affecter les autres.
- Testabilité accrue: chaque couche peut être testée par unité avec de fausses données, ce qui n'est pas possible si le code de ViewModel est écrit dans la zone Code-Behind de la vue .
La construction:
Créer un nouveau projet d'application WPF
Créez trois nouveaux dossiers dans votre solution: Model , ViewModel et View , et supprimez le MainWindow.xaml
origine, juste pour obtenir un nouveau départ.
Créez trois nouveaux éléments, chacun correspondant à un calque distinct:
- Cliquez avec le bouton droit sur le dossier Model et ajoutez un élément Class appelé
HelloWorldModel.cs
. - Cliquez avec le bouton droit sur le dossier ViewModel et ajoutez un élément de classe appelé
HelloWorldViewModel.cs
. - Cliquez avec le bouton droit sur le dossier View et ajoutez un élément Window (WPF) appelé
HelloWorldView.xaml
.
Alter App.xaml
pour pointer vers la nouvelle vue
<Application x:Class="MyMVVMProject.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyMVVMProject"
StartupUri="/View/HelloWorldView.xaml">
<Application.Resources>
</Application.Resources>
</Application>
ViewModel:
Commencez par créer le ViewModel en premier. La classe doit implémenter l'interface INotifyPropertyChanged
, déclarer un événement PropertyChangedEventHandler
et créer une méthode pour déclencher l'événement (source: MSDN: comment implémenter la notification de changement de propriété ). Ensuite, déclarez un champ et une propriété correspondante, en veillant à appeler la méthode OnPropertyChanged()
dans l'accesseur d' set
la propriété. Le constructeur de l'exemple ci-dessous est utilisé pour démontrer que le modèle fournit les données au ViewModel .
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using MyMVVMProject.Model;
namespace MyMVVMProject.ViewModel
{
// Implements INotifyPropertyChanged interface to support bindings
public class HelloWorldViewModel : INotifyPropertyChanged
{
private string helloString;
public event PropertyChangedEventHandler PropertyChanged;
public string HelloString
{
get
{
return helloString;
}
set
{
helloString = value;
OnPropertyChanged();
}
}
/// <summary>
/// Raises OnPropertychangedEvent when property changes
/// </summary>
/// <param name="name">String representing the property name</param>
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public HelloWorldViewModel()
{
HelloWorldModel helloWorldModel = new HelloWorldModel();
helloString = helloWorldModel.ImportantInfo;
}
}
}
Modèle:
Ensuite, construisez le modèle . Comme indiqué précédemment, le modèle fournit des données pour ViewModel en les extrayant d'un référentiel (ainsi qu'en les renvoyant au référentiel pour les enregistrer). Ceci est démontré ci-dessous avec la méthode GetData()
, qui renverra un simple List<string>
. La logique métier est également appliquée dans cette couche et peut être vue dans la méthode ConcatenateData()
. Cette méthode construit la phrase «Hello, world!» De la List<string>
précédemment renvoyée de notre «référentiel».
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyMVVMProject.Model
{
public class HelloWorldModel
{
private List<string> repositoryData;
public string ImportantInfo
{
get
{
return ConcatenateData(repositoryData);
}
}
public HelloWorldModel()
{
repositoryData = GetData();
}
/// <summary>
/// Simulates data retrieval from a repository
/// </summary>
/// <returns>List of strings</returns>
private List<string> GetData()
{
repositoryData = new List<string>()
{
"Hello",
"world"
};
return repositoryData;
}
/// <summary>
/// Concatenate the information from the list into a fully formed sentence.
/// </summary>
/// <returns>A string</returns>
private string ConcatenateData(List<string> dataList)
{
string importantInfo = dataList.ElementAt(0) + ", " + dataList.ElementAt(1) + "!";
return importantInfo;
}
}
}
Vue:
Enfin, la vue peut être construite. Il n'y a rien à ajouter au code derrière cet exemple, bien que cela puisse varier en fonction des besoins de l'application. Cependant, il y a quelques lignes ajoutées au XAML. La Window
nécessite une référence à l'espace de noms ViewModel
. Ceci est mappé à l'espace de noms XAML xmlns:vm="clr-namespace:MyMVVMProject.ViewModel"
. Ensuite, la fenêtre a besoin d'un DataContext
. Ceci est défini sur <vm:HelloWorldViewModel/>
. L'étiquette (ou le contrôle de votre choix) peut maintenant être ajoutée à la fenêtre. Le point clé à ce stade consiste à vous assurer que vous définissez la liaison sur la propriété du ViewModel que vous souhaitez afficher en tant que contenu de l'étiquette. Dans ce cas, il s'agit de {Binding HelloString}
.
Il est important de lier la propriété, et non le champ, car dans ce dernier cas, la vue ne recevra pas la notification de modification de la valeur, car la méthode OnPropertyChanged()
augmentera uniquement le PropertyChangedEvent
sur la propriété, et non sur le champ.
<Window x:Class="MyMVVMProject.View.HelloWorldView"
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:MyMVVMProject.View"
xmlns:vm="clr-namespace:MyMVVMProject.ViewModel"
mc:Ignorable="d"
Title="HelloWorldView" Height="300" Width="300">
<Window.DataContext>
<vm:HelloWorldViewModel/>
</Window.DataContext>
<Grid>
<Label x:Name="label" FontSize="30" Content="{Binding HelloString}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Window>