WPF - Développement d'une application moderne

Windows Presentation Foundation comment développer une application moderne ? Existe t-il encore ces vieilles histoires de Prims, MEF et Unity que sais-je encore modèle MVVM, inversion des containers avec IoC. Que dois-je faire pour démarrer correctement un nouveau développement avec WPF ?

Nous avons vu précédemment que WPF est maintenu sur le framework .NET x.x :

C# .NET: WPF avec .NET Core et .NET Framework

Mais pour obtenir un "canvas" d'application moderne avec WPF, il me manque encore quelques éléments d'architecture.

Éléments de l'architecture WPF

Je tout début de l'architecture WPF (Windows Presentation Foundation) avec Learn Microsoft :

Learn Microsoft - Architecture WPF

System.Object

Objets graphiques, milcore partie dealant avec DirectX au dessus on trouve PresentationCore et PresentationFramework

System.Threading.DispatcherObject

Les objets WPF dérivent de DispatcherObject pour gérer la concurrence et le threading

Deux concepts le Dispatcher et le Thread affinity 

En dérivant de DispatcherObject vous créez un objet STA (Single Thread Affinity)

System.Windows.DependencyObject

Préférer les propriétés plutôt que les méthodes (impératif) ou les event car la propriétés déclaratives permettent de plus facilement spécifier l'intention (nullable).

Permet l'émergence d'un système piloté par les données (Model) pour afficher le contenu dans l'UI d'où INotifyPropertyChange. Ainsi le système est notifié si une propriété est modifiée.

D'où la création du DependencyObject. Cf expando de JavaScript

Et oui, le modèle MVC (Model View Controler) vient de JavaScript.

System.Windows.Media.Visual

Pour dessiner les pixels à l'écran la class Visual est l'arborescence des objets visuels. Conçue pour prévenir l'apparition d'une application qui ne répond pas. WPF utilise un "algorithme de peintre" chaque composant est en charge de son rendu.

System.Windows.UIElement

Layout est un concept clé dans WPF. Deux phases Measure et Arrange.

UIElement introduit la notion de CommandBinding implémente ICommand, pour créer une Grid à la base de toutes les pages d'une application WPF.

System.Windows.FrameworkElement

S’appuie sur le contrat de disposition de base introduit par UIElement et ajoute la notion d’un « emplacement »

disposition pilotées par la propriété telles que HorizontalAlignment, VerticalAlignment et MinWidthMargin.

permet de donner un comportement cohérent à l'intérieur des "layout containers"

expose BeginStoryboard et Storyboard pour les animations 

System.Windows.Controls.Control

Introduit le ControlTemplate, script permettant de créer des éléments enfants avec des liaisons aux propriétés Foreground, Background, Padding

Architecture moderne WPF

Donc on voit que par exemple ICommand que l'on connait bien dans le modèle MVVM de Prism semble maintenant intégré dans le .NET Core : System.Windows.Input.ICommand.

En parcourant les Extensions pour Visual Studio Community 2019, je trouve WAF Project Template que j'installe pour créer un Template d'application. A ma surprise je ne peux utiliser que le .NET Framework 4.7 ...

WPF application moderne - WAF Template
WPF application moderne - WAF Template

Il s'agit du bon vieux modèle MVVM (Model, View, ViewModel). Si vous avez un problème pour exécuter le Template ainsi créé, il faut penser à mettre à jour l'extension :

WAF Template - Mise à jour de l'extension
WAF Template - Mise à jour de l'extension

Et donc pour l'instant, je jette un œil Ici.

C'est immense, avec plus de 200 projets (208 dans le WPF Samples que j'ai téléchargé). 

First WPF Sample

Ce que je recherche, c'est comment architecturer une application moderne en WPF comment enchaîner des pages, des fonctionnalités.

Microsoft - WPF Samples - First WPF app sample

Est un des premiers exemple préconisé. Au delà des explications du README.md, il y a 3 Page dans le même namespace ExpenseIt :

MainWindow.xaml

Est une Navigation NavigationWindow :    

    <NavigationWindow x:Class="ExpenseIt.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500" Source="ExpenseItHome.xaml">
    </NavigationWindow>

Dont l'élément Source est initialisé avec la première page à charger.

ExpenseItHome.xaml

Avec un bouton View :

        <!-- View report button -->
        <Button Grid.Column="1" Grid.Row="3" Click="Button_Click" Style="{StaticResource ButtonStyle}">View</Button>

