Créer des vues

Nouveau module

Afin de créer une nouvelle vue, il faut d’abord créer un nouveau module POS. Dans Visual Studio nous sélectionnons un nouveau projet WPF Custom Control Library. Ce type de projet génère automatiquement une structure indispensable et permet d’ajouter rapidement de nouveaux éléments. Au début, notre projet vide est composé du dossier Themes avec le fichier Generic.xaml et du fichier CustomControl1.cs que nous pouvons supprimer.

Dans un temps suivant, il faut créer la classe Module.cs qui sera responsable pour l’enregistrement de notre module dans l’application POS. Cette classe doit hériter de la classe de base ModuleBase (Comarch.POS.Presentation.Core) et implémenter correctement la méthode Initialize. À l’intérieur de cette méthode nous allons enregistrer nos services, vues et viewmodels personnalisés, enregistrer les boutons dans le menu principal POS, enregistrer nos propres contrôles, gérer la visibilité des propriétés des contrôles dans la gestion de l’interface, élargir les conteneurs et datagrids existants dans le système.

Pour que notre vue peut être ultérieurement gérée par l’utilisateur en cours du fonctionnement de l’application POS, il faut ajouter au dossier Themes un nouvel élément du type Resource Dictionary (il faut cliquer avec le bouton droit de la souris et ensuite dans le menu contextuel sélectionner dans l’ordre suivant : Add, Resource Dictionary…). Nous l’appellons ModernUI.xaml et l’enregistrons. Dans ce fichier seront définies les propriétés par défaut des éléments de l’interface gérables (vues, contrôles) – voir Gérer la vue et ses éléments. À la fin, il faut encore enregistrer une ressource. Ceci est fait dans le constructeur de classe Module en écrivant la ligne suivante :

LayoutService.RegisterResources(typeof(Module));

(LayoutService est une classe statique présente dans l’espace Comarch.POS.Presentation.Core.Services).

Créer une nouvelle vue

La création d’une nouvelle vue doit être commencée avec la création du dossier Views où seront gardées toutes les vues de projet et le dossier ViewModels pour les viewmodels. Ensuite, nous ajoutons dans le dossier Views un nouvel élément du type User Control (WPF), appelé par exemple OrdersView.xaml.

Ensuite, il faut changer dans l’espace Comarch.POS.Presentation.Core le type UserControl en View.

<core:View x:Class="Comarch.POS.Presentation.Sales.Views.OrdersView"
           xmlns:core="clr-
namespace:Comarch.POS.Presentation.Core;assembly=Comarch.POS.Presentation.Core"

Dans le code-behind nous supprimons l’hérédité d’UserControl et implémentons l’interface View requise.

La propriété Header est un string affiché dans la section de l’en-tête de l’application – elle est requise uniquement pour les vues qui seront ouvertes en tant que vues de base, car seules ces vues ont la présentation de l’en-tête. Dans tous les autres cas (c’est-à-dire la vue modale et la vue de message), il suffit de la paramétrer comme String.Empty. Il est également possible de créer son propre en-tête de section avec un contenu libre – voir Ajouter un en-tête personnalisé.

La propriété HeaderLayoutID doit en revanche contenir un nom unique de l’identifiant layout id ce qui est requis pour le fonctionnement correct de la gestion des vues par l’utilisateur POS. Si l’on souhaite que la vue ne puisse pas être modifiée, il suffit de paramétrer cette propriété comme String.Empty. Aux fins de cette documentation, nous paramétrons ici la valeur « OrdersViewId ».

Le constructeur de base requiert le transfert d’un objet du type IViewModel, donc nous allons maintenant créer un viewmodel. Dans le dossier ViewModels il faut d’abord créer un dossier appelé Orders. Ensuite, nous y ajoutons la nouvelle classe OrdersViewModel et l’interface IOrdersViewModel. L’interface doit être publique et hériter d’IViewModel. La classe OrdersViewModel doit être également publique et elle doit implémenter la classe de base ViewModelBase, ainsi que l’interface IOrdersViewModel.

