Freigeben über


Native Einbettung

Beispiel durchsuchen.Durchsuchen Sie das Beispiel

Eine .NET Multiplatform App UI (.NET MAUI)-App umfasst in der Regel Seiten, die Layouts enthalten, wie Grid, und Layouts, die Ansichten enthalten, wie Button. Seiten, Layouts und Ansichten leiten sich alle von Element ab. Die native Einbettung ermöglicht die Verwendung aller .NET MAUI-Steuerelemente, die von Element abgeleitet werden, in .NET for Android-, .NET for iOS-, .NET for Mac Catalyst- und WinUI-nativen Apps.

Das Verfahren zur Verwendung eines .NET MAUI-Steuerelements in einer nativen App ist wie folgt:

  1. Erstellen Sie Erweiterungsmethoden, um Ihre systemeigene eingebettete App zu bootstrapen. Weitere Informationen finden Sie unter Erstellen von Erweiterungsmethoden.
  2. Erstellen Sie ein einzelnes .NET MAUI-Projekt, das Ihre .NET MAUI-Benutzeroberfläche und alle Abhängigkeiten enthält. Weitere Informationen finden Sie unter Erstellen eines einzelnen .NET MAUI-Projekts.
  3. Erstellen Sie eine systemeigene App und aktivieren Sie die .NET MAUI-Unterstützung darin. Weitere Informationen finden Sie unter Aktivieren der .NET MAUI-Unterstützung.
  4. Initialisieren Sie .NET MAUI in Ihrem systemeigenen App-Projekt. Weitere Informationen finden Sie unter .NET MAUI initialisieren.
  5. Erstellen Sie die .NET MAUI-Benutzeroberfläche und konvertieren Sie sie mit der Erweiterungsmethode ToPlatformEmbedding in den entsprechenden systemeigenen Typ. Weitere Informationen finden Sie unter Verwenden von .NET MAUI-Steuerelementen.
  1. Erstellen Sie ein einzelnes .NET MAUI-Projekt, das Ihre .NET MAUI-Benutzeroberfläche und alle Abhängigkeiten enthält. Weitere Informationen finden Sie unter Erstellen eines einzelnen .NET MAUI-Projekts.
  2. Erstellen Sie eine systemeigene App und aktivieren Sie die .NET MAUI-Unterstützung darin. Weitere Informationen finden Sie unter Aktivieren der .NET MAUI-Unterstützung.
  3. Initialisieren Sie .NET MAUI in Ihrem systemeigenen App-Projekt. Weitere Informationen finden Sie unter .NET MAUI initialisieren.
  4. Erstellen Sie die .NET MAUI-Benutzeroberfläche und konvertieren Sie sie mit der Erweiterungsmethode ToPlatformEmbedding in den entsprechenden systemeigenen Typ. Weitere Informationen finden Sie unter Verwenden von .NET MAUI-Steuerelementen.

Hinweis

Bei Verwendung der nativen Einbettung funktioniert die Datenbindungsmaschine von .NET MAUI weiterhin. Die Seitennavigation muss jedoch über die native Navigations-API erfolgen.

Erstellen von Erweiterungsmethoden

Bevor Sie eine systemeigene App erstellen, die .NET MAUI-Steuerelemente verwendet, sollten Sie zuerst ein .NET MAUI-Klassenbibliotheksprojekt erstellen und den Ordner Plattformen und die Class1-Klasse daraus löschen. Fügen Sie dann eine Klasse mit dem Namen EmbeddedExtensions hinzu, die den folgenden Code enthält:

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

Diese Erweiterungsmethoden befinden sich im Microsoft.Maui.Controls-Namespace und werden verwendet, um Ihre systemeigene eingebettete App auf jeder Plattform zu bootstrapen. Die Erweiterungsmethoden verweisen auf die Typen EmbeddedPlatformApplication, EmbeddedWindowHandler und EmbeddedWindowProvider, die Sie auch dem .NET MAUI-Bibliotheksprojekt hinzufügen müssen.

