Au cours de la leçon précédente, nous avons ajouté un bouton dans le XAML et généré un événement associé. Notre première réalisation consistait à modifier le texte du bouton lors du clic.
Tout d’abord, revenez dans votre fichier XAML. Il faut attribuer un nom au bouton avec x:Name="btnAdd" afin de pouvoir le manipuler depuis le code C++ d’arrière-plan.
<Grid>
<Button x:Name="btnAdd" Content="Click Me" HorizontalAlignment="Center" VerticalAlignment="Center" Click="OnButtonClick"/>
</Grid>Langage du code : HTML, XML (xml)
Ensuite, allez dans la fonction d’implémentation OnButtonClick située dans MainWindow.xaml.cpp.

Vous pouvez récupérer directement l’objet bouton via la variable btnAdd déclarée ci-dessus.
Lors du clic, sa propriété Content prend la valeur « Welcome to FoxDevelop.com ».
Lançons maintenant le projet pour tester le fonctionnement.

void winrt::WinuiCppDemo::implementation::MainWindow::OnButtonClick(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
btnAdd().Content(box_value(L"Welcome to FoxDevelop.com"));
}
Langage du code : C++ (cpp)
Comme vous pouvez le constater, un clic permet de modifier les propriétés de l’interface. Nous allons ensuite créer une propriété de type entier pour compter les clics, l’incrémenter à chaque appui et la lier à un TextBlock du XAML afin que l’interface se mette à jour automatiquement.
Liaison de propriétés
Pour éviter les interférences avec les exemples précédents, vous pouvez créer un nouveau projet vide.
Suivez les étapes ci-dessous :
Modifiez le XAML et ajoutez un TextBlock.
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="WinuiDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinuiDemo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="WinuiDemo">
<Grid>
<TextBlock Text="{x:Bind MyProperty}" FontSize="24"/>
</Grid>
</Window>
Langage du code : C++ (cpp)
Dans le fichier .cpp, faites en sorte que MyProperty renvoie simplement un nombre.
namespace winrt::WinuiDemo::implementation
{
int32_t MainWindow::MyProperty()
{
return 100;
}
void MainWindow::MyProperty(int32_t /* value */)
{
throw hresult_not_implemented();
}
}
Langage du code : C++ (cpp)
Lancez ensuite la compilation et l’exécution.
Il est possible que votre environnement de développement affiche l’erreur suivante et que la compilation reste bloquée indéfiniment.
Build started at 14:42...
1>------ Build started: Project: WinuiCppDemo, Configuration: Debug x64 ------
1>WindowsAppSDKMLDeploymentMode=Framework
1>MainWindow.xaml.cpp
Le message d’erreur est le suivant :
#error directive: "C++/WinRT no longer supports pre-standardization coroutines.
If you use co_await, switch to /await:strict or upgrade to C++20. If you do not,
remove /await from the compiler flags."Langage du code : PHP (php)
Mise à niveau vers C++20
WinUI 3 et C++/WinRT reposent sur des coroutines conformes à la norme C++20, ce qui facilite grandement la maintenance à long terme.
Allez dans Propriétés du projet → C/C++ → Langage → Norme du langage C++ et sélectionnez C++20.

Relancez la compilation. Le processus sera très long et générera 1,3 Go de fichiers intermédiaires dans le dossier D:\Demos\WinuiDemo\WinuiDemo\x64\Debug, ce qui explique la lenteur. La durée dépend de la configuration de votre ordinateur. Une fois la compilation réussie, lancez l’application : le chiffre 100 s’affichera sur la fenêtre.
int32_t MainWindow::MyProperty()
{
return 100;
}Langage du code : C++ (cpp)
L’écran affiche directement la valeur renvoyée par cette propriété.

