Partager via


Incorporation native

Parcourir l’exemple. Parcourir l'exemple

En règle générale, une application d’interface utilisateur d’application multiplateforme .NET (.NET MAUI) inclut des pages qui contiennent des dispositions, telles que Grid, et des dispositions qui contiennent des vues, telles que Button. Les pages, les mises en page et les vues dérivent de Element. L’incorporation native permet à tous les contrôles .NET MAUI qui dérivent de Element d’être utilisés dans les applications natives .NET pour Android, .NET pour iOS, .NET pour Mac Catalyst et WinUI.

Le processus de consommation d’un contrôle MAUI .NET dans une application native est le suivant :

  1. Créez des méthodes d’extension pour démarrer votre application incorporée native. Pour plus d’informations, consultez Créer des méthodes d’extension.
  2. Créez un projet unique .NET MAUI qui contient votre interface utilisateur .NET MAUI et toutes les dépendances. Pour plus d’informations, consultez Créer un projet .NET MAUI unique.
  3. Créez une application native et activez la prise en charge de .NET MAUI. Pour plus d’informations, consultez Activer la prise en charge de .NET MAUI.
  4. Initialisez .NET MAUI dans votre projet d’application natif. Pour plus d’informations, consultez Initialiser .NET MAUI.
  5. Créez l’interface utilisateur .NET MAUI et convertissez-la en type natif approprié avec la méthode d’extension ToPlatformEmbedding. Pour plus d’informations, consultez Consommer des contrôles .NET MAUI.
  1. Créez un projet unique .NET MAUI qui contient votre interface utilisateur .NET MAUI et toutes les dépendances. Pour plus d’informations, consultez Créer un projet .NET MAUI unique.
  2. Créez une application native et activez la prise en charge de .NET MAUI. Pour plus d’informations, consultez Activer la prise en charge de .NET MAUI.
  3. Initialisez .NET MAUI dans votre projet d’application natif. Pour plus d’informations, consultez Initialiser .NET MAUI.
  4. Créez l’interface utilisateur .NET MAUI et convertissez-la en type natif approprié avec la méthode d’extension ToPlatformEmbedding. Pour plus d’informations, consultez Consommer des contrôles .NET MAUI.

Remarque

Lorsque vous utilisez l’incorporation native, le moteur de liaison de données de .NET MAUI fonctionne toujours. Toutefois, la navigation de page doit être effectuée à l’aide de l’API de navigation native.

Créer des méthodes d’extension

Avant de créer une application native qui consomme des contrôles .NET MAUI, vous devez d’abord créer un projet de bibliothèque de classes .NET MAUI et supprimer le dossier Plateformes et la classe Class1 de celui-ci. Ensuite, ajoutez une classe à celle-ci nommée EmbeddedExtensions qui contient le code suivant :

using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Maui.Platform;

#if ANDROID
using PlatformView = Android.Views.View;
using PlatformWindow = Android.App.Activity;
using PlatformApplication = Android.App.Application;
#elif IOS || MACCATALYST
using PlatformView = UIKit.UIView;
using PlatformWindow = UIKit.UIWindow;
using PlatformApplication = UIKit.IUIApplicationDelegate;
#elif WINDOWS
using PlatformView = Microsoft.UI.Xaml.FrameworkElement;
using PlatformWindow = Microsoft.UI.Xaml.Window;
using PlatformApplication = Microsoft.UI.Xaml.Application;
#endif

namespace Microsoft.Maui.Controls;

public static class EmbeddedExtensions
{
    public static MauiAppBuilder UseMauiEmbedding(this MauiAppBuilder builder, PlatformApplication? platformApplication = null)
    {
#if ANDROID
        platformApplication ??= (Android.App.Application)Android.App.Application.Context;
#elif IOS || MACCATALYST
        platformApplication ??= UIKit.UIApplication.SharedApplication.Delegate;
#elif WINDOWS
        platformApplication ??= Microsoft.UI.Xaml.Application.Current;
#endif

        builder.Services.AddSingleton(platformApplication);
        builder.Services.AddSingleton<EmbeddedPlatformApplication>();
        builder.Services.AddScoped<EmbeddedWindowProvider>();

        // Returning null is acceptable here as the platform window is optional - but we don't know until we resolve it
        builder.Services.AddScoped<PlatformWindow>(svc => svc.GetRequiredService<EmbeddedWindowProvider>().PlatformWindow!);
        builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<IMauiInitializeService, EmbeddedInitializeService>());
        builder.ConfigureMauiHandlers(handlers =>
        {
            handlers.AddHandler(typeof(Window), typeof(EmbeddedWindowHandler));
        });

        return builder;
    }

    public static IMauiContext CreateEmbeddedWindowContext(this MauiApp mauiApp, PlatformWindow platformWindow, Window? window = null)
    {
        var windowScope = mauiApp.Services.CreateScope();

#if ANDROID
        var windowContext = new MauiContext(windowScope.ServiceProvider, platformWindow);
#else
        var windowContext = new MauiContext(windowScope.ServiceProvider);
#endif

        window ??= new Window();

        var wndProvider = windowContext.Services.GetRequiredService<EmbeddedWindowProvider>();
        wndProvider.SetWindow(platformWindow, window);
        window.ToHandler(windowContext);

        return windowContext;
    }

    public static PlatformView ToPlatformEmbedded(this IElement element, IMauiContext context)
    {
        var wndProvider = context.Services.GetService<EmbeddedWindowProvider>();
        if (wndProvider is not null && wndProvider.Window is Window wnd && element is VisualElement visual)
            wnd.AddLogicalChild(visual);

        return element.ToPlatform(context);
    }

    private class EmbeddedInitializeService : IMauiInitializeService
    {
        public void Initialize(IServiceProvider services) =>
            services.GetRequiredService<EmbeddedPlatformApplication>();
    }
}

Ces méthodes d’extension se trouvent dans l’espace de noms Microsoft.Maui.Controls et sont utilisées pour démarrer votre application incorporée native sur chaque plateforme. Les méthodes d’extension font référence les types EmbeddedPlatformApplication, EmbeddedWindowHandler et EmbeddedWindowProvider que vous devez également ajouter au projet de bibliothèque .NET MAUI.