Der folgende Code zeigt die EmbeddedPlatformApplication-Klasse, die dem gleichen .NET MAUI-Bibliotheksprojekt wie die EmbeddedExtensions-Klasse hinzugefügt werden soll:

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

Der folgende Code zeigt die EmbeddedWindowHandler-Klasse, die dem gleichen .NET MAUI-Bibliotheksprojekt wie die EmbeddedExtensions-Klasse hinzugefügt werden soll:

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

Der folgende Code zeigt die EmbeddedWindowProvider-Klasse, die dem gleichen .NET MAUI-Bibliotheksprojekt wie die EmbeddedExtensions-Klasse hinzugefügt werden soll:

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

Erstellen eines .NET MAUI-Einzelprojekts

Bevor Sie eine systemeigene App erstellen, die .NET MAUI-Steuerelemente verwendet, sollten Sie derselben Lösung wie das zuvor erstellte .NET MAUI-Klassenbibliotheksprojekt ein .NET MAUI-App-Projekt hinzufügen. Das .NET MAUI-App-Projekt speichert die Benutzeroberfläche, die Sie in Ihrer nativen eingebetteten App erneut verwenden möchten. Führen Sie nach dem Hinzufügen eines neuen .NET MAUI-App-Projekts zur Lösung die folgenden Schritte aus:

  1. Löschen Sie den Ordner Eigenschaften aus dem Projekt.

  2. Löschen Sie den Ordner Platforms aus dem Projekt.

  3. Löschen Sie den Ordner Resources/AppIcon aus dem Projekt.

  4. Löschen Sie den Ordner Resources/raw aus dem Projekt.

  5. Löschen Sie den Ordner Resources/Splash aus dem Projekt.

  6. Löschen Sie die AppShell-Klasse aus dem Projekt.

  7. Stellen Sie sicher, dass die Klasse die App MainPage Eigenschaft nicht festgelegt oder die CreateWindow Methode überschreibt:

    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
        }
    }
    
  8. Löschen Sie die MainPage-Klasse aus dem Projekt.

  9. Ändern Sie die Projektdatei so, dass die $(TargetFramework)-Buildeigenschaft auf net8.0 festgelegt ist und die $(OutputType)-Buildeigenschaft entfernt wird:

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

    Wichtig

    Stellen Sie sicher, dass Sie die Buildeigenschaft $(TargetFramework) und nicht die Buildeigenschaft $(TargetFrameworks) festlegen.

  10. Ändern Sie die CreateMauiApp-Methode in der MauiProgram-Klasse so, dass sie ein optionales Action<MauiAppBuilder>-Argument akzeptiert, das aufgerufen wird, bevor die Methode zurückgegeben wird:

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

An diesem Punkt sollten Sie die erforderliche .NET MAUI-Benutzeroberfläche zum Projekt hinzufügen, einschließlich aller Abhängigkeiten und Ressourcen, und stellen Sie sicher, dass das Projekt ordnungsgemäß erstellt wird.

Erstellen eines .NET MAUI-Einzelprojekts