Implémenter un compteur incrémental au clic sur bouton
Ajoutons maintenant un bouton et associons-lui un gestionnaire d’événement clic.
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="WinuiDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinuiDemo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="WinuiDemo">
<StackPanel Orientation="Vertical">
<TextBlock Text="{x:Bind MyProperty}" FontSize="24"/>
<Button Content="Click Me" Click="Button_Click"/>
</StackPanel>
</Window>
Langage du code : HTML, XML (xml)
Passez le curseur sur Button_Click dans l’attribut Click= »Button_Click », puis appuyez sur la touche F12 : Visual Studio générera automatiquement la signature de la fonction événement dans les fichiers .h et .cpp.
void Button_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
La syntaxe est identique à l’exemple précédent. Il nous faut ensuite une variable membre privée de type int32_t pour stocker le nombre de clics.
Tout d’abord, ajoutez une propriété entière dans le fichier MainWindow.xaml.h pour conserver la valeur du compteur.
Les propriétés définies dans le fichier .idl ne sont qu’une interface d’accès externe ; nous devons créer nous-mêmes un champ privé pour stocker les données réelles.
Lorsque nous écrivons
Int32 MyPropertydans l’IDL, la classe expose une propriété Int32 en lecture/écriture aux composants externes.Le compilateur génère automatiquement les méthodes virtuelles Get/Set et l’événement de modification de propriété
MyPropertyChanged
int32_t m_myPropValue = 0; // Champ privé qui stocke le nombre de clics !Langage du code : C++ (cpp)
#pragma once
#include "MainWindow.g.h"
namespace winrt::WinuiDemo::implementation
{
struct MainWindow : MainWindowT<MainWindow>
{
private:
int32_t m_myPropValue = 0; // stocke la valeur de MyProperty
public:
MainWindow()
{
// Les objets Xaml ne doivent pas appeler InitializeComponent dans le constructeur.
// Voir https://github.com/microsoft/cppwinrt/tree/master/nuget#initializecomponent
}
//fonctions getter & setter
int32_t MyProperty();
void MyProperty(int32_t value);
//Fonction de clic
void Button_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
};
}
namespace winrt::WinuiDemo::factory_implementation
{
struct MainWindow : MainWindowT<MainWindow, implementation::MainWindow>
{
};
}
Langage du code : C++ (cpp)

Modifiez ensuite les fonctions getter et setter dans le fichier .cpp. Dans le gestionnaire de clic, récupérez la valeur actuelle via MyProperty(), incrémentez-la de 1 et réaffectez-la. Un point essentiel :
this->Bindings->Update(); Ne supprimez absolument pas cette ligne. Elle notifie tous les éléments de l’interface liés à cette propriété de se rafraîchir ; sans elle, l’affichage ne sera jamais mis à jour.
#include "pch.h"
#include "MainWindow.xaml.h"
#if __has_include("MainWindow.g.cpp")
#include "MainWindow.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::UI::Xaml;
// Pour en savoir plus sur WinUI, la structure des projets WinUI et les modèles, voir : http://aka.ms/winui-project-info.
namespace winrt::WinuiDemo::implementation
{
int32_t MainWindow::MyProperty()
{
return m_myPropValue; //récupère m_myPropValue
}
void MainWindow::MyProperty(int32_t value)
{
m_myPropValue = value; //définit m_myPropValue
this->Bindings->Update(); // Force le rafraîchissement de tous les x:Bind de la page pour mettre à jour l’affichage UI
}
}
void winrt::WinuiDemo::implementation::MainWindow::Button_Click(winrt::Windows::Foundation::IInspectable const& sender,
winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e)
{
MyProperty(MyProperty() + 1);//met à jour m_myPropValue, ajoute 1
}
Langage du code : C++ (cpp)

Recompilez et lancez l’application.
Sur mon ordinateur, la compilation prend énormément de temps ; cela variera selon vos composants matériels.
Build started at 15:29...
1>------ Build started: Project: WinuiDemo, Configuration: Debug x64 ------
1>WindowsAppSDKMLDeploymentMode=Framework
1>App.xaml.cpp
1>MainWindow.xaml.cpp
La compilation C++ génère de nombreux fichiers intermédiaires ; sur ma machine, le processus a duré plus de dix minutes sans se terminer au début.

À 15h40 heure locale, la compilation s’est enfin achevée et la fenêtre de l’application est apparue : l’ensemble du processus a pris 11 minutes complètes. J’ai craint à plusieurs reprises un plantage et failli fermer Visual Studio.
Résultat final de l’exécution

C’est la fin de cette leçon. Aujourd’hui, nous avons vu comment exécuter une logique d’arrière-plan et modifier le contenu de l’interface au clic sur un bouton, ainsi que le mécanisme de liaison de propriétés qui actualise automatiquement l’UI quand la valeur d’une propriété d’arrière-plan change.