Le code suivant montre la classe EmbeddedPlatformApplication, qui doit être ajoutée au même projet de bibliothèque .NET MAUI que la classe EmbeddedExtensions :

#if ANDROID
using PlatformApplication = Android.App.Application;
#elif IOS || MACCATALYST
using PlatformApplication = UIKit.IUIApplicationDelegate;
#elif WINDOWS
using PlatformApplication = Microsoft.UI.Xaml.Application;
#endif

namespace Microsoft.Maui.Controls;

internal class EmbeddedPlatformApplication : IPlatformApplication
{
    private readonly MauiContext rootContext;
    private readonly IMauiContext applicationContext;

    public IServiceProvider Services { get; }
    public IApplication Application { get; }

    public EmbeddedPlatformApplication(IServiceProvider services)
    {
        IPlatformApplication.Current = this;

#if ANDROID
        var platformApp = services.GetRequiredService<PlatformApplication>();
        rootContext = new MauiContext(services, platformApp);
#else
        rootContext = new MauiContext(services);
#endif

        applicationContext = MakeApplicationScope(rootContext);
        Services = applicationContext.Services;
        Application = Services.GetRequiredService<IApplication>();
    }

    private static IMauiContext MakeApplicationScope(IMauiContext rootContext)
    {
        var scopedContext = new MauiContext(rootContext.Services);
        InitializeScopedServices(scopedContext);
        return scopedContext;
    }

    private static void InitializeScopedServices(IMauiContext scopedContext)
    {
        var scopedServices = scopedContext.Services.GetServices<IMauiInitializeScopedService>();

        foreach (var service in scopedServices)
            service.Initialize(scopedContext.Services);
    }
}

Le code suivant montre la classe EmbeddedWindowHandler, qui doit être ajoutée au même projet de bibliothèque .NET MAUI que la classe EmbeddedExtensions :

using Microsoft.Maui.Handlers;

#if ANDROID
using PlatformWindow = Android.App.Activity;
#elif IOS || MACCATALYST
using PlatformWindow = UIKit.UIWindow;
#elif WINDOWS
using PlatformWindow = Microsoft.UI.Xaml.Window;
#endif

namespace Microsoft.Maui.Controls;

internal class EmbeddedWindowHandler : ElementHandler<IWindow, PlatformWindow>, IWindowHandler
{
    public static IPropertyMapper<IWindow, IWindowHandler> Mapper =
        new PropertyMapper<IWindow, IWindowHandler>(ElementHandler.ElementMapper)
        {
        };

    public static CommandMapper<IWindow, IWindowHandler> CommandMapper =
        new CommandMapper<IWindow, IWindowHandler>(ElementHandler.ElementCommandMapper)
        {
        };

    public EmbeddedWindowHandler() : base(Mapper)
    {
    }

    protected override PlatformWindow CreatePlatformElement() =>
        MauiContext!.Services.GetRequiredService<PlatformWindow>() ??
        throw new InvalidOperationException("EmbeddedWindowHandler could not locate a platform window.");
}

Le code suivant montre la classe EmbeddedWindowProvider, qui doit être ajoutée au même projet de bibliothèque .NET MAUI que la classe EmbeddedExtensions :

#if ANDROID
using PlatformWindow = Android.App.Activity;
#elif IOS || MACCATALYST
using PlatformWindow = UIKit.UIWindow;
#elif WINDOWS
using PlatformWindow = Microsoft.UI.Xaml.Window;
#endif

namespace Microsoft.Maui.Controls;

public class EmbeddedWindowProvider
{
    WeakReference<PlatformWindow?>? platformWindow;
    WeakReference<Window?>? window;

    public PlatformWindow? PlatformWindow => Get(platformWindow);
    public Window? Window => Get(window);

    public void SetWindow(PlatformWindow? platformWindow, Window? window)
    {
        this.platformWindow = new WeakReference<PlatformWindow?>(platformWindow);
        this.window = new WeakReference<Window?>(window);
    }

    private static T? Get<T>(WeakReference<T?>? weak) where T : class =>
        weak is not null && weak.TryGetTarget(out var target) ? target : null;
}

Créer un projet .NET MAUI unique

Avant de créer une application native qui consomme des contrôles .NET MAUI, vous devez ajouter un projet d’application .NET MAUI à la même solution que le projet de bibliothèque de classes .NET MAUI que vous avez créé précédemment. Le projet d’application .NET MAUI stocke l’interface utilisateur que vous envisagez de réutiliser dans votre application incorporée native. Après avoir ajouté un nouveau projet d’application .NET MAUI à la solution, procédez comme suit :

  1. Supprimez le dossier Propriétés du projet.

  2. Supprimez le dossier Plateformes du projet.

  3. Supprimez le dossier Resources/AppIcon du projet.

  4. Supprimez le dossier Resources/raw du projet.

  5. Supprimez le dossier Resources/Splash du projet.

  6. Supprimez la classe AppShell du projet.

  7. Vérifiez que la App classe ne définit pas la MainPage propriété ou ne remplace pas la CreateWindow méthode :

    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
        }
    }
    
  8. Supprimez la classe MainPage du projet.

  9. Modifiez le fichier projet afin que la propriété de build $(TargetFramework) soit définie sur net8.0, et la propriété de build $(OutputType) est supprimée :

    <PropertyGroup>
      <TargetFramework>net8.0</TargetFramework>
    
      <RootNamespace>MyMauiApp</RootNamespace>
      <UseMaui>true</UseMaui>
      <SingleProject>true</SingleProject>
      <ImplicitUsings>enable</ImplicitUsings>
      <Nullable>enable</Nullable>
    
      ...
    </PropertyGroup>
    

    Important

    Vérifiez que vous définissez la propriété de build $(TargetFramework), et non la propriété de build $(TargetFrameworks).

  10. Modifiez la méthode CreateMauiApp dans la classe MauiProgram afin qu’elle accepte un argument facultatif Action<MauiAppBuilder> appelé avant que la méthode ne retourne :

    public static MauiApp CreateMauiApp(Action<MauiAppBuilder>? additional = null)
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
            });
    
        #if DEBUG
            builder.Logging.AddDebug();
        #endif
    
        additional?.Invoke(builder);
        return builder.Build();
    }
    