Bevor Sie eine systemeigene App erstellen, die .NET MAUI-Steuerelemente verwendet, sollten Sie derselben Lösung wie das zuvor erstellte .NET MAUI-Klassenbibliotheksprojekt ein .NET MAUI-App-Projekt hinzufügen. Das .NET MAUI-App-Projekt speichert die Benutzeroberfläche, die Sie in Ihrer nativen eingebetteten App erneut verwenden möchten. Führen Sie nach dem Hinzufügen eines neuen .NET MAUI-App-Projekts zur Lösung die folgenden Schritte aus:

  1. Löschen Sie den Ordner Eigenschaften aus dem Projekt.

  2. Löschen Sie den Ordner Platforms aus dem Projekt.

  3. Löschen Sie den Ordner Resources/AppIcon aus dem Projekt.

  4. Löschen Sie den Ordner Resources/raw aus dem Projekt.

  5. Löschen Sie den Ordner Resources/Splash aus dem Projekt.

  6. Löschen Sie die AppShell-Klasse aus dem Projekt.

  7. Stellen Sie sicher, dass die Klasse die App MainPage Eigenschaft nicht festgelegt oder die CreateWindow Methode überschreibt:

    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
        }
    }
    
  8. Löschen Sie die MainPage-Klasse aus dem Projekt.

  9. Ändern Sie die Projektdatei so, dass die $(TargetFramework)-Buildeigenschaft auf net9.0 festgelegt ist und die $(OutputType)-Buildeigenschaft entfernt wird:

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

    Wichtig

    Stellen Sie sicher, dass Sie die Buildeigenschaft $(TargetFramework) und nicht die Buildeigenschaft $(TargetFrameworks) festlegen.

  10. Ändern Sie in der MauiProgram Klasse die CreateMauiApp Methode, um ein TApp generisches Argument zu akzeptieren, und akzeptieren Sie ein optionales Action<MauiAppBuilder> Argument, das aufgerufen wird, bevor die Methode zurückgegeben wird. Ändern Sie außerdem den Anruf von 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. Fügen Sie in der MauiProgram Klasse eine CreateMauiApp Überladung hinzu, die ein optionales Action<MauiAppBuilder> Argument akzeptiert:

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

Anschließend sollten Sie die erforderliche .NET MAUI-Benutzeroberfläche dem Projekt hinzufügen, einschließlich aller Abhängigkeiten und Ressourcen, und stellen Sie sicher, dass das Projekt ordnungsgemäß erstellt wird.

Aktivieren der .NET MAUI-Unterstützung

Um .NET MAUI-Steuerelemente zu nutzen, die von Element in einer .NET for Android-, .NET for iOS-, .NET for Mac Catalyst- oder WinUI-App abgeleitet werden, sollten Sie Ihr systemeigenes App-Projekt zur gleichen Lösung wie das zuvor erstellte .NET MAUI-Klassenbibliotheksprojekt hinzufügen. Anschließend sollten Sie die .NET MAUI-Unterstützung in der Projektdatei Ihrer nativen App aktivieren, indem Sie die $(UseMaui)- und $(MauiEnablePlatformUsings)-Buildeigenschaften im ersten <PropertyGroup>-Knoten in der Projektdatei auf true festlegen:

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

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

Für .NET for Mac Catalyst-Apps müssen Sie auch die $(SupportedOSPlatformVersion)-Buildeigenschaft auf mindestens 14.0 festlegen:

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

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

Für .NET für Mac Catalyst-Apps müssen Sie auch die $(SupportedOSPlatformVersion) Buildeigenschaft auf mindestens 15.0 festlegen:

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

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

Für WinUI-Apps müssen Sie auch die $(EnableDefaultXamlItems)-Buildeigenschaft auf false festlegen:

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

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

Dadurch wird verhindert, dass Sie Build-Fehler erhalten, weil die Methode InitializeComponent bereits definiert ist.

Fügen Sie dann $(PackageReference)-Buildelemente zur Projektdatei für die Microsoft.Maui.Controls- und Microsoft.Maui.Controls.Compatiblity-NuGet-Pakete hinzu:

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

Fügen Sie dann der Projektdatei für das Microsoft.Maui.Controls NuGet-Paket Buildelemente hinzu$(PackageReference):

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

Initialisieren von .NET MAUI

.NET MAUI muss initialisiert werden, bevor ein natives App-Projekt ein .NET MAUI-Steuerelement konstruieren kann. Die Auswahl, wann sie initialisiert werden soll, hängt in erster Linie davon ab, wann sie in Ihrem App-Flow am passendsten ist – sie kann beim Start oder direkt vor dem Erstellen eines .NET MAUI-Steuerelements ausgeführt werden. Der hier beschriebene Ansatz besteht darin, .NET MAUI zu initialisieren, wenn die anfängliche Benutzeroberfläche der App erstellt wird.