En héritant de ViewModelBase il faut implémenter la méthode IsTarget. Elle est appelée lors de la navigation et permet à l’instance de viewmodel de vérifier si elle doit être activée ou non (voir Naviguer entre les vues) – à présent, nous la définissons pour qu’elle retourne la valeur true.

En outre, si l’on souhaite que la vue puisse être gérée par l’utilisateur POS, il faut ajouter une classe supplémentaire, un viewmodel appelé DesignOrdersViewModel qui héritera de DesignViewModelBase et implémentera l’interface IOrdersViewModel. La structure entière est présentée sur le dession à côté.

Maintenant, nous revenons au code-behind de la classe OrdersView (fichier OrdersView.xaml.cs) et nous paramétrons le constructeur pour qu’il adopte le paramètre du type IOrdersViewModel, appelé viewModel (attention : ce nom est important et ce paramètre doit être toujours appelé comme ça !). Ensuite, nous complétons le constructeur de base en lui transmettant notre variable viewModel.

La dernière étape consiste à enregistrer notre nouvelle vue et elle a été décrite dans le chapitre Enregistrer des vues à naviguer et à gérer l’affichage.

Le modèle fini de création de module avec une vue vide est disponible dans l’exemple Module simple avec une nouvelle vue vide.

Ajouter un en-tête personnalisé

Il est possible de définir pour chaque vue de base le texte dans l’en-tête qui sera affiché dans la partie supérieure de l’application POS. Par défaut, seul une chaîne de caractères définie dans la propriété Header de la vue peut y être emplacée. S’il est nécessaire d’avoir une structure plus complexe dans l’en-tête, une vue d’en-tête personnalisée (custom header) peut être créée.

Nous commençons à définir un en-tête personnalisé par ajouter un nouvel élément User Control (WPF) au dossier avec la vue. Pour améliorer la lisibilité, l’élément sera appelé comme notre vue, mais avec le préfixe Header (par exemple pour la vue OrdersView, le nom sera OrdersViewHeader).

À la fin, il faut revenir au code-behind de notre vue OrdersView et paramétrer dans le constructeur la propriété CustomHeaderType pour le type de notre en-tête personnalisé. Un DataContext indiquant le ViewModel de la vue sera automatiquement attribué à la vue d’en-tête. Dans ce cas, ça sera OrdersViewModel. Ainsi, il sera possible d’utiliser dans notre en-tête un binding direct à la propriété dans le viewmodel de la vue.