À ce stade, vous devez ajouter votre interface utilisateur .NET MAUI requise au projet, y compris toutes les dépendances et ressources, et vous assurer que le projet est généré correctement.

Créer un projet .NET MAUI unique

Avant de créer une application native qui consomme des contrôles .NET MAUI, vous devez ajouter un projet d’application .NET MAUI à la même solution que le projet de bibliothèque de classes .NET MAUI que vous avez créé précédemment. Le projet d’application .NET MAUI stocke l’interface utilisateur que vous envisagez de réutiliser dans votre application incorporée native. Après avoir ajouté un nouveau projet d’application .NET MAUI à la solution, procédez comme suit :

  1. Supprimez le dossier Propriétés du projet.

  2. Supprimez le dossier Plateformes du projet.

  3. Supprimez le dossier Resources/AppIcon du projet.

  4. Supprimez le dossier Resources/raw du projet.

  5. Supprimez le dossier Resources/Splash du projet.

  6. Supprimez la classe AppShell du projet.

  7. Vérifiez que la App classe ne définit pas la MainPage propriété ou ne remplace pas la CreateWindow méthode :

    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
        }
    }
    
  8. Supprimez la classe MainPage du projet.

  9. Modifiez le fichier projet afin que la propriété de build $(TargetFramework) soit définie sur net9.0, et la propriété de build $(OutputType) est supprimée :

    <PropertyGroup>
      <TargetFramework>net9.0</TargetFramework>
    
      <RootNamespace>MyMauiApp</RootNamespace>
      <UseMaui>true</UseMaui>
      <SingleProject>true</SingleProject>
      <ImplicitUsings>enable</ImplicitUsings>
      <Nullable>enable</Nullable>
    
      ...
    </PropertyGroup>
    

    Important

    Vérifiez que vous définissez la propriété de build $(TargetFramework), et non la propriété de build $(TargetFrameworks).

  10. Dans la MauiProgram classe, modifiez la CreateMauiApp méthode pour accepter un TApp argument générique et acceptez un argument facultatif Action<MauiAppBuilder> appelé avant que la méthode ne retourne. En outre, remplacez l’appel par UseMauiApp<App> UseMauiEmbeddedApp<TApp>:

    public static class MauiProgram
    {
        // Create a MauiApp using the specified application.
        public static MauiApp CreateMauiApp<TApp>(Action<MauiAppBuilder>? additional = null) where TApp : App
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiEmbeddedApp<TApp>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                });
    
            #if DEBUG
                builder.Logging.AddDebug();
            #endif
    
            additional?.Invoke(builder);
    
            return builder.Build();
        }
    }
    
  11. Dans la MauiProgram classe, ajoutez une CreateMauiApp surcharge qui accepte un argument facultatif Action<MauiAppBuilder> :

    public static class MauiProgram
    {
        ...
    
        // Create a MauiApp using the default application.
        public static MauiApp CreateMauiApp(Action<MauiAppBuilder>? additional = null) =>
            CreateMauiApp<App>(additional);
    }
    

Vous devez ensuite ajouter votre interface utilisateur .NET MAUI requise au projet, y compris toutes les dépendances et ressources, et vous assurer que le projet est généré correctement.

Activer la prise en charge de .NET MAUI

Pour utiliser des contrôles .NET MAUI dérivés d’une application Element dans .NET pour Android, .NET pour iOS, .NET pour Mac Catalyst ou WinUI, vous devez ajouter votre projet d’application natif à la même solution que le projet de bibliothèque de classes .NET MAUI que vous avez créé précédemment. Ensuite, vous devez activer la prise en charge de .NET MAUI dans le fichier projet de votre application native en définissant les propriétés de build $(UseMaui) et $(MauiEnablePlatformUsings) sur true dans le premier nœud <PropertyGroup> du fichier projet :

<PropertyGroup>
    ...
    <Nullable>enable</Nullable>
    <ImplicitUsings>true</ImplicitUsings>

    <UseMaui>true</UseMaui>
    <MauiEnablePlatformUsings>true</MauiEnablePlatformUsings>  
</PropertyGroup>

Pour les applications .NET pour Mac Catalyst, vous devez également définir la propriété de build $(SupportedOSPlatformVersion) sur un minimum de 14.0 :

<PropertyGroup>
    ...
    <Nullable>enable</Nullable>
    <ImplicitUsings>true</ImplicitUsings>

    <SupportedOSPlatformVersion>14.2</SupportedOSPlatformVersion>
    <UseMaui>true</UseMaui>
    <MauiEnablePlatformUsings>true</MauiEnablePlatformUsings>  
</PropertyGroup>

Pour les applications .NET pour Mac Catalyst, vous devez également définir la $(SupportedOSPlatformVersion) propriété de build sur un minimum de 15,0 :

<PropertyGroup>
    ...
    <Nullable>enable</Nullable>
    <ImplicitUsings>true</ImplicitUsings>

    <SupportedOSPlatformVersion>15.0</SupportedOSPlatformVersion>
    <UseMaui>true</UseMaui>
    <MauiEnablePlatformUsings>true</MauiEnablePlatformUsings>  
</PropertyGroup>

Pour les applications WinUI, vous devez également définir la propriété de build $(EnableDefaultXamlItems) sur false :

<PropertyGroup>
    ...
    <Nullable>enable</Nullable>
    <ImplicitUsings>true</ImplicitUsings>

    <UseMaui>true</UseMaui>
    <MauiEnablePlatformUsings>true</MauiEnablePlatformUsings>    
    <EnableDefaultXamlItems>false</EnableDefaultXamlItems>
</PropertyGroup>

Cela vous empêche de recevoir des erreurs de build sur la méthode InitializeComponent déjà définie.

Ensuite, ajoutez des éléments de build $(PackageReference) au fichier projet pour les packages NuGet Microsoft.Maui.Controls et Microsoft.Maui.Controls.Compatiblity :

<ItemGroup>
    <PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
    <PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="$(MauiVersion)" />
</ItemGroup>

Ensuite, ajoutez $(PackageReference) des éléments de build au fichier projet pour le Microsoft.Maui.Controls package NuGet :