In der Regel lautet das Muster für die Initialisierung von .NET MAUI in einem systemeigenen App-Projekt wie folgt:

  • Erstellen eines MauiApp-Objekts
  • Erstellen Sie ein MauiContext-Objekt aus dem MauiApp-Objekt. Das MauiContext Objekt wird verwendet, um eine systemeigene Ansicht aus der .NET MAUI-Ansicht abzurufen.

Unter Android ist die OnCreate-Überschreibung in der MainActivity-Klasse normalerweise der Ort, an dem Aufgaben im Zusammenhang mit dem App-Start ausgeführt werden. Das folgende Codebeispiel zeigt die Initialisierung von .NET MAUI in der Klasse 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

        ...              
    }
}

Unter iOS und Mac Catalyst sollte die Klasse AppDelegate so geändert werden, dass sie true für die Außerkraftsetzung von FinishedLaunching zurück gibt:

namespace MyNativeEmbeddedApp.iOS;

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

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

Die Methode WillConnect in der Klasse SceneDelegate sollte dann geändert werden, um Ihren Haupt-View Controller zu erstellen und als Ansicht von UINavigationController festzulegen:

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

    ...
}

Öffnen Sie dann im XML-Editor die Datei Info.plist, und fügen Sie am Ende der Datei den folgenden XML-Code hinzu:

<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 kann dann in der ViewDidLoad-Methode im Hauptansichtscontroller initialisiert werden:

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

        ...
    }
}

Unter Windows ist die MainWindow-Klasse in der Regel der Ort, an dem auf die Benutzeroberfläche bezogene Startaufgaben der App ausgeführt werden:

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

        ...
    }
}

In diesem Beispiel wird das MauiApp-Objekt mithilfe der verzögerten Initialisierung erstellt. Die UseMauiEmbedding-Erweiterungsmethode wird für das MauiAppBuilder-Objekt aufgerufen. Daher sollte Ihr systemeigenes App-Projekt einen Verweis auf das .NET MAUI-Klassenbibliotheksprojekt enthalten, das Sie erstellt haben, das diese Erweiterungsmethode enthält. Anschließend wird ein MauiContext-Objekt aus dem MauiApp-Objekt erstellt, wobei bool bestimmt, wo sich der Kontext befindet. Das MauiContext-Objekt wird bei der Konvertierung von .NET MAUI-Steuerelementen in native Typen verwendet.

Das Einbetten kann in einem App-Kontext oder einem Fensterkontext ausgeführt werden, aber für maximale .NET MAUI-Kompatibilität sollte es in einem Fensterkontext ausgeführt werden.

App-Kontext

Systemeigene Einbettung kann in einem App-Kontext ausgeführt werden, in dem die systemeigene App kein Wissen über ein Fenster hat. Bei diesem Ansatz erfordert die native Einbettungsinitialisierung Folgendes:

  • Erstellen eines MauiApp-Objekts
  • Erstellen Sie ein MauiContext-Objekt aus dem MauiApp-Objekt. Das MauiContext Objekt wird verwendet, um eine systemeigene Ansicht aus der .NET MAUI-Ansicht abzurufen.

Das folgende Beispiel zeigt diesen Ansatz:

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

Anschließend kann eine .NET MAUI-Ansicht erstellt und in eine systemeigene Ansicht mit der ToPlatformEmbedded Erweiterungsmethode konvertiert werden, die das MauiContext Objekt als Argument erfordert.

Dieser Ansatz eignet sich für Szenarien, in denen eine systemeigene App eine einfache .NET MAUI-Benutzeroberfläche einbetten muss, aber keinen Zugriff auf alle .NET MAUI-Features erfordert. Der Nachteil dieses Ansatzes besteht darin, dass Tools wie hot reload und einige .NET MAUI-Features nicht funktionieren.

Tipp

Das Erstellen eines MauiApp Objekts jedes Mal, wenn eine .NET MAUI-Ansicht als systemeigene Ansicht eingebettet ist, wird nicht empfohlen. Dies kann problematisch sein, wenn eingebettete Ansichten auf die Application.Current Eigenschaft zugreifen. Stattdessen kann das MauiApp Objekt als freigegebene, statische Instanz erstellt werden:

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

