- NuGet
- Xamarin
- Xamarin.Forms
- dotnet
J’ai créé cet outil pour éviter d’écrire du code redondant pour mes ViewModels. Cet outil est construit à partir du compiler Rosyln pour .NET.
Lorsque vous développez votre projet, vous définissez toujours un grand nombre de properties
et de commands
dans vos ViewModels. Cela donne des dizaines et des dizaines de lignes qui ne permettent pas une lecture rapide de votre fichier.
L’idée de ce NuGet est simple: vous définissez simplement vos commands
et properties
avec une seule ligne dans un fichier XML spécifique, vous rebuildez votre projet et vous êtes prêt à démarrer !
Ce NuGet a différents avantages:
MvvmCodeGenerator prend désormais en charge les Frameworks MVVM:
Tout d’abord, installez le NuGet sur votre projet .NetStandard par exemple.
Créez ensuite un nouveau fichier appelé MvvmCodeGenMapper.xml
à la racine de votre projet. Ce fichier contiendra la définition de vos ViewModels.
Nous devons maintenant choisir le Framework MVVM dont nous avons besoin pour générer nos ViewModels. Comme je l’ai dit précédemment, MvvmCodeGenerator supporte ces options:
Lorsque votre choix est terminé, signalons-le au générateur à l’intérieur du fichier MvvmCodeGenMapper.xml
comme ceci:
<?xml version="1.0" encoding="UTF-8" ?>
<Resources>
<Generator Value="mvvmlightlibs" />
</Resources>
Pour ce tutoriel, j’ai choisi MvvmLightLibs. N’oubliez pas d’installer le NuGet du Framework MVVM que vous avez choisi dans votre projet.
Il est temps de définir vos ViewModels. Pour ce tutoriel, imaginons que nous avons deux cas:
ListView
.Donc, pour créer cet arbre à l’intérieur des balises Resources
, faisons ceci:
<?xml version="1.0" encoding="UTF-8" ?>
<Resources>
<Generator Value="mvvmlightlibs" />
<ViewModels Namespace="Xamarin.Sample" DestinationFolder="ViewModel">
</ViewModels>
<ViewModels Namespace="Xamarin.Sample.Items" DestinationFolder="ViewModel/Items">
</ViewModels>
</Resources>
Comme vous pouvez le voir ci-dessus, vous définissez namespace
associé à vos ViewModels et le dossier de destination. Vous devez savoir que MvvmCodeGenerator créera tous les dossiers de destination s’ils n’existent pas.
Chaque balise ViewModel
a 2 propriétés:
Dans beaucoup de projets, nous avons un ViewModel racine qui est une classe qui regroupe toutes les propriétés répétitives dont nous avons besoin dans chaque ViewModel. Une propriété de base est le IsLoading
. Donc, pour éviter de déclarer cette propriété pour chaque ViewModel, vous pouvez simplement la déclarer une fois dans un RootViewModel
et tous les autres ViewModels en hériteront.
Voyons comment dans notre fichier XML:
<?xml version="1.0" encoding="UTF-8" ?>
<Resources>
<Generator Value="mvvmlightlibs" />
<ViewModels Namespace="Xamarin.Sample" DestinationFolder="ViewModel">
<ViewModel Key="Root">
</ViewModel>
<ViewModel Key="Home" Base="Root">
</ViewModel>
</ViewModels>
<ViewModels Namespace="Xamarin.Sample.Items" DestinationFolder="ViewModel/Items">
<ItemViewModel Key="Switch">
</ItemViewModel>
</ViewModels>
</Resources>
Notre HomeViewModel
hérite maintenant du RootViewModel
.
Vous pouvez spécifier les Properties pour chaque ViewModels:
Pour les Properties, vous avez la possibilité de le définir en utilisant la balise Property
qui a ces valeurs:
property
property
property
Vous avez différentes options pour spécifier le Type de votre property
Ici vous avez la liste des types de base que vous pouvez utiliser:
Si nous revenons à notre exemple pour définir une propriété IsLoading
dans notre RootViewModel
, il nous suffit d’écrire:
<Property Name="IsLoading" Type="bool" Description="Gets or sets the is loading property" />
Si le type dont vous avez besoin ne figure pas dans la liste des types que j’ai décris précédemment, ne vous inquiétez pas, vous pouvez simplement le spécifier en utilisant l’espace de noms complet, par exemple:
<Property Name="House" Type="Xamarin.Sample.Models.House" Description="Gets or sets the house." />
Ici, je définis une property en utilisant un modèle House
que j’ai crée dans mon projet.
Vous pouvez également déclarer une liste d’éléments en utilisant le mot clé list
avant votre type, comme ceci:
<Property Name="names" Type="list string" Description="Gets or sets all names." />
<Property Name="AllHouses" Type="list Xamarin.Sample.Models.House" Description="Gets or sets all houses." />
Cela générera une IList
du type de vos besoins.
Pour résumer ici, voici un exemple plus complet:
<?xml version="1.0" encoding="UTF-8" ?>
<Resources>
<Generator Value="mvvmlightlibs" />
<ViewModels Namespace="Xamarin.Sample" DestinationFolder="ViewModel">
<ViewModel Key="Root">
<Property Name="IsLoading" Type="bool" Description="Gets or sets the is loading property" />
</ViewModel>
<ViewModel Key="Home" Base="Root">
<Property Name="Title" Type="string" Description="Gets or sets the title." />
<Property Name="Number" Type="int" Description="Gets or sets the total number." />
<Property Name="Degrees" Type="float" Description="Gets or sets the degrees." />
<Property Name="MyTimeOffset" Type="DateTimeOffset" Description="Gets or sets the date and hour offset." />
<Property Name="MyTimeSpan" Type="TimeSpan" Description="Gets or sets the time span." />
<Property Name="Messages" Type="list string" Description="Gets or sets all messages." />
<Property Name="MyHouse" Type="Xamarin.Sample.Models.House" Description="Gets or sets my houses." />
<Property Name="AllHouses" Type="list Xamarin.Sample.Models.House" Description="Gets or sets all houses." />
</ViewModel>
</ViewModels>
<ViewModels Namespace="Xamarin.Sample.Items" DestinationFolder="ViewModel/Items">
<ItemViewModel Key="Switch">
<Property Name="UnKnown" Type="object" Description="Gets or sets the unknown object." />
<Property Name="MyDate" Type="DateTime" Description="Gets or sets the date and hour." />
</ItemViewModel>
</ViewModels>
</Resources>
Dans vos ViewModels, vous devez toujours spécifier certaines commandes. Faisons-le avec MvvmCodeGenerator!
En utilisant MvvmCodeGenerator, vous avez la possibilité de définir:
Command
AsyncCommand
Chaque balise Command
a des propriétés différentes:
command
command
command
doit avoir une méthode can execute ou noncommand
Voici un exemple cd Command:
<Command Name="Buy" Parameter="bool" CanExecute="true" Description="Gets or sets the command to buy a boat" />
Et voici un exemple d’AsyncCommand:
<AsyncCommand Name="Consultation" Parameter="int" CanExecute="true" Description="Gets or sets the command for the consultation" />
Facile à définir, n’est-ce pas?
Les commandes asynchrone de MvvmLightLibs et FreshMvvm n’ayant pas de propriété IsRunning, MvvmCodeGenerator les génèrent automatiquement pour vous. MvvmCross et Mvvmicro disposent déjà de ce type de mécanisme.
Maintenant, si nous revenons à un exemple complet, nous pouvons avoir quelque chose comme ceci:
<?xml version="1.0" encoding="UTF-8" ?>
<Resources>
<Generator Value="mvvmlightlibs" />
<ViewModels Namespace="Xamarin.Sample" DestinationFolder="ViewModel">
<ViewModel Key="Root">
<Property Name="IsLoading" Type="bool" Description="Gets or sets the is loading property" />
<AsyncCommand Name="InitData" Description="Gets or sets the command to init the data" />
</ViewModel>
<ViewModel Key="Home" Base="Root">
<Property Name="Title" Type="string" Description="Gets or sets the title." />
<Property Name="Number" Type="int" Description="Gets or sets the total number." />
<Property Name="Degrees" Type="float" Description="Gets or sets the degrees." />
<Property Name="MyTimeOffset" Type="DateTimeOffset" Description="Gets or sets the date and hour offset." />
<Property Name="MyTimeSpan" Type="TimeSpan" Description="Gets or sets the time span." />
<Property Name="Messages" Type="list string" Description="Gets or sets all messages." />
<Property Name="MyHouse" Type="Xamarin.Sample.Models.House" Description="Gets or sets my houses." />
<Property Name="AllHouses" Type="list Xamarin.Sample.Models.House" Description="Gets or sets all houses." />
<Command Name="JobActivation" Description="Gets or sets the command to manager job actions such as day (de)activation and breaks" />
<Command Name="ConsultControlFiles" Parameter="int" Description="Gets or sets the command to consult control files" />
<Command Name="Files" Parameter="bool" CanExecute="true" Description="Gets or sets the files"/>
<AsyncCommand Name="ConsultFiles" Description="Gets or sets the command to consult control files" />
<AsyncCommand Name="Consult" Parameter="string" Description="Gets or sets the command to consult control files" />
<AsyncCommand Name="Consultation" Parameter="string" CanExecute="true" Description="Gets or sets the command for the consultation" />
</ViewModel>
</ViewModels>
<ViewModels Namespace="Xamarin.Sample.Items" DestinationFolder="ViewModel/Items">
<ItemViewModel Key="Switch">
<Property Name="UnKnown" Type="object" Description="Gets or sets the unknown object." />
<Property Name="MyDate" Type="DateTime" Description="Gets or sets the date and hour." />
<AsyncCommand Name="Toggle" Description="Gets or sets the toggle command" />
</ItemViewModel>
</ViewModels>
</Resources>
Ce XML générera 3 fichiers pour chaque ViewModel
que vous définissez, voici le résultat pour le SwitchItemViewModel
:
Le SwitchItemViewModel.cs
:
namespace Xamarin.Sample.Items
{
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using GalaSoft.MvvmLight.Command;
public partial class SwitchItemViewModel
{
}
}
Le SwitchItemViewModel.interface.g.cs
:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by MvvmCodeGenerator.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Xamarin.Sample.Items
{
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using GalaSoft.MvvmLight.Command;
public interface ISwitchItemViewModel : System.ComponentModel.INotifyPropertyChanged
{
System.Object UnKnown
{
get;
}
System.DateTime MyDate
{
get;
}
System.Boolean IsToggleCommandRunning
{
get;
}
System.Windows.Input.ICommand ToggleCommand
{
get;
}
}
}
Le SwitchItemViewModel.part.g.cs
:
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by MvvmCodeGenerator.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Xamarin.Sample.Items
{
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using GalaSoft.MvvmLight.Command;
public partial class SwitchItemViewModel : GalaSoft.MvvmLight.ViewModelBase, Xamarin.Sample.Items.ISwitchItemViewModel
{
private System.Object unKnown;
private System.DateTime myDate;
private System.Boolean isToggleCommandRunning;
private GalaSoft.MvvmLight.Command.RelayCommand toggleCommand;
/// <summary>
// Gets or sets the unknown object.
/// </summary>
public System.Object UnKnown
{
get => this.unKnown;
set => this.Set(ref this.unKnown, value);
}
/// <summary>
// Gets or sets the date and hour.
/// </summary>
public System.DateTime MyDate
{
get => this.myDate;
set => this.Set(ref this.myDate, value);
}
/// <summary>
// Gets or sets the value to know if the associated async command is running.
/// </summary>
public System.Boolean IsToggleCommandRunning
{
get => this.isToggleCommandRunning;
set => this.Set(ref this.isToggleCommandRunning, value);
}
/// <summary>
// Gets or sets the toggle command
/// </summary>
public System.Windows.Input.ICommand ToggleCommand
{
get => this.toggleCommand ?? (this.toggleCommand = new GalaSoft.MvvmLight.Command.RelayCommand(async () =>
{
try
{
this.IsToggleCommandRunning = true;
await ExecuteToggleCommandAsync();
}
catch (System.Exception ex)
{
OnExecuteToggleCommandAsyncError(ex);
}
finally
{
this.IsToggleCommandRunning = false;
}
}
)); // You must implement the following method(s): ExecuteToggleCommandAsync and OnExecuteToggleCommandAsyncError
}
}
}
Il ne vous reste plus qu’à implémenter vos commandes dans le fichier SwitchItemViewModel.cs
et le tour est joué !
Lorsque vous reconstruisez votre projet, vous devriez voir les ViewModels, les dossiers et un fichier MvvmCodeGenMapper.g.targets
générés. Ce dernier permet à Visual Studio de regrouper vos fichiers correctement.
Si tout fonctionne correctement, vous devriez voir quelque chose comme ceci:
Si vos fichiers ne sont pas correctement groupés comme ci-dessus, veuillez vérifier si le fichier MvvmCodeGenMapper.g.targets
a été importé correctement dans votre .csproj associé à votre projet. Si ce n’est pas le cas, vous pouvez le faire manuellement en ajoutant cette ligne:
<Import Project="MvvmCodeGenMapper.g.targets" />
Rechargez votre projet et vous serez prêt à partir.
Vous trouverez un sample dans le répertoire Github MvvmCodeGenerator pour le tester vous-même.
Happy coding !
Vous avez aimé ce tutoriel ? Laissez une étoile sur le répertoire Github associé !