Condividi tramite


Incorporamento nativo

Sfogliare l'esempio. Esplorare l'esempio

In genere, un'app .NET Multipiattaforma App UI (.NET MAUI) include pagine che contengono layout, ad esempio Grid, e che contengono visualizzazioni, ad esempio Button. Le pagine, i layout e le visualizzazioni derivano tutti da Element. L'incorporamento nativo consente l'uso di tutti i controlli MAUI .NET che derivano da Element da per usare in .NET per Android, .NET per iOS, .NET per Mac Catalyst e app native WinUI.

Il processo per l'utilizzo di un controllo MAUI .NET in un'app nativa è il seguente:

  1. Creare metodi di estensione per eseguire il bootstrap dell'app incorporata nativa. Per altre informazioni, vedere Creare metodi di estensione.
  2. Creare un singolo progetto MAUI .NET che contiene l'interfaccia utente MAUI .NET e tutte le dipendenze. Per altre informazioni, vedere Creare un singolo progetto MAUI .NET.
  3. Creare un'app nativa e abilitare il supporto di .NET MAUI. Per altre informazioni, vedere Abilitare il supporto MAUI di .NET.
  4. Inizializzare .NET MAUI chiamando il UseMauiEmbedding metodo di estensione. Per altre informazioni, vedere Inizializzare .NET MAUI.
  5. Creare l'interfaccia utente MAUI .NET e convertirla nel tipo nativo appropriato con il ToPlatformEmbedding metodo di estensione. Per altre informazioni, vedere Utilizzare controlli MAUI .NET.

Nota

Quando si usa l'incorporamento nativo, il motore di data binding di .NET MAUI funziona ancora. Tuttavia, lo spostamento tra le pagine deve essere eseguito usando l'API di spostamento nativa.

Creare metodi di estensione

Prima di creare un'app nativa che utilizza controlli MAUI .NET, è necessario creare un progetto di libreria di classi MAUI .NET ed eliminare la cartella Platforms e la Class1 classe da essa. Aggiungere quindi una classe denominata EmbeddedExtensions che contiene il codice seguente:

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

Questi metodi di estensione si trovano nello spazio dei Microsoft.Maui.Controls nomi e vengono usati per eseguire il bootstrap dell'app incorporata nativa in ogni piattaforma. I metodi di estensione fanno riferimento EmbeddedPlatformApplicationai tipi , EmbeddedWindowHandlere EmbeddedWindowProvider che è necessario aggiungere anche al progetto di libreria MAUI .NET.

Il codice seguente illustra la EmbeddedPlatformApplication classe , che deve essere aggiunta allo stesso progetto di libreria MAUI .NET della EmbeddedExtensions classe :

#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);
    }
}

Il codice seguente illustra la EmbeddedWindowHandler classe , che deve essere aggiunta allo stesso progetto di libreria MAUI .NET della EmbeddedExtensions classe :

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.");
}

Il codice seguente illustra la EmbeddedWindowProvider classe , che deve essere aggiunta allo stesso progetto di libreria MAUI .NET della EmbeddedExtensions classe :

#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;
}

Creare un singolo progetto MAUI .NET

Prima di creare un'app nativa che utilizza controlli MAUI .NET, è necessario aggiungere un progetto di app MAUI .NET alla stessa soluzione del progetto di libreria di classi MAUI .NET creato in precedenza. Il progetto di app .NET MAUI archivierà l'interfaccia utente che intendi riutilizzare nell'app incorporata nativa. Dopo aver aggiunto un nuovo progetto di app MAUI .NET alla soluzione, seguire questa procedura:

  1. Eliminare la cartella Proprietà dal progetto.

  2. Eliminare la cartella Platforms dal progetto.

  3. Eliminare la cartella Resources/AppIcon dal progetto.

  4. Eliminare la cartella Resources/raw dal progetto.

  5. Eliminare la cartella Resources/Splash dal progetto.

  6. Eliminare la AppShell classe dal progetto.

  7. Modificare la App classe in modo che non imposti la MainPage proprietà :

    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
        }
    }
    
  8. Eliminare la MainPage classe dal progetto.

  9. Modificare il file di progetto in modo che la $(TargetFramework) proprietà di compilazione sia impostata su net8.0e che la $(OutputType) proprietà di compilazione venga rimossa:

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

    Importante

    Assicurarsi di impostare la proprietà di $(TargetFramework) compilazione, non la proprietà di$(TargetFrameworks) compilazione.

  10. Modificare il CreateMauiApp metodo nella MauiProgram classe in modo che accetti un argomento facoltativo richiamato Action<MauiAppBuilder> prima che il metodo restituisca:

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