Mit diesem Ansatz können Sie das MauiApp Objekt frühzeitig in Ihrem App-Lebenszyklus instanziieren, um zu vermeiden, dass beim ersten Einbetten einer .NET MAUI-Ansicht in Ihre App eine geringe Verzögerung auftritt.

Unter Android stellt ein Fragment einen Teil der Benutzeroberfläche innerhalb einer Aktivität dar. Im folgenden Codebeispiel wird .NET MAUI in einem Fragment initialisiert:

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

        ...
    }
}

Unter iOS und Mac Catalyst sollte die Klasse AppDelegate so geändert werden, dass sie true für die Außerkraftsetzung von FinishedLaunching zurück gibt:

namespace MyNativeEmbeddedApp.iOS;

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

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

Die Methode WillConnect in der Klasse SceneDelegate sollte dann geändert werden, um Ihren Haupt-View Controller zu erstellen und als Ansicht von UINavigationController festzulegen:

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

    ...
}

Öffnen Sie dann im XML-Editor die Datei Info.plist, und fügen Sie am Ende der Datei den folgenden XML-Code hinzu:

<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 kann dann in der ViewDidLoad-Methode im Hauptansichtscontroller initialisiert werden:

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

        ...
    }
}

Unter Windows ist die MainWindow-Klasse in der Regel der Ort, an dem auf die Benutzeroberfläche bezogene Startaufgaben der App ausgeführt werden:

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

        ...
    }
}

In diesem Beispiel wird das MauiApp Objekt als freigegebene, statische Instanz erstellt. Wenn dieses Objekt erstellt wird, wird aufgerufen, MauiProgram.CreateMauiApp wodurch wiederum die UseMauiEmbedding Erweiterungsmethode für das MauiAppBuilder Objekt aufgerufen wird. Daher sollte Ihr systemeigenes App-Projekt einen Verweis auf das .NET MAUI-Klassenbibliotheksprojekt enthalten, das Ihre MauiProgram Klasse und Ihre .NET MAUI-Benutzeroberfläche enthält. Anschließend wird ein MauiContext Objekt aus dem MauiApp Objekt erstellt, das auf das MauiApp Objekt festgelegt ist. Das MauiContext-Objekt wird bei der Konvertierung von .NET MAUI-Steuerelementen in native Typen verwendet.

Fensterkontext

Systemeigene Einbettung kann in einem Fensterkontext ausgeführt werden, in dem die systemeigene App über Kenntnisse eines Fensters verfügt. In einigen Szenarien erfordern .NET MAUI-Ansichten Zugriff auf ein Fenster, um ordnungsgemäß zu funktionieren. Adaptive Trigger erfordern beispielsweise Zugriff auf das Fenster einer Ansicht, und wenn kein Fenster vorhanden ist, funktionieren sie nicht.

Bei diesem Ansatz erfordert die native Einbettungsinitialisierung Folgendes:

  • Erstellen eines MauiApp-Objekts
  • Erstellen Sie ein MauiContext Objekt mit der CreateEmbeddedWindowContext Methode. Das MauiContext Objekt wird verwendet, um eine systemeigene Ansicht aus der .NET MAUI-Ansicht abzurufen.

Die CreateEmbeddedWindowContext Methode erstellt einen Fensterkontext, der ein systemeigenes Fenster mit einem .NET MAUI-Fenster verknüpft:

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

Anschließend kann eine .NET MAUI-Ansicht erstellt und in eine systemeigene Ansicht mit der ToPlatformEmbedded Erweiterungsmethode konvertiert werden, die das MauiContext Objekt als Argument erfordert.

Hinweis

Die ToPlatformEmbedded Erweiterungsmethode verfügt über eine Überladung, die einem eingebetteten Fenster eine .NET MAUI-Ansicht hinzufügt.