public partial class OrdersView 
{
        public OrdersView(IOrdersViewModel viewModel) : base(viewModel)
        {
            CustomHeaderType = typeof (OrdersViewHeader);
            InitializeComponent();
        }
…
…

Enregistrer des vues à naviguer et à gérer l’affichage

Après avoir créé la vue (en implémentant la logique de fonctionnement dans viewmodel et l’UI dans xaml respectivement), l’étape nécessaire pour que notre vue fonctionne correctement et de l’enregistrer. Afin de le faire, il faut ouvrir la classe Module, créée lors de la création du projet (voir Nouveau module). Nous ajoutons des lignes suivantes dans la méthode Initialize :

Register<IOrderViewModel, OrderViewModel>();
RegisterViews(new ViewStructure<OrdersView, DesignOrdersViewModel>("OrdersView", 
Resources.ResourceManager);

La première enregistre notre viewmodel dans le conteneur, grâce à ce qu’une instance de l’interface IOrdersViewModel est automatiquement implémentée dans le constructeur de vue.

Grâce à la deuxième méthode, un utilisateur POS peut enregistrer la vue en mode de gestion de son interface lors du fonctionnement de l’application. Ensuite, lorsque l’utilisateur ouvre la vue de gestion d’interface, il verra notre vue dans la liste des vues. Il pourra l’ouvrir et modifier l’affichage de tous ces éléments qui ont été définis comme gérables (pour en savoir plus voir Gestion de vue et de ses éléments). Cette méthode exige que deux paramètres soient transmis. Le premier est le nom de clé dans les ressources et le deuxième est une instance du gestionnaire de ressources. Ces paramètres permettent de présenter le nom de vue dans l’arbre des vues dans la gestion des vues de l’application POS.

Alternativement, si l’on ne veut pas enregistrer la vue en mode de gestion d’interface, au lieu de RegisterViews il faut utiliser la méthode RegisterForNavigation<TView >().

RegisterForNavigation<OrdersView>();

Ajouter une vue au menu principal

Chaque vue que l’on souhaite ouvrir en mode base peut être ajoutée au menu principal sous forme d’une mosaïque (TileButton). En ajoutant une vue au menu principal, elle sera automatiquement ajoutée au menu latéral déroulant qui peut être ouvert à partir de n’importe quelle vue de base.

Afin d’ajouter une vue précédemment créée au menu sous forme de mosaïque, il faut l’enregistrer dans la méthode Initialize de la classe Module à l’aide de la méthode RegisterMenuTile<TView> où TView est le nom de la classe de vue. Les paramètres d’appel sont le nom de clé dans les ressources et le gestionnaire de ressources respectivement. Facultativement, il est possible de définir le délégué canExecute. S’il est false, la mosaïque sera en gris et ne pourra pas être cliquée. Il est également possible d’ajouter un délégué aux actions qui doivent être exécutées avant l’ouverture de vue/et définir les autorisations requises pour ouvrir la vue avec la clé dans les ressources où sera enregistré le message qui apparaîtra dans la fenêtre modale dans le cas où les autorisations ne seraient pas suffisantes (pour plus d’informations sur les autorisations voir Vérification des autorisations). Aux fins de notre exemple, nous allons enregistrer la vue OrdersView; créée précédemment.

RegisterMenuTile<OrdersView>("OrdersView", Resources.ResourceManager);

Après l’enregistrement de vue dans le menu principal, il sera possible de l’ouvrir en appuyant sur la mosaïque appropriée. Par défaut, la mosaïque aura l’aspect défini dans la configuration globale de l’interface POS. Afin de modifier ses propriétés visuelles, il faut ajouter des entrées appropriées dans le fichier ModernUI.xaml qui se trouve dans le dossier Themes. Par exemple, pour définir une nouvelle couleur par défaut pour notre mosaïque ouvrant la vue OrdersView, il faut ajouter la ligne suivante :

<SolidColorBrush x:Key="OrdersView.Default.Background" Color="Red" />

Le format de chaque clé dans ModernUI sera :

[LayoutId ou Nom du type de contrôle].Default.[Nom de propriété]

En revanche, la définition entière sera :

<[Nom du type de propriété] x:Key=”[clé selon le format en-dessus]” [attributs]>[valeur]</[Nom du type de propriété>

Les attributs et la valeur ne sont pas obligatoires et ils dépendent strictement du type de propriété à laquelle nous avons à faire.

LayoutId pour la mosaïque de la vue OrdersView est défini dans le premier paramètre de la méthode RegisterMenuTile. Dans notre cas, LayoutId utilisé dans la clé définissant la couleur de la mosaïque est OrdersVies, car cette valeur a été définie avant, lors de l’appel de la méthode d’enregistrement de la vue sous forme de mosaïque dans le menu principal. Les propriétés, prises en charge par la gestion d’interface, dépendent du type de contrôle. Dans le cas des mosaïques c’est le contrôle TileButton. Une liste avec informations quel contrôle prend en charge quelles propriétés se trouve ici : Liste des propriétés prises en charge

Brancher un module dans l’application POS

Après la compilation du modèle en cours de création, la dernière étape est son démarrage dans l’environnement cible, c’est-à-dire dans l’application POS. Ceci est fait en copiant le module créé sous forme de répertoire (ou répertoires) dans le dossier d’installation de l’application POS. Ensuite, il faut ouvrir le fichier POS.exe.config, y retrouver la section <modules> et ajouter le nouveau module à la fin de cette section selon le modèle suivant :

<module assemblyFile=”[nom_module].dll” moduleType=”[namespace_classe_module].Module, [namespace_classe_module]” moduleName=”[ nom_module]” />

S’il y a plus de répertoires, il faut enregistrer uniquement ceux dans lesquelles est implémentée la classe Module.

Czy ten artykuł był pomocny?