Une fonction Button_Click dans code-behind :

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // View Expense Report
            ExpenseReportPage expenseReportPage = new ExpenseReportPage(this.peopleListBox.SelectedItem);
            this.NavigationService.Navigate(expenseReportPage);
        }

Qui utilise NavigationService pour afficher la page :

ExpenseReportPage.xaml

Dans le constructeur on initialise le DataContext avec l'item choisi par l'utilisateur :

        // Custom constructor to pass expense report data
        public ExpenseReportPage(object data):this()
        {
            // Bind to expense report data.
            this.DataContext = data;
        }

Rien de plus, nous avons fait le tour de l'architecture de navigation entre les pages de l'application ExpenseItIntro.

Cet exemple montre également l'utilisation d'un fichier de Styles.xaml à l'aide d'un ResourceDictionary.MergedDictionaries. 

First WPF Sample Data

Les Data sont dans un XmlDataProvider déclarées dans ExpenseItHome.xaml au sein de Grid.Resources.

    <Grid Margin="10,0,10,10">
        <Grid.Resources>
            <!-- Expense Report Data -->
            <XmlDataProvider x:Key="ExpenseDataSource" XPath="Expenses">
                <x:XData>
                   <Expenses xmlns="">

J'ajoute les données d'une Person supplémentaire :

Architecture d'une application WPF avec NavigationService.Navigate
Architecture d'une application WPF avec NavigationService.Navigate

Mais ce que l'on cherche c'est la structuration d'une application facile à faire évoluer donc par exemple avec un menu  qui appelle des pages.

ControlsAndLayout Sample

ControlsAndLaytout est un exemple d'application WPF intéressant parce qu'il montre l'utilisation d'un menu et de page, en fait non, ce ne sont pas des pages mais cet exemple pourrait être utiliser pour un WPF Starter Kit dans le genre de : mabyre/WpfAppCore1

ICommand WPF Samples

J'ai une idée rechercher ICommand dans WPF Samples pour découvrir des samples au plus proche de ce que je souhaite faire.

\Visual Studio 2019\Samples\WPF-Samples\Documents\Fixed Documents\DocumentMerge\MainWindow.cs
\Visual Studio 2019\Samples\WPF-Samples\Sample Applications\CustomComboBox\DropList.cs
\Visual Studio 2019\Samples\WPF-Samples\Tools\BamlReflector\BamlTools\KnownElements.cs

Tient des tools, vous connaissiez le :

WPF - Samples BamlReflector - A test tool for BAML Decompilation

BamlReflector est en soit une application intéressante :

WPF - Samples BamlRefector Application Structure
WPF - Samples BamlRefector Application Structure

Avec un Menu un Treeview un TabControl INotifyPropertyChanged, ObservableCollection donc une structure d'application WPF intéressante.

Il existe aussi :

WPF Samples - LocBaml

intéressant, je prends note du coup je cherche dans les deux autres exemples mais rien de probant.

WPF Samples - MultiPage

Parmi les Samples GettingStarted MultiPage nous montre comment passer d'une page à une autre cette fois on va plus loin avec le positionnement d'une bouton dans la page avec :

<Hyperlink  NavigateUri="Page1.xaml">Go To The Start Page</Hyperlink>

Simple pour naviguer entre les pages .xaml mais on ne se passe pas de Data entre les Pages.

WPF Samples - Conclusions

Après ce parcours rapide des différents exemples de structure d'application WPF nous avons maintenant deux systèmes à notre disposition, l'un qui utilise NavagationService pour passer des Data entre des page, un autre pour simplement naviguer entre pages avec NavigateUri.

Spécifications de mon WPF StarterKit

Je peux maintenant imaginer le développement de mon StarterKit pour développer rapidement en WPF. Je vois à peu près comment tout câbler ;)

Il me faut un Menu pour Quitter proprement et déclencher d'autres commandes.

Un TreeView pour ajouter rapidement une page de démonstration et l'activer.

WPF Template Studio for Visual Studio 2022

Je continue mes recherches sur les Templates d'application modernes pour WPF et je trouve :

GitHub - Microsoft - Template Studio

Cela semble prometteur, en face d'Application Design Pattern je trouve : 

WPF: MVVM Toolkit, Code Behind, and Prism.

Template Studio est une suite d'extensions Visual Studio 2022 qui accélèrent la création de nouvelles applications WinUI 3, WPF et UWP à l'aide d'une expérience basée sur un wizard.

Template Studio for WPF

Des structures d'application que nous connaissons bien mais il faudra installer Visual Studio 2022.

Aucun commentaire:

Enregistrer un commentaire

Pour plus d'interactivité, n'hésitez pas à laisser votre commentaire.