Der Vorteil dieses Ansatzes besteht darin, dass ein einzelnes .NET MAUI-Fenster für jedes systemeigene Fenster vorhanden ist, fensterbezogene APIs ordnungsgemäß funktionieren und Tools wie hot reload funktionieren ordnungsgemäß.

Tipp

Das Erstellen eines MauiApp Objekts jedes Mal, wenn eine .NET MAUI-Ansicht als systemeigene Ansicht eingebettet ist, wird nicht empfohlen. Dies kann problematisch sein, wenn eingebettete Ansichten auf die Application.Current Eigenschaft zugreifen. Stattdessen kann das MauiApp Objekt als freigegebene, statische Instanz erstellt werden:

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

Mit diesem Ansatz können Sie das MauiApp Objekt frühzeitig in Ihrem App-Lebenszyklus instanziieren, um zu vermeiden, dass beim ersten Einbetten einer .NET MAUI-Ansicht in Ihre App eine geringe Verzögerung auftritt.

Unter Android stellt ein Fragment einen Teil der Benutzeroberfläche innerhalb einer Aktivität dar. Im folgenden Codebeispiel wird .NET MAUI in einem Fragment initialisiert:

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;

        ...
    }
}

Unter iOS und Mac Catalyst sollte die Klasse AppDelegate so geändert werden, dass sie true für die Außerkraftsetzung von FinishedLaunching zurück gibt:

namespace MyNativeEmbeddedApp.iOS;

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

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

Die Methode WillConnect in der Klasse SceneDelegate sollte dann geändert werden, um Ihren Haupt-View Controller zu erstellen und als Ansicht von UINavigationController festzulegen:

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

    ...
}

Öffnen Sie dann im XML-Editor die Datei Info.plist, und fügen Sie am Ende der Datei den folgenden XML-Code hinzu:

<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 kann dann in der ViewDidLoad-Methode im Hauptansichtscontroller initialisiert werden:

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;

        ...
    }
}

Unter Windows ist die MainWindow-Klasse in der Regel der Ort, an dem auf die Benutzeroberfläche bezogene Startaufgaben der App ausgeführt werden:

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;

        ...
    }
}

In diesem Beispiel wird das MauiApp Objekt als freigegebene, statische Instanz erstellt. Wenn dieses Objekt erstellt wird, wird aufgerufen, MauiProgram.CreateMauiApp wodurch wiederum die UseMauiEmbedding Erweiterungsmethode für das MauiAppBuilder Objekt aufgerufen wird. Daher sollte Ihr systemeigenes App-Projekt einen Verweis auf das .NET MAUI-Klassenbibliotheksprojekt enthalten, das Ihre MauiProgram Klasse und Ihre .NET MAUI-Benutzeroberfläche enthält. Anschließend wird ein MauiContext Objekt mit der CreateEmbeddedWindowContext Methode erstellt, die auf das Fenster festgelegt ist. Das MauiContext-Objekt wird bei der Konvertierung von .NET MAUI-Steuerelementen in native Typen verwendet.

Verwenden von .NET MAUI-Steuerelementen

Nachdem .NET MAUI in Ihrer nativen App initialisiert wurde, können Sie die .NET MAUI-Benutzeroberfläche zum Layout Ihrer nativen App hinzufügen. Dies kann erreicht werden, indem eine Instanz der Benutzeroberfläche erstellt und mit der Erweiterungsmethode ToPlatformEmbedded in den entsprechenden nativen Typ konvertiert wird.

Unter Android konvertiert die ToPlatformEmbedded-Erweiterungsmethode das .NET MAUI-Steuerelement in ein Android-View-Objekt:

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

In diesem Beispiel wird ein ContentView-abgeleitetes Objekt in ein Android View-Objekt umgewandelt.

Hinweis

Die Erweiterungsmethode ToPlatformEmbedded befindet sich in der .NET MAUI-Klassenbibliothek, die Sie zuvor erstellt haben. Daher sollte Ihr systemeigenes App-Projekt einen Verweis auf dieses Projekt enthalten.