<ItemGroup>
    <PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
</ItemGroup>

Initialiser .NET MAUI

.NET MAUI doit être initialisé avant qu’un projet d’application native puisse construire un contrôle .NET MAUI. Le choix de l’initialisation dépend principalement du moment où il est le plus pratique dans votre flux d’application. Il peut être effectué au démarrage ou juste avant la construction d’un contrôle MAUI .NET. L’approche décrite ici consiste à initialiser .NET MAUI lorsque l’interface utilisateur initiale de l’application est créée.

En règle générale, le modèle d’initialisation de .NET MAUI dans un projet d’application native est le suivant :

Sur Android, le remplacement OnCreate dans la classe est généralement l’endroit où effectuer des tâches liées au démarrage de l’application MainActivity. L’exemple de code suivant montre que .NET MAUI est initialisé dans la classe MainActivity :

namespace MyNativeEmbeddedApp.Droid;

[Activity(Label = "@string/app_name", MainLauncher = true, Theme = "@style/AppTheme")]
public class MainActivity : Activity
{
    public static readonly Lazy<MauiApp> MauiApp = new(() =>
    {
        var mauiApp = MauiProgram.CreateMauiApp(builder =>
        {
            builder.UseMauiEmbedding();
        });
        return mauiApp;
    });

    public static bool UseWindowContext = true;

    protected override void OnCreate(Bundle? savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        // Ensure .NET MAUI app is built before creating .NET MAUI views
        var mauiApp = MainActivity.MauiApp.Value;

        // Create .NET MAUI context
        var context = UseWindowContext
            ? mauiApp.CreateEmbeddedWindowContext(this) // Create window context
            : new MauiContext(mauiApp.Services, this);  // Create app context

        ...              
    }
}

Sur iOS et Mac Catalyst, la classe AppDelegate doit être modifiée pour retourner true pour le remplacement FinishedLaunching :

namespace MyNativeEmbeddedApp.iOS;

[Register("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
    public override UIWindow? Window { get; set; }

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) => true;
}

La méthode WillConnect de la classe SceneDelegate doit ensuite être modifiée pour créer votre contrôleur de vue principal et la définir comme vue de l’élément UINavigationController :

namespace MyNativeEmbeddedApp.iOS;

[Register("SceneDelegate")]
public class SceneDelegate : UIResponder, IUIWindowSceneDelegate
{
    [Export("window")]
    public UIWindow? Window { get; set; }

    [Export("scene:willConnectToSession:options:")]
    public void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions)
    {
        if (scene is not UIWindowScene windowScene)
            return;

        Window = new UIWindow(windowScene);

        var mainVC = new MainViewController();
        var navigationController = new UINavigationController(mainVC);
        navigationController.NavigationBar.PrefersLargeTitles = true;

        Window.RootViewController = navigationController;
        Window.MakeKeyAndVisible();
    }

    ...
}

Ensuite, dans l’éditeur XML, ouvrez le fichier Info.plist et ajoutez le code XML suivant à la fin du fichier :

<key>UIApplicationSceneManifest</key>
<dict>
  <key>UIApplicationSupportsMultipleScenes</key>
  <true/>
  <key>UISceneConfigurations</key>
  <dict>
    <key>UIWindowSceneSessionRoleApplication</key>
    <array>
      <dict>
        <key>UISceneConfigurationName</key>
        <string>Default Configuration</string>
        <key>UISceneDelegateClassName</key>
        <string>SceneDelegate</string>
      </dict>
    </array>
  </dict>
</dict>

.NET MAUI peut ensuite être initialisé dans la méthode ViewDidLoad dans votre contrôleur de vue principal :

using Microsoft.Maui.Platform;

namespace MyNativeEmbeddedApp.iOS;

public class MainViewController : UIViewController
{
    UIWindow GetWindow() =>
        View?.Window ??
        ParentViewController?.View?.Window ??
        MainViewController.MauiApp.Value.Services.GetRequiredService<IUIApplicationDelegate>().GetWindow() ??
        UIApplication.SharedApplication.Delegate.GetWindow();

    public static readonly Lazy<MauiApp> MauiApp = new(() =>
    {
        var mauiApp = MauiProgram.CreateMauiApp(builder =>
        {
            builder.UseMauiEmbedding();
        });
        return mauiApp;
    });

    public static bool UseWindowContext = true;

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        // Ensure app is built before creating .NET MAUI views
        var mauiApp = MainViewController.MauiApp.Value;

        // Create .NET MAUI context
        var context = UseWindowContext
            ? mauiApp.CreateEmbeddedWindowContext(GetWindow()) // Create window context
            : new MauiContext(mauiApp.Services);               // Create app context

        ...
    }
}

Sur Windows, la classe MainWindow est généralement l’endroit où effectuer des tâches de démarrage d’application associées à l’interface utilisateur :

namespace MyNativeEmbeddedApp.WinUI;

public sealed partial class MainWindow : Microsoft.UI.Xaml.Window
{
    public static readonly Lazy<MauiApp> MauiApp = new(() =>
    {
        var mauiApp = MauiProgram.CreateMauiApp(builder =>
        {
            builder.UseMauiEmbedding();
        });
        return mauiApp;
    });

    public static bool UseWindowContext = true;

    public MainWindow()
    {
        this.InitializeComponent();

        // Ensure .NET MAUI app is built before creating .NET MAUI views
        var mauiApp = MainWindow.MauiApp.Value;

        // Create .NET MAUI context
        var context = UseWindowContext
            ? mauiApp.CreateEmbeddedWindowContext(this) // Create window context
            : new MauiContext(mauiApp.Services);        // Create app context

        ...
    }
}

Dans cet exemple, l’objet MauiApp est créé à l’aide d’une initialisation différée. La méthode d’extension UseMauiEmbedding est appelée sur l’objet MauiAppBuilder. Par conséquent, votre projet d’application native doit inclure une référence au projet de bibliothèque de classes .NET MAUI que vous avez créé qui contient cette méthode d’extension. Un objet MauiContext est ensuite créé à partir de l’objet MauiApp , avec une détermination bool à partir de laquelle le contexte est délimité. L’objet MauiContext sera utilisé lors de la conversion de contrôles .NET MAUI en types natifs.

