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 en appelant la méthode d’extension UseMauiEmbedding. 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.

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. Modifiez la classe App afin qu’elle ne définit pas la propriété MainPage :

    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.

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 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>

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 mauiContext = 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 mauiContext = 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 mauiContext = 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.

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(mauiContext);

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.

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(mauiContext);
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);

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

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

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(mauiContext);

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.

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.