Hinweis

Die ToPlatformEmbedded Erweiterungsmethode befindet sich im Microsoft.Maui.Controls.Embedding Namespace. Daher sollte Ihr systemeigenes App-Projekt eine using Anweisung für diesen Namespace enthalten.

Das View-Objekt kann dann einem Layout in Ihrer nativen App hinzugefügt werden:

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

Unter iOS und Mac Catalyst konvertiert die Erweiterungsmethode ToPlatformEmbedded das .NET MAUI-Steuerelement in ein UIView-Objekt:

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

In diesem Beispiel wird ein von ContentView abgeleitetes Objekt in ein UIView-Objekt konvertiert. Anschließend werden die Einschränkungen für Breite und Höhe festgelegt, um die Interaktion zu ermöglichen.

Hinweis

Die Erweiterungsmethode ToPlatformEmbedded befindet sich in der .NET MAUI-Klassenbibliothek, die Sie zuvor erstellt haben. Daher sollte Ihr systemeigenes App-Projekt einen Verweis auf dieses Projekt enthalten.

Das UIView-Objekt kann dann zu einer Ansicht im Ansichtscontroller hinzugefügt werden:

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

In diesem Beispiel wird ein ContentView-abgeleitetes Objekt in ein UIView-Objekt umgewandelt.

Hinweis

Die ToPlatformEmbedded Erweiterungsmethode befindet sich im Microsoft.Maui.Controls.Embedding Namespace. Daher sollte Ihr systemeigenes App-Projekt eine using Anweisung für diesen Namespace enthalten.

Das UIView-Objekt kann dann zu einer Ansicht im Ansichtscontroller hinzugefügt werden:

stackView.AddArrangedSubView(new ContainerView(nativeView));

ContainerView ist ein benutzerdefinierter Typ, der die .NET MAUI-Ansicht umschließt, um sicherzustellen, dass die Größe korrekt ist. Dies wird erreicht, indem die .NET MAUI-Ansicht SizeThatFitsumgeleitet IntrinsicContentSize wird:

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

Darüber hinaus kann eine ToUIViewController Erweiterungsmethode in .NET MAUI verwendet werden, um eine .NET MAUI-Seite in eine UIViewController:

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

In diesem Beispiel wird ein ContentPage-abgeleitetes Objekt in ein UIViewController umgewandelt.

Unter Windows konvertiert die ToPlatformEmbedded-Erweiterungsmethode das .NET MAUI-Steuerelement in ein FrameworkElement-Objekt:

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

In diesem Beispiel wird ein ContentView-abgeleitetes Objekt in ein FrameworkElement-Objekt umgewandelt. Das FrameworkElement-Objekt kann dann als Inhalt einer WinUI-Seite festgelegt werden.

Hinweis

Die Erweiterungsmethode ToPlatformEmbedded befindet sich in der .NET MAUI-Klassenbibliothek, die Sie zuvor erstellt haben. Daher sollte Ihr systemeigenes App-Projekt einen Verweis auf dieses Projekt enthalten.

Hinweis

Die ToPlatformEmbedded Erweiterungsmethode befindet sich im Microsoft.Maui.Controls.Embedding Namespace. Daher sollte Ihr systemeigenes App-Projekt eine using Anweisung für diesen Namespace enthalten.

Das FrameworkElement-Objekt kann dann einem Layout in Ihrer nativen App hinzugefügt werden:

stackPanel.Children.Add(nativeView);

Wichtig

Um einen Fehler zu vermeiden, sollte das erneute Laden von XAML deaktiviert werden, bevor eine native eingebettete App in der Debugkonfiguration ausgeführt wird.

XAML Hot Reload unterstützen

XAML Hot Reload wird in nativen eingebetteten Apps nicht unterstützt. Sie können jedoch weiterhin XAML Hot Reload verwenden, um Ihre .NET MAUI-Benutzeroberfläche schnell zu iterieren, indem Sie eine .NET MAUI-App erstellen, die die .NET MAUI-Benutzeroberfläche verwendet.