L’incorporation peut être effectuée dans un contexte d’application ou un contexte de fenêtre, mais pour une compatibilité .NET MAUI maximale, elle doit être effectuée dans un contexte de fenêtre.

Contexte de l’application

L’incorporation native peut être effectuée dans un contexte d’application, où l’application native n’a aucune connaissance d’une fenêtre. Avec cette approche, l’initialisation d’incorporation native vous oblige à :

L’exemple suivant montre cette approche :

var mauiApp = MauiProgram.CreateMauiApp();
var context = new MauiContext(mauiApp.Services); // Activity also needs passing on Android

Une vue MAUI .NET peut ensuite être créée et convertie en vue native avec la ToPlatformEmbedded méthode d’extension, ce qui nécessite l’objet MauiContext en tant qu’argument.

Cette approche convient aux scénarios où une application native doit incorporer une interface utilisateur .NET MAUI simple, mais n’a pas besoin d’accéder à toutes les fonctionnalités .NET MAUI. L’inconvénient de cette approche est que les outils tels que le rechargement à chaud et certaines fonctionnalités MAUI .NET ne fonctionnent pas.

Conseil

La création d’un MauiApp objet chaque fois qu’une vue MAUI .NET est incorporée en tant qu’affichage natif n’est pas recommandée. Cela peut être problématique si les vues incorporées accèdent à la Application.Current propriété. Au lieu de cela, l’objet MauiApp peut être créé en tant qu’instance statique partagée :

public static class MyEmbeddedMauiApp
{
    static MauiApp? _shared;
    public static MauiApp Shared => _shared ??= MauiProgram.CreateMauiApp();
}

Avec cette approche, vous pouvez instancier l’objet MauiApp au début du cycle de vie de votre application pour éviter d’avoir un petit délai la première fois que vous incorporez une vue MAUI .NET dans votre application.

Sur Android, un fragment représente une partie de l’interface utilisateur au sein d’une activité. L’exemple de code suivant montre que .NET MAUI est initialisé dans un fragment :

using Android.Runtime;
using Android.Views;
using AndroidX.Navigation.Fragment;
using Microsoft.Maui.Controls.Embedding;
using Fragment = AndroidX.Fragment.App.Fragment;
using View = Android.Views.View;

namespace MyNativeEmbeddedApp.Droid;

[Register("com.companyname.nativeembeddingdemo." + nameof(FirstFragment))]
public class FirstFragment : Fragment
{
    public override View? OnCreateView(LayoutInflater inflater, ViewGroup? container, Bundle? savedInstanceState) =>
        inflater.Inflate(Resource.Layout.fragment_first, container, false);

    public override void OnViewCreated(View view, Bundle? savedInstanceState)
    {
        base.OnViewCreated(view, savedInstanceState);

        // Ensure .NET MAUI app is built before creating .NET MAUI views
        var mauiApp = MyEmbeddedMauiApp.Shared;

        // Create .NET MAUI context
        var context = new MauiContext(mauiApp.Services, Activity);

        ...
    }
}

Sur iOS et Mac Catalyst, la classe AppDelegate doit être modifiée pour retourner true pour le remplacement FinishedLaunching :

namespace MyNativeEmbeddedApp.iOS;

[Register("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
    public override UIWindow? Window { get; set; }

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) => true;
}

La méthode WillConnect de la classe SceneDelegate doit ensuite être modifiée pour créer votre contrôleur de vue principal et la définir comme vue de l’élément UINavigationController :

namespace MyNativeEmbeddedApp.iOS;

[Register("SceneDelegate")]
public class SceneDelegate : UIResponder, IUIWindowSceneDelegate
{
    [Export("window")]
    public UIWindow? Window { get; set; }

    [Export("scene:willConnectToSession:options:")]
    public void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions)
    {
        if (scene is not UIWindowScene windowScene)
            return;

        Window = new UIWindow(windowScene);

        var mainVC = new MainViewController();
        var navigationController = new UINavigationController(mainVC);
        navigationController.NavigationBar.PrefersLargeTitles = true;

        Window.RootViewController = navigationController;
        Window.MakeKeyAndVisible();
    }

    ...
}

Ensuite, dans l’éditeur XML, ouvrez le fichier Info.plist et ajoutez le code XML suivant à la fin du fichier :

<key>UIApplicationSceneManifest</key>
<dict>
  <key>UIApplicationSupportsMultipleScenes</key>
  <true/>
  <key>UISceneConfigurations</key>
  <dict>
    <key>UIWindowSceneSessionRoleApplication</key>
    <array>
      <dict>
        <key>UISceneConfigurationName</key>
        <string>Default Configuration</string>
        <key>UISceneDelegateClassName</key>
        <string>SceneDelegate</string>
      </dict>
    </array>
  </dict>
</dict>

.NET MAUI peut ensuite être initialisé dans la méthode ViewDidLoad dans votre contrôleur de vue principal :

using Microsoft.Maui.Controls.Embedding;

namespace MyNativeEmbeddedApp.iOS;

public class MainViewController : UIViewController
{
    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        // Ensure .NET MAUI app is built before creating .NET MAUI views
        var mauiApp = MyEmbeddedMauiApp.Shared;

        // Create .NET MAUI context
        var context = new MauiContext(mauiApp.Services);

        ...
    }
}

Sur Windows, la classe MainWindow est généralement l’endroit où effectuer des tâches de démarrage d’application associées à l’interface utilisateur :

using Microsoft.Maui.Controls.Embedding;
using Microsoft.UI.Xaml;

namespace MyNativeEmbeddedApp.WinUI;

public sealed partial class MainWindow : Microsoft.UI.Xaml.Window
{
    public MainWindow()
    {
        this.InitializeComponent();
    }

    private async void OnRootLayoutLoaded(object? sender, RoutedEventArgs e)
    {
        await Task.Yield();

        // Ensure .NET MAUI app is built before creating .NET MAUI views
        var mauiApp = MyEmbeddedMauiApp.Shared;

        // Create .NET MAUI context
        var context = new MauiContext(mauiApp.Services);

        ...
    }
}

