Migration de l’interface utilisateur (y compris WinUI 3)

Cette rubrique montre comment migrer votre code d’interface utilisateur, y compris la migration vers la bibliothèque d’interface utilisateur Windows (WinUI) 3.

Résumé des différences d’API et/ou de fonctionnalités

La propriété Window.Current migre vers App.Window. Et la méthode CoreDispatcher.RunAsync migre vers DispatcherQueue.TryEnqueue.

Vous devez définir le handle de votre fenêtre (HWND) sur un MessageDialog et sur les sélecteurs.

Pour utiliser les API DataTransferManager , vous devez les associer à votre fenêtre.

Pour ContentDialog et Popup, vous devez définir leur propriété XamlRoot .

Vous devrez peut-être refactoriser votre balisage XAML Visual State Manager et Page.Resources .

Dans le SDK d'application Windows, AcryliqueBrush échantillonne toujours le contenu de l’application.

Remplacez Windows.UI.Xaml.Window.Current par App.Window

Cette section s’applique si vous utilisez la propriété Windows.UI.Xaml.Window.Current dans votre application UWP. Cette propriété n’est pas prise en charge dans le SDK d'application Windows. Cette section explique donc comment porter le code UWP qui utilise Window.Current.

// MainPage.xaml.cs in a UWP app
var width = Window.Current.Bounds.Width;
// MainPage.xaml.cpp in a UWP app
auto width{ Window::Current().Bounds().Width };

Votre application SDK d'application Windows peut ajouter sa propre notion de fenêtre actuelle ou main à l’aide d’une propriété statique publique sur votre classe d’application.

// App.xaml.cs in a Windows App SDK app
public partial class App : Application
{
    ...
    public static Window Window { get { return m_window; } }
    private static Window m_window;
}
// App.xaml.h in a Windows App SDK app
...
struct App : AppT<App>
{
    ...
    static winrt::Microsoft::UI::Xaml::Window Window(){ return window; };

private:
    static winrt::Microsoft::UI::Xaml::Window window;
};
...

// App.xaml.cpp
...
winrt::Microsoft::UI::Xaml::Window App::window{ nullptr };
...

Ensuite, dans la classe App elle-même, vous pouvez passer Window.Current simplement à window. En dehors de la classe App , remplacez Window.CurrentApp.Windowpar , comme suit :

// MainPage.xaml.cs in a UWP app
var width = App.Window.Bounds.Width;
// MainPage.xaml.cpp in a UWP app
#include <App.xaml.h>
auto width{ App::Window().Bounds().Width };

MessageDialog et sélecteurs

Dans votre application UWP, si vous utilisez certains types à partir des espaces de noms Windows.UI.Popups ou Windows.Storage.Pickers , cette section contient des informations pour vous aider à migrer ce code. Les exemples de code ci-dessous utilisent MessageDialog, mais vous pouvez appliquer exactement les mêmes techniques à l’affichage d’un sélecteur (par exemple, un FileOpenPicker, un FileSavePicker ou un FolderPicker).

Les étapes que vous devez suivre dans une application de bureau sont décrites dans Afficher les objets d’interface utilisateur WinRT qui dépendent de CoreWindow.

Notes

Pour les nouvelles applications, nous vous recommandons d’utiliser le contrôle ContentDialog au lieu de MessageDialog. Pour plus d’informations, consultez la section ContentDialog et Popup ci-dessous.

Voici un code UWP classique pour afficher un MessageDialog.

// In a UWP app
var showDialog = new Windows.UI.Popups.MessageDialog("Message here");
await showDialog.ShowAsync();
// In a UWP app
auto showDialog{ Windows::UI::Popups::MessageDialog(L"Message here") };
co_await showDialog.ShowAsync();

Voici le code équivalent dans une application SDK d'application Windows.

// MainWindow.xaml.cs in a WinUI 3 app
var showDialog = new Windows.UI.Popups.MessageDialog("Message here");
WinRT.Interop.InitializeWithWindow.Initialize(showDialog,
    WinRT.Interop.WindowNative.GetWindowHandle(this));