A questo punto è necessario aggiungere l'interfaccia utente MAUI .NET necessaria al progetto, incluse eventuali dipendenze e risorse, e assicurarsi che il progetto venga compilato correttamente.

Abilitare il supporto DI MAUI per .NET

Per utilizzare i controlli MAUI .NET che derivano da Element in un'app .NET per Android, .NET per iOS, .NET per Mac Catalyst o WinUI, è necessario aggiungere il progetto di app nativa alla stessa soluzione del progetto di libreria di classi .NET MAUI creato in precedenza. È quindi necessario abilitare il supporto MAUI .NET nel file di progetto dell'app nativa impostando le $(UseMaui) proprietà di compilazione e $(MauiEnablePlatformUsings) su true nel primo <PropertyGroup> nodo del file di progetto:

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

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

Per le app .NET per Mac Catalyst, è anche necessario impostare la $(SupportedOSPlatformVersion) proprietà di compilazione su almeno 14.0:

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

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

Per le app WinUI, dovrai anche impostare la proprietà di $(EnableDefaultXamlItems) compilazione su false:

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

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

In questo modo si interrompe la ricezione di errori di compilazione relativi al InitializeComponent metodo già definito.

Aggiungere quindi elementi di compilazione $(PackageReference) al file di progetto per i Microsoft.Maui.Controls pacchetti NuGet e Microsoft.Maui.Controls.Compatiblity :

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

Inizializzare .NET MAUI

.NET MAUI deve essere inizializzato prima che un progetto di app nativa possa costruire un controllo MAUI .NET. La scelta di quando inizializzarla dipende principalmente da quando è più conveniente nel flusso dell'app. È possibile eseguirla all'avvio o subito prima che venga costruito un controllo MAUI .NET. L'approccio descritto di seguito consiste nell'inizializzare .NET MAUI quando viene creata l'interfaccia utente iniziale dell'app.

In genere, il modello per l'inizializzazione di .NET MAUI in un progetto di app nativa è il seguente:

In Android, l'override OnCreate nella MainActivity classe è in genere la posizione in cui eseguire attività correlate all'avvio dell'app. L'esempio di codice seguente mostra l'inizializzazione di .NET MAUI nella MainActivity classe :

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

        ...              
    }
}

In iOS e Mac Catalyst, la AppDelegate classe deve essere modificata in modo da restituire true per l'override 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;
}

Il WillConnect metodo nella SceneDelegate classe deve quindi essere modificato per creare il controller di visualizzazione principale e impostarlo come visualizzazione di 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();
    }

    /// ...
}

Quindi, nell'editor XML aprire il file Info.plist e aggiungere il codice XML seguente alla fine del file:

<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 può quindi essere inizializzato nel ViewDidLoad metodo nel controller di visualizzazione principale:

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

        ...
    }
}

In Windows la MainWindow classe è in genere la posizione in cui eseguire attività di avvio dell'app correlate all'interfaccia utente:

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

        ...
    }
}

In questo esempio l'oggetto viene creato usando l'inizializzazione MauiApp differita. Il UseMauiEmbedding metodo di estensione viene richiamato sull'oggetto MauiAppBuilder . Di conseguenza, il progetto di app nativa deve includere un riferimento al progetto di libreria di classi MAUI .NET creato che contiene questo metodo di estensione. Viene MauiContext quindi creato un oggetto dall'oggetto MauiApp , con un oggetto bool che determina la posizione di ambito del contesto. L'oggetto MauiContext verrà usato durante la conversione dei controlli MAUI .NET in tipi nativi.

Utilizzare controlli MAUI .NET

Dopo l'inizializzazione di .NET MAUI nell'app nativa, è possibile aggiungere l'interfaccia utente MAUI .NET al layout dell'app nativa. A tale scopo, è possibile creare un'istanza dell'interfaccia utente e convertirla nel tipo nativo appropriato con il ToPlatformEmbedded metodo di estensione.

In Android, il ToPlatformEmbedded metodo di estensione converte il controllo MAUI .NET in un oggetto Android View :

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

In questo esempio un ContentViewoggetto derivato da viene convertito in un oggetto Android View .

Nota

Il ToPlatformEmbedded metodo di estensione si trova nella libreria di classi MAUI .NET creata in precedenza. Di conseguenza, il progetto di app nativa deve includere un riferimento a tale progetto.

L'oggetto View può quindi essere aggiunto a un layout nell'app nativa:

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

In iOS e Mac Catalyst il ToPlatformEmbedded metodo di estensione converte il controllo MAUI .NET in un UIView oggetto :

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

In questo esempio un ContentViewoggetto derivato da viene convertito in un UIView oggetto e quindi vengono impostati vincoli di larghezza e altezza per consentire l'interazione.