So zeigen Sie Ihre .NET MAUI-Benutzeroberfläche mit XAML Hot Reload an:

  1. Aktualisieren Sie im Projekt mit Ihrer .NET MAUI-Benutzeroberfläche die MauiProgram-Klasse, um eine CreateMauiApp-Überladung hinzuzufügen, und ändern Sie die vorhandene CreateMauiApp-Methode so, dass ein generisches Argument akzeptiert wird:

    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. Konvertieren Sie im Projekt mit Ihrer .NET MAUI-Benutzeroberfläche jedes Ressourcenverzeichnis aus einer eigenständigen XAML-Datei in ein Ressourcenverzeichnis, das von einer CodeBehind-Datei unterstützt wird.

  3. Aktualisieren Sie im Projekt mit Ihrer .NET MAUI-Benutzeroberfläche die Instanziierung des Ressourcenverzeichnisses, in der Regel in App.xaml, sodass die Source-Eigenschaft auch die Assembly angibt, die das Ressourcenverzeichnis enthält:

    <ResourceDictionary Source="Resources/Styles/Colors.xaml;assembly=NativeEmbeddingDemo" />
    <ResourceDictionary Source="Resources/Styles/Styles.xaml;assembly=NativeEmbeddingDemo" />
    
  4. Erstellen Sie eine neue .NET MAUI-App, und fügen Sie sie der Lösung hinzu, die das Projekt mit Ihrer .NET MAUI-Benutzeroberfläche und Ihre nativen eingebetteten Apps enthält.

  5. Fügen Sie in Ihrem .NET MAUI-App-Projekt einen Verweis auf das Projekt hinzu, das Ihre .NET MAUI-Benutzeroberfläche enthält.

  6. Löschen Sie in Ihrem .NET MAUI-App-Projekt alle untergeordneten Resource-Ordner, in denen die Ressource vom Projekt mit Ihrer .NET MAUI-Benutzeroberfläche bereitgestellt wird. Wenn das Projekt mit Ihrer .NET MAUI-Benutzeroberfläche beispielsweise die Ordner Resources > Fonts, Resources > Images und Resources > Styles enthält, sollten diese Ordner aus der soeben erstellten .NET MAUI-App gelöscht werden. Auf diese Weise kann Ihre .NET MAUI-App die Ressourcen aus dem Projekt mit Ihrer .NET MAUI-Benutzeroberfläche nutzen.

  7. Aktualisieren Sie in Ihrer .NET MAUI-App Ihre App-Klasse so, dass sie von der App-Klasse im Projekt mit Ihrer .NET MAUI-Benutzeroberfläche abgeleitet wird:

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

    Aktualisieren Sie dann die CodeBehind-Datei für die App-Klasse, sodass sie von der App-Klasse im Projekt mit Ihrer .NET MAUI-Benutzeroberfläche abgeleitet wird und alle XAML-Ressourcen aus diesem Projekt lädt:

    public partial class TestApp : myMauiUIProject.App
    {
        public TestApp()
        {
            var baseResources = Resources;
            InitializeComponent();
            Resources.MergedDictionaries.Add(baseResources);
            MainPage = new HostPage();
        }
    }
    
  8. Fügen Sie in Ihrer .NET MAUI-App eine Seite hinzu, auf der die Benutzeroberfläche aus dem Projekt mit ihrer .NET MAUI-Benutzeroberfläche angezeigt wird:

    <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. Aktualisieren Sie in Ihrer .NET MAUI-App die MauiProgram-Klasse, um die CreateMauiApp-Methode im Projekt mit Ihrer .NET MAUI-Benutzeroberfläche aufzurufen:

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

Sie sollten nun in der Lage sein, Ihr .NET MAUI-App-Projekt auf jeder Plattform auszuführen und XAML Hot Reload zum Iterieren Ihrer .NET MAUI-Benutzeroberfläche zu verwenden.

Ein Beispiel für diesen Ansatz finden Sie in der Beispiel-App.