Dans cet exemple, l’objet MauiApp est créé en tant qu’instance statique partagée. Lorsque cet objet est créé, MauiProgram.CreateMauiApp est appelé à son tour la UseMauiEmbedding méthode d’extension sur l’objet MauiAppBuilder . Par conséquent, votre projet d’application native doit inclure une référence au projet de bibliothèque de classes .NET MAUI que vous avez créé qui contient votre MauiProgram classe et votre interface utilisateur MAUI .NET. Un MauiContext objet est ensuite créé à partir de l’objet MauiApp , qui est délimité à l’objet MauiApp . L’objet MauiContext sera utilisé lors de la conversion de contrôles .NET MAUI en types natifs.

Contexte de fenêtre

L’incorporation native peut être effectuée dans un contexte de fenêtre, où l’application native a connaissance d’une fenêtre. Dans certains scénarios, les vues MAUI .NET nécessitent l’accès à une fenêtre pour fonctionner correctement. Par exemple, les déclencheurs adaptatifs nécessitent l’accès à la fenêtre d’une vue et s’il n’y a pas de fenêtre qu’ils ne fonctionnent pas.

Avec cette approche, l’initialisation d’incorporation native vous oblige à :

  • Créez un objet MauiApp.
  • Créez un MauiContext objet avec la CreateEmbeddedWindowContext méthode. L’objet MauiContext sera utilisé pour obtenir une vue native à partir de la vue .NET MAUI.

La CreateEmbeddedWindowContext méthode crée un contexte de fenêtre qui associe une fenêtre native à une fenêtre .NET MAUI :

var mauiApp = MauiProgram.CreateMauiApp();
var context = mauiApp.CreateEmbeddedWindowContext(this);

Une vue MAUI .NET peut ensuite être créée et convertie en vue native avec la ToPlatformEmbedded méthode d’extension, ce qui nécessite l’objet MauiContext en tant qu’argument.

Remarque

La ToPlatformEmbedded méthode d’extension a une surcharge qui ajoute une vue MAUI .NET à une fenêtre incorporée.

L’avantage de cette approche est qu’il existe une seule fenêtre MAUI .NET pour chaque fenêtre native, les API liées aux fenêtres fonctionnent correctement, et les outils tels que le rechargement à chaud fonctionnent correctement.

Conseil

La création d’un MauiApp objet chaque fois qu’une vue MAUI .NET est incorporée en tant qu’affichage natif n’est pas recommandée. Cela peut être problématique si les vues incorporées accèdent à la Application.Current propriété. Au lieu de cela, l’objet MauiApp peut être créé en tant qu’instance statique partagée :

public static class MyEmbeddedMauiApp
{
    static MauiApp? _shared;
    public static MauiApp Shared => _shared ??= MauiProgram.CreateMauiApp();
}

Avec cette approche, vous pouvez instancier l’objet MauiApp au début du cycle de vie de votre application pour éviter d’avoir un petit délai la première fois que vous incorporez une vue MAUI .NET dans votre application.

Sur Android, un fragment représente une partie de l’interface utilisateur au sein d’une activité. L’exemple de code suivant montre que .NET MAUI est initialisé dans un fragment :

using Android.Runtime;
using Android.Views;
using AndroidX.Navigation.Fragment;
using Microsoft.Maui.Controls.Embedding;
using Fragment = AndroidX.Fragment.App.Fragment;
using View = Android.Views.View;

namespace MyNativeEmbeddedApp.Droid;

[Register("com.companyname.nativeembeddingdemo." + nameof(FirstFragment))]
public class FirstFragment : Fragment
{
    Activity? _window;
    IMauiContext? _windowContext;

    public IMauiContext WindowContext =>
        _windowContext ??= MyEmbeddedMauiApp.Shared.CreateEmbeddedWindowContext(_window ?? throw new InvalidOperationException());

    public override View? OnCreateView(LayoutInflater inflater, ViewGroup? container, Bundle? savedInstanceState) =>
        inflater.Inflate(Resource.Layout.fragment_first, container, false);

    public override void OnViewCreated(View view, Bundle? savedInstanceState)
    {
        base.OnViewCreated(view, savedInstanceState);

        _window ??= Activity;

        // Create MAUI embedded window context
        var context = WindowContext;

        ...
    }
}

Sur iOS et Mac Catalyst, la classe AppDelegate doit être modifiée pour retourner true pour le remplacement FinishedLaunching :

namespace MyNativeEmbeddedApp.iOS;

[Register("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
    public override UIWindow? Window { get; set; }

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) => true;
}

La méthode WillConnect de la classe SceneDelegate doit ensuite être modifiée pour créer votre contrôleur de vue principal et la définir comme vue de l’élément UINavigationController :

namespace MyNativeEmbeddedApp.iOS;

[Register("SceneDelegate")]
public class SceneDelegate : UIResponder, IUIWindowSceneDelegate
{
    [Export("window")]
    public UIWindow? Window { get; set; }

    [Export("scene:willConnectToSession:options:")]
    public void WillConnect(UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions)
    {
        if (scene is not UIWindowScene windowScene)
            return;

        Window = new UIWindow(windowScene);

        var mainVC = new MainViewController();
        var navigationController = new UINavigationController(mainVC);
        navigationController.NavigationBar.PrefersLargeTitles = true;

        Window.RootViewController = navigationController;
        Window.MakeKeyAndVisible();
    }

    ...
}

Ensuite, dans l’éditeur XML, ouvrez le fichier Info.plist et ajoutez le code XML suivant à la fin du fichier :

<key>UIApplicationSceneManifest</key>
<dict>
  <key>UIApplicationSupportsMultipleScenes</key>
  <true/>
  <key>UISceneConfigurations</key>
  <dict>
    <key>UIWindowSceneSessionRoleApplication</key>
    <array>
      <dict>
        <key>UISceneConfigurationName</key>
        <string>Default Configuration</string>
        <key>UISceneDelegateClassName</key>
        <string>SceneDelegate</string>
      </dict>
    </array>
  </dict>
</dict>

.NET MAUI peut ensuite être initialisé dans la méthode ViewDidLoad dans votre contrôleur de vue principal :

using Microsoft.Maui.Controls.Embedding;

namespace MyNativeEmbeddedApp.iOS;

public class MainViewController : UIViewController
{
    UIKit.UIWindow? _window;
    IMauiContext? _windowContext;

    public IMauiContext WindowContext =>
        _windowContext ??= MyEmbeddedMauiApp.Shared.CreateEmbeddedWindowContext(_window ?? throw new InvalidOperationException());

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        _window ??= ParentViewController!.View!.Window;

        // Create MAUI embedded window context
        var context = WindowContext;

        ...
    }
}

Sur Windows, la classe MainWindow est généralement l’endroit où effectuer des tâches de démarrage d’application associées à l’interface utilisateur :

using Microsoft.Maui.Controls.Embedding;
using Microsoft.UI.Xaml;

namespace MyNativeEmbeddedApp.WinUI;

public sealed partial class MainWindow : Microsoft.UI.Xaml.Window
{
    Microsoft.UI.Xaml.Window? _window;
    IMauiContext? _windowContext;

    public IMauiContext WindowContext =>
        _windowContext ??= MyEmbeddedMauiApp.Shared.CreateEmbeddedWindowContext(_window ?? throw new InvalidOperationException());

    public MainWindow()
    {
        this.InitializeComponent();
        _window ??= this;
    }

    private async void OnRootLayoutLoaded(object? sender, RoutedEventArgs e)
    {
        await Task.Yield();

        // Create MAUI embedded window context
        var context = WindowContext;

        ...
    }
}

Dans cet exemple, l’objet MauiApp est créé en tant qu’instance statique partagée. Lorsque cet objet est créé, MauiProgram.CreateMauiApp est appelé à son tour la UseMauiEmbedding méthode d’extension sur l’objet MauiAppBuilder . Par conséquent, votre projet d’application native doit inclure une référence au projet de bibliothèque de classes .NET MAUI que vous avez créé qui contient votre MauiProgram classe et votre interface utilisateur MAUI .NET. Un MauiContext objet est ensuite créé avec la CreateEmbeddedWindowContext méthode, qui est délimité à la fenêtre. L’objet MauiContext sera utilisé lors de la conversion de contrôles .NET MAUI en types natifs.

Consommer des contrôles .NET MAUI

Une fois que .NET MAUI a été initialisé dans votre application native, vous pouvez ajouter votre interface utilisateur MAUI .NET à la disposition de votre application native. Pour ce faire, créez une instance de l’interface utilisateur et convertissez-la en type natif approprié avec la méthode d’extension ToPlatformEmbedded.

Sur Android, la méthode d’extension ToPlatformEmbedded convertit le contrôle .NET MAUI en objet View Android :

var mauiView = new MyMauiContent();
Android.Views.View nativeView = mauiView.ToPlatformEmbedded(context);

Dans cet exemple, un ContentViewobjet dérivé est converti en objet View Android.

Remarque

La méthode d’extension ToPlatformEmbedded se trouve dans la bibliothèque de classes .NET MAUI que vous avez créée précédemment. Par conséquent, votre projet d’application native doit inclure une référence à ce projet.

Remarque

La ToPlatformEmbedded méthode d’extension se trouve dans l’espace Microsoft.Maui.Controls.Embedding de noms. Par conséquent, votre projet d’application native doit inclure une using instruction pour cet espace de noms.

L’objet View peut ensuite être ajouté à une disposition dans votre application native :

rootLayout.AddView(nativeView, new LinearLayout.LayoutParams(MatchParent, WrapContent));

Sur iOS et Mac Catalyst, la méthode d’extension ToPlatformEmbedded convertit le contrôle .NET MAUI en objet UIView :

var mauiView = new MyMauiContent();
UIView nativeView = mauiView.ToPlatformEmbedded(context);
nativeView.WidthAnchor.ConstraintEqualTo(View.Frame.Width).Active = true;
nativeView.HeightAnchor.ConstraintEqualTo(500).Active = true;

Dans cet exemple, un objet dérivé de ContentView est converti en objet UIView, puis les contraintes de largeur et de hauteur sont définies sur cet objet pour permettre l’interaction.

Remarque

La méthode d’extension ToPlatformEmbedded se trouve dans la bibliothèque de classes .NET MAUI que vous avez créée précédemment. Par conséquent, votre projet d’application native doit inclure une référence à ce projet.

L’objet UIView peut ensuite être ajouté à une vue dans votre contrôleur de vue :

stackView.AddArrangedSubView(nativeView);
var mauiView = new MyMauiContent();
UIView nativeView = mauiView.ToPlatformEmbedded(context);

Dans cet exemple, un objet dérivé ContentView est converti en objet UIView.

Remarque

La ToPlatformEmbedded méthode d’extension se trouve dans l’espace Microsoft.Maui.Controls.Embedding de noms. Par conséquent, votre projet d’application native doit inclure une using instruction pour cet espace de noms.

L’objet UIView peut ensuite être ajouté à une vue dans votre contrôleur de vue :

stackView.AddArrangedSubView(new ContainerView(nativeView));

ContainerView est un type personnalisé qui encapsule la vue .NET MAUI pour vous assurer qu’elle est correctement dimensionnée. Pour ce faire, vous IntrinsicContentSize êtes redirigé vers la vue SizeThatFits.NET MAUI :

class ContainerView : UIView
{
    public ContainerView(UIView view)
    {
        AddSubview(view);
    }

    public override CGSize IntrinsicContentSize =>
        SizeThatFits(new CGSize(nfloat.MaxValue, nfloat.MaxValue));

    public override CGSize SizeThatFits(CGSize size) =>
        Subviews?.FirstOrDefault()?.SizeThatFits(size) ?? CGSize.Empty;

    public override void LayoutSubviews()
    {
        if (Subviews?.FirstOrDefault() is { } view)
            view.Frame = Bounds;
    }

    public override void SetNeedsLayout()
    {
        base.SetNeedsLayout();
          InvalidateIntrinsicContentSize();
    }
}

En outre, une méthode d’extension ToUIViewController dans .NET MAUI peut être utilisée pour convertir une page .NET MAUI en un UIViewController:

MyMauiPage myMauiPage = new MyMauiPage();
UIViewController myPageController = myMauiPage.ToUIViewController(context);

Dans cet exemple, un objet dérivé ContentPage est converti en un UIViewController.

Sur Windows, la méthode d’extension ToPlatformEmbedded convertit le contrôle .NET MAUI en objet FrameworkElement :

var mauiView = new MyMauiContent();
FrameworkElement nativeView = myMauiPage.ToPlatformEmbedded(context);

Dans cet exemple, un objet dérivé ContentView est converti en objet FrameworkElement. L’objet FrameworkElement peut ensuite être défini comme contenu d’une page WinUI.

Remarque

La méthode d’extension ToPlatformEmbedded se trouve dans la bibliothèque de classes .NET MAUI que vous avez créée précédemment. Par conséquent, votre projet d’application native doit inclure une référence à ce projet.

Remarque

La ToPlatformEmbedded méthode d’extension se trouve dans l’espace Microsoft.Maui.Controls.Embedding de noms. Par conséquent, votre projet d’application native doit inclure une using instruction pour cet espace de noms.

L’objet FrameworkElement peut ensuite être ajouté à une disposition dans votre application native :

stackPanel.Children.Add(nativeView);

Important

Pour éviter une erreur, le rechargement à chaud XAML doit être désactivé avant d’exécuter une application incorporée native dans la configuration de débogage.

Prise en charge du rechargement à chaud XAML

Le rechargement à chaud XAML n’est pas pris en charge dans les applications incorporées natives. Toutefois, vous pouvez toujours utiliser le rechargement à chaud XAML pour itérer rapidement sur votre interface utilisateur .NET MAUI en créant une application MAUI .NET qui consomme l’interface utilisateur .NET MAUI.

Pour afficher votre interface utilisateur .NET MAUI avec le rechargement à chaud XAML :

  1. Dans le projet contenant votre interface utilisateur .NET MAUI, mettez à jour la classe MauiProgram pour ajouter une surcharge de CreateMauiApp et modifiez la méthode CreateMauiApp existante pour qu’elle accepte un argument générique :

    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp(Action<MauiAppBuilder>? additional = null) =>
            CreateMauiApp<App>(additional);
    
        public static MauiApp CreateMauiApp<TApp>(Action<MauiAppBuilder>? additional = null) where TApp : App
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<TApp>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                });
    
    #if DEBUG
            builder.Logging.AddDebug();
    #endif
            additional?.Invoke(builder);
    
            return builder.Build();
        }
    }
    
  2. Dans le projet contenant votre interface utilisateur .NET MAUI, convertissez chaque dictionnaire de ressources d’un fichier XAML autonome en dictionnaire de ressources s’appuyant sur un fichier code-behind.

  3. Dans le projet contenant votre interface utilisateur .NET MAUI, mettez à jour l’instanciation de votre dictionnaire de ressources, généralement dans App.xaml, afin que la propriété Source spécifie également l’assembly qui contient le dictionnaire de ressources :

    <ResourceDictionary Source="Resources/Styles/Colors.xaml;assembly=NativeEmbeddingDemo" />
    <ResourceDictionary Source="Resources/Styles/Styles.xaml;assembly=NativeEmbeddingDemo" />
    
  4. Créez une application .NET MAUI et ajoutez-la à la solution contenant votre projet d’interface utilisateur .NET MAUI et vos applications incorporées natives.

  5. Dans votre projet d’application .NET MAUI, ajoutez une référence au projet qui contient votre interface utilisateur .NET MAUI.

  6. Dans votre projet d’application .NET MAUI, supprimez les dossiers enfants Ressource dans lesquels la ressource est fournie par votre projet d’interface utilisateur .NET MAUI. Par exemple, si votre projet d’interface utilisateur .NET MAUI contient des dossiers Resources > Polices, Resources > Images et Resources > Styles, ces dossiers doivent être supprimés de l’application .NET MAUI que vous venez de créer. Cela permet à votre application .NET MAUI d’utiliser les ressources du projet contenant votre interface utilisateur .NET MAUI.

  7. Dans votre application .NET MAUI, mettez à jour votre classe App afin qu’elle dérive de la classe App dans votre projet d’interface utilisateur .NET MAUI :

    <myMauiUIProject:App xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                         xmlns:myMauiUIProject="clr-namespace:NativeEmbeddingDemo;assembly=NativeEmbeddingDemo"
                         x:Class="TestHarnessApp.TestApp">
        <myMauiUIProject:App.Resources>
            <!-- App specific resources go here -->
        </myMauiUIProject:App.Resources>
    </myMauiUIProject:App>
    

    Ensuite, mettez à jour le fichier code-behind de la classe App afin qu’elle dérive de la classe App dans votre projet d’interface utilisateur .NET MAUI et charge les ressources XAML de ce projet :

    public partial class TestApp : myMauiUIProject.App
    {
        public TestApp()
        {
            var baseResources = Resources;
            InitializeComponent();
            Resources.MergedDictionaries.Add(baseResources);
            MainPage = new HostPage();
        }
    }
    
  8. Dans votre application .NET MAUI, ajoutez une page qui affiche l’interface utilisateur du projet contenant votre interface utilisateur .NET MAUI :

    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:myMauiUIProject="clr-namespace:NativeEmbeddingDemo;assembly=NativeEmbeddingDemo"
                 x:Class="TestHarnessApp.HostPage"
                 Title="HostPage">
        <myMauiUIProject:MyMauiContent />
    </ContentPage>
    
  9. Dans votre application .NET MAUI, mettez à jour la classe MauiProgram pour qu’elle appelle la méthode CreateMauiApp dans le projet contenant votre interface utilisateur .NET MAUI :

    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp() =>
            NativeEmbeddingDemo.MauiProgram.CreateMauiApp<TestApp>(builder =>
            {
                // Add any test harness configuration such as service stubs or mocks.
            });
    }
    

Vous devriez maintenant être en mesure d’exécuter votre projet d’application .NET MAUI sur chaque plateforme et d’utiliser le rechargement à chaud XAML pour itérer sur votre interface utilisateur .NET MAUI.

Pour obtenir un exemple de cette approche, consultez l’exemple d’application.