await showDialog.ShowAsync();
// pch.h in a WinUI 3 app
...
#include <Shobjidl.h>
#include <microsoft.ui.xaml.window.h>
#include <winrt/Windows.UI.Popups.h>
...

// MainWindow.xaml.cpp
...
auto showDialog{ Windows::UI::Popups::MessageDialog(L"Message here") };

auto windowNative{ this->m_inner.as<::IWindowNative>() };
HWND hWnd{ 0 };
windowNative->get_WindowHandle(&hWnd);
showDialog.as<::IInitializeWithWindow>()->Initialize(hWnd);

co_await showDialog.ShowAsync();

DataTransferManager

Dans votre application UWP, si vous appelez la méthode DataTransferManager.ShowShareUI , cette section contient des informations pour vous aider à migrer ce code.

Voici un code UWP classique qui appelle ShowShareUI.

// In a UWP app
var dataTransferManager = Windows.ApplicationModel.DataTransfer.DataTransferManager.GetForCurrentView();

dataTransferManager.DataRequested += (sender, args) =>
{
    args.Request.Data.Properties.Title = "In a UWP app...";
    args.Request.Data.SetText("...display the user interface for sharing content with another app.");
    args.Request.Data.RequestedOperation =
        Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy;
};

Windows.ApplicationModel.DataTransfer.DataTransferManager.ShowShareUI();
// In a UWP app
#include <winrt/Windows.ApplicationModel.DataTransfer.h>
...
auto dataTransferManager{ Windows::ApplicationModel::DataTransfer::DataTransferManager::GetForCurrentView() };

dataTransferManager.DataRequested([](Windows::ApplicationModel::DataTransfer::DataTransferManager const& /* sender */,
    Windows::ApplicationModel::DataTransfer::DataRequestedEventArgs const& args)
    {
        args.Request().Data().Properties().Title(L"In a UWP app...");
        args.Request().Data().SetText(L"...display the user interface for sharing content with another app.");
        args.Request().Data().RequestedOperation(Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy);
    });

Windows::ApplicationModel::DataTransfer::DataTransferManager::ShowShareUI();

Pour utiliser DataTransferManager.ShowShareUI dans votre application SDK d'application Windows, vous devez associer l’interface utilisateur de partage à votre fenêtre. Et cela doit être fait manuellement. Pour plus d’informations et des exemples de code, consultez Afficher des objets d’interface utilisateur WinRT qui dépendent de CoreWindow.

ContentDialog et popup

Si, dans votre application UWP, vous utilisez les classes Windows.UI.Xaml.Controls.ContentDialog ou Windows.UI.Xaml.Controls.Primitives.Popup , cette section contient des informations pour vous aider à migrer ce code. Les exemples de code ci-dessous utilisent ContentDialog, mais vous pouvez appliquer exactement les mêmes techniques à l’affichage d’un objet popup .

Voici un code UWP classique pour afficher un ContentDialog.

// MainPage.xaml.cs in a UWP app
var unsupportedFilesDialog = new ContentDialog();
// Set Title, Content, etc.
await unsupportedFilesDialog.ShowAsync();
// MainPage.xaml.cpp in a UWP app
ContentDialog unsupportedFilesDialog{};
// Set Title, Content, etc.
co_await unsupportedFilesDialog.ShowAsync();

Dans votre application SDK d'application Windows, il vous suffit de définir également la propriété XamlRoot de la boîte de dialogue. Voici comment procéder.

// MainPage.xaml.cs in a Windows App SDK app
var unsupportedFilesDialog = new ContentDialog();
// Set Title, Content, etc.
unsupportedFilesDialog.XamlRoot = this.Content.XamlRoot;
await unsupportedFilesDialog.ShowAsync();
// MainPage.xaml.cpp in a Windows App SDK app
ContentDialog unsupportedFilesDialog{};
// Set Title, Content, etc.
unsupportedFilesDialog.XamlRoot(this->Content().XamlRoot());
co_await unsupportedFilesDialog.ShowAsync();