Nota

Il ToPlatformEmbedded metodo di estensione si trova nella libreria di classi MAUI .NET creata in precedenza. Di conseguenza, il progetto di app nativa deve includere un riferimento a tale progetto.

L'oggetto UIView può quindi essere aggiunto a una visualizzazione nel controller di visualizzazione:

stackView.AddArrangedSubView(nativeView);

È anche possibile usare un ToUIViewController metodo di estensione in .NET MAUI per tentare di convertire una pagina MAUI .NET in :UIViewController

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

In questo esempio un ContentPageoggetto derivato da viene convertito in un oggetto UIViewController.

In Windows il ToPlatformEmbedded metodo di estensione converte il controllo MAUI .NET in un FrameworkElement oggetto :

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

In questo esempio un ContentViewoggetto derivato da viene convertito in un FrameworkElement oggetto . L'oggetto FrameworkElement può quindi essere impostato come contenuto di una pagina WinUI.

L'oggetto FrameworkElement può quindi essere aggiunto a un layout nell'app nativa:

stackPanel.Children.Add(nativeView);

Importante

Per evitare un errore, il ricaricamento rapido XAML deve essere disabilitato prima di eseguire un'app incorporata nativa nella configurazione di debug.

Supporto del ricaricamento rapido XAML

Il ricaricamento rapido XAML non è supportato nelle app incorporate native. Tuttavia, puoi comunque usare il ricaricamento rapido XAML per scorrere rapidamente l'interfaccia utente MAUI di .NET creando un'app MAUI .NET che usa l'interfaccia utente MAUI .NET.

Per visualizzare l'interfaccia utente MAUI .NET con ricaricamento rapido XAML:

  1. Nel progetto contenente l'interfaccia utente MAUI .NET aggiornare la MauiProgram classe per aggiungere un CreateMauiApp overload e modificare il metodo esistente CreateMauiApp per accettare un argomento generico:

    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. Nel progetto contenente l'interfaccia utente MAUI .NET convertire ogni dizionario risorse da un file XAML autonomo in un dizionario risorse supportato da un file code-behind.

  3. Nel progetto contenente l'interfaccia utente MAUI di .NET aggiornare l'istanza del dizionario risorse, in genere in App.xaml, in modo che la Source proprietà specifichi anche l'assembly che contiene il dizionario risorse:

    <ResourceDictionary Source="Resources/Styles/Colors.xaml;assembly=NativeEmbeddingDemo" />
    <ResourceDictionary Source="Resources/Styles/Styles.xaml;assembly=NativeEmbeddingDemo" />
    
  4. Creare una nuova app MAUI .NET e aggiungerla alla soluzione contenente il progetto di interfaccia utente MAUI .NET e le app incorporate native.

  5. Nel progetto di app .NET MAUI aggiungere un riferimento al progetto che contiene l'interfaccia utente MAUI .NET.

  6. Nel progetto di app .NET MAUI eliminare tutte le cartelle figlio della risorsa in cui la risorsa viene fornita dal progetto di interfaccia utente MAUI .NET. Ad esempio, se il progetto dell'interfaccia utente MAUI .NET contiene le cartelle Tipi di carattere risorse>, > Immagini risorse e Stili risorse>, queste cartelle devono essere eliminate dall'app MAUI .NET appena creata. In questo modo l'app MAUI .NET può usare le risorse del progetto contenente l'interfaccia utente MAUI di .NET.

  7. Nell'app .NET MAUI aggiornare la App classe in modo che derivi dalla App classe nel progetto di interfaccia utente MAUI .NET:

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

    Aggiornare quindi il file code-behind per la App classe in modo che derivi dalla App classe nel progetto dell'interfaccia utente MAUI .NET e carichi tutte le risorse XAML da questo progetto:

    public partial class TestApp : myMauiUIProject.App
    {
        public TestApp()
        {
            var baseResources = Resources;
            InitializeComponent();
            Resources.MergedDictionaries.Add(baseResources);
            MainPage = new HostPage();
        }
    }
    
  8. Nell'app .NET MAUI aggiungere una pagina che visualizza l'interfaccia utente dal progetto contenente l'interfaccia utente MAUI .NET:

    <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. Nell'app .NET MAUI aggiornare la MauiProgram classe per chiamare il metodo nel progetto contenente l'interfaccia CreateMauiApp utente MAUI di .NET:

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

A questo ora dovrebbe essere possibile eseguire il progetto di app .NET MAUI in ogni piattaforma e usare il ricaricamento rapido XAML per scorrere l'interfaccia utente MAUI di .NET.

Per un esempio di questo approccio, vedi l'app di esempio.