Dois-je implémenter la navigation de page ?

Dans un projet UWP, par défaut, il y a du code de navigation dans les méthodes de la classe App , même si votre application est suffisamment simple pour qu’elle n’ait qu’une seule Page.

Quand vous créez un projet de SDK d’application Windows dans Visual Studio, le modèle de projet vous fournit une classe MainWindow (de type Microsoft.UI.Xaml.Window), mais aucune Page. En outre, le modèle de projet ne fournit aucun code de navigation.

Pour une application SDK d'application Windows suffisamment simple (une application monopage), vous pouvez peut-être la simplifier. Il se peut que vous n’ayez pas besoin de créer des pages ou des contrôles utilisateur dans votre projet SDK d'application Windows, mais plutôt de copier le balisage XAML et le code-behind de cette page unique dans MainWindow. Toutefois, il existe certaines choses que MainWindow ne prend pas en charge. Window n’étant pas un DependencyObject, les fonctionnalités telles que Resources et DataContext n’existent pas sur celle-ci. Les événements tels que Charger et Décharger ne font pas non plus l’objet. Pour plus d’informations et des solutions de contournement, consultez Visual State Manager et Page.Resources.

Si vous souhaitez ou avez besoin d’une navigation entre les pages de votre application SDK d'application Windows, vous pouvez le faire en migrant les méthodes App.OnLaunched et App::OnNavigationFailed à partir de votre application UWP. Dans App.OnLaunched, recherchez le code de navigation (le code qui crée rootFrame et accède à la première page de votre application) et fusionnez-le entre les deux lignes de code existantes (les lignes qui créent une fenêtre, puis l’activent). Vous devez également migrer le code que vous avez copié-collé. Pour obtenir un exemple de code simple, consultez Classe Page.

Visual State Manager et Page.Resources

Consultez également Dois-je implémenter la navigation de page ?. Si vous disposez d’une application UWP suffisamment simple pour copier votre balisage XAML et votre code-behind dans MainWindow, gardez à l’esprit ces exceptions.

Votre classe MainWindow (de type Microsoft.UI.Xaml.Window) n’est pas un contrôle, donc elle ne prend pas en charge le balisage XAML et le code-behind de Visual State Manager (voir Tutoriel : Créer des dispositions adaptatives). Vous disposez toutefois des deux options suivantes :

  • Ajoutez un élément UserControl au projet et migrez votre balisage et votre code-behind vers celui-ci. Placez ensuite une instance de ce contrôle utilisateur dans MainWindow.
  • Ajoutez un élément Page au projet et migrez votre balisage et votre code-behind vers celui-ci. Ajoutez ensuite du code à votre classe App pour accéder à cette page au démarrage, comme décrit dans Dois-je implémenter la navigation de page ?.

En outre, vous ne pourrez pas copier un <Page.Resources> élément dans MainWindow et le renommer simplement en <Window.Resources>. Au lieu de cela, parentez l’élément Resources sous le conteneur de disposition racine (par exemple, une grille) dans le balisage XAML pour MainWindow. Cela ressemblera à ceci :

<Window ...>
    <Grid>
        <Grid.Resources>...</Grid.Resources>
        ...
    </Grid>
</Window>

Propriété AcrylicBrush.BackgroundSource

La propriété AcrylicBrush.BackgroundSource existe dans UWP, mais pas dans le SDK d'application Windows. Dans le SDK d'application Windows, AcryliqueBrush échantillonne toujours le contenu de l’application.

Par conséquent, si vous accédez à la propriété AcrylicBrush.BackgroundSource dans le code source de votre application UWP (que ce soit dans le balisage XAML ou dans le code impératif), supprimez ce code lors de la migration de votre application vers le SDK d'application Windows. Utilisez plutôt la classe DesktopAcrylicController .