Udostępnij za pośrednictwem


Osadzanie natywne

Przeglądaj przykład. Przeglądanie przykładu

Zazwyczaj aplikacja interfejsu użytkownika aplikacji wieloplatformowej platformy .NET (.NET MAUI) zawiera strony zawierające układy, takie jak Grid, i zawierające widoki, takie jak Button. Wszystkie strony, układy i widoki pochodzą z elementu Element. Osadzanie natywne umożliwia korzystanie z dowolnych kontrolek MAUI platformy .NET, które pochodzą z Element platformy .NET dla systemów Android, .NET dla systemów iOS, .NET dla komputerów Mac Catalyst i WinUI natywnych.

Proces korzystania z kontrolki MAUI platformy .NET w aplikacji natywnej jest następujący:

  1. Utwórz metody rozszerzenia, aby uruchomić natywną aplikację osadzoną. Aby uzyskać więcej informacji, zobacz Create extension methods (Tworzenie metod rozszerzenia).
  2. Utwórz pojedynczy projekt MAUI platformy .NET, który zawiera interfejs użytkownika .NET MAUI i wszelkie zależności. Aby uzyskać więcej informacji, zobacz Create a .NET MAUI single project (Tworzenie pojedynczego projektu .NET MAUI).
  3. Utwórz aplikację natywną i włącz w niej obsługę interfejsu MAUI platformy .NET. Aby uzyskać więcej informacji, zobacz Włączanie obsługi interfejsu MAUI platformy .NET.
  4. Zainicjuj interfejs MAUI platformy .NET w projekcie aplikacji natywnej. Aby uzyskać więcej informacji, zobacz Inicjowanie interfejsu MAUI platformy .NET.
  5. Utwórz interfejs użytkownika .NET MAUI i przekonwertuj go na odpowiedni typ natywny za ToPlatformEmbedding pomocą metody rozszerzenia. Aby uzyskać więcej informacji, zobacz Korzystanie z kontrolek MAUI platformy .NET.
  1. Utwórz pojedynczy projekt MAUI platformy .NET, który zawiera interfejs użytkownika .NET MAUI i wszelkie zależności. Aby uzyskać więcej informacji, zobacz Create a .NET MAUI single project (Tworzenie pojedynczego projektu .NET MAUI).
  2. Utwórz aplikację natywną i włącz w niej obsługę interfejsu MAUI platformy .NET. Aby uzyskać więcej informacji, zobacz Włączanie obsługi interfejsu MAUI platformy .NET.
  3. Zainicjuj interfejs MAUI platformy .NET w projekcie aplikacji natywnej. Aby uzyskać więcej informacji, zobacz Inicjowanie interfejsu MAUI platformy .NET.
  4. Utwórz interfejs użytkownika .NET MAUI i przekonwertuj go na odpowiedni typ natywny za ToPlatformEmbedding pomocą metody rozszerzenia. Aby uzyskać więcej informacji, zobacz Korzystanie z kontrolek MAUI platformy .NET.

Uwaga

W przypadku korzystania z natywnego osadzania aparat powiązania danych programu .NET MAUI nadal działa. Jednak nawigacja po stronie musi być wykonywana przy użyciu natywnego interfejsu API nawigacji.

Tworzenie metod rozszerzenia

Przed utworzeniem aplikacji natywnej korzystającej z kontrolek MAUI platformy .NET należy najpierw utworzyć projekt biblioteki klas MAUI platformy .NET i usunąć folder Platformy oraz klasę Class1 z niej. Następnie dodaj do niego klasę o nazwie EmbeddedExtensions , która zawiera następujący kod:

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

Te metody rozszerzenia znajdują się w przestrzeni nazw i są używane do uruchamiania natywnej Microsoft.Maui.Controls aplikacji osadzonej na każdej platformie. Metody rozszerzeń odwołują się EmbeddedPlatformApplicationdo , EmbeddedWindowHandleri EmbeddedWindowProvider typów, które należy również dodać do projektu biblioteki .NET MAUI.

Poniższy kod przedstawia klasę EmbeddedPlatformApplication , która powinna zostać dodana do tego samego projektu biblioteki MAUI platformy .NET co EmbeddedExtensions klasa:

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

Poniższy kod przedstawia klasę EmbeddedWindowHandler , która powinna zostać dodana do tego samego projektu biblioteki MAUI platformy .NET co EmbeddedExtensions klasa:

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

Poniższy kod przedstawia klasę EmbeddedWindowProvider , która powinna zostać dodana do tego samego projektu biblioteki MAUI platformy .NET co EmbeddedExtensions klasa:

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

Tworzenie pojedynczego projektu MAUI platformy .NET

Przed utworzeniem aplikacji natywnej, która korzysta z kontrolek MAUI platformy .NET, należy dodać projekt aplikacji .NET MAUI do tego samego rozwiązania co utworzony wcześniej projekt biblioteki klas .NET MAUI. Projekt aplikacji .NET MAUI będzie przechowywać interfejs użytkownika, który zamierzasz ponownie używać w natywnej aplikacji osadzonej. Po dodaniu nowego projektu aplikacji .NET MAUI do rozwiązania wykonaj następujące kroki:

  1. Usuń folder Properties z projektu.

  2. Usuń folder Platformy z projektu.

  3. Usuń folder Resources/AppIcon z projektu.

  4. Usuń folder Resources/raw z projektu.

  5. Usuń folder Resources/Splash z projektu.

  6. Usuń klasę AppShell z projektu.

  7. Upewnij się, App że klasa nie ustawia MainPage właściwości ani nie zastępuje CreateWindow metody :

    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
        }
    }
    
  8. Usuń klasę MainPage z projektu.

  9. Zmodyfikuj plik projektu, aby $(TargetFramework) właściwość kompilacji została ustawiona na net8.0, a właściwość kompilacji została usunięta $(OutputType) :

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

    Ważne

    Upewnij się, że ustawiono właściwość kompilacji $(TargetFramework) , a nie właściwość kompilacji$(TargetFrameworks) .

  10. Zmodyfikuj MauiProgram metodę CreateMauiApp w klasie, aby akceptowała opcjonalny Action<MauiAppBuilder> argument wywoływany przed zwróceniem metody:

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

W tym momencie należy dodać wymagany interfejs użytkownika maui platformy .NET do projektu, w tym wszelkie zależności i zasoby, i upewnić się, że projekt jest kompilowany poprawnie.

Tworzenie pojedynczego projektu MAUI platformy .NET

Przed utworzeniem aplikacji natywnej, która korzysta z kontrolek MAUI platformy .NET, należy dodać projekt aplikacji .NET MAUI do tego samego rozwiązania co utworzony wcześniej projekt biblioteki klas .NET MAUI. Projekt aplikacji .NET MAUI będzie przechowywać interfejs użytkownika, który zamierzasz ponownie używać w natywnej aplikacji osadzonej. Po dodaniu nowego projektu aplikacji .NET MAUI do rozwiązania wykonaj następujące kroki:

  1. Usuń folder Properties z projektu.

  2. Usuń folder Platformy z projektu.

  3. Usuń folder Resources/AppIcon z projektu.

  4. Usuń folder Resources/raw z projektu.

  5. Usuń folder Resources/Splash z projektu.

  6. Usuń klasę AppShell z projektu.

  7. Upewnij się, App że klasa nie ustawia MainPage właściwości ani nie zastępuje CreateWindow metody :

    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
        }
    }
    
  8. Usuń klasę MainPage z projektu.

  9. Zmodyfikuj plik projektu, aby $(TargetFramework) właściwość kompilacji została ustawiona na net9.0, a właściwość kompilacji została usunięta $(OutputType) :

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

    Ważne

    Upewnij się, że ustawiono właściwość kompilacji $(TargetFramework) , a nie właściwość kompilacji$(TargetFrameworks) .

  10. W klasie zmodyfikuj MauiProgram metodę TApp tak, aby akceptowała CreateMauiApp argument ogólny i zaakceptuj opcjonalny Action<MauiAppBuilder> argument wywoływany przed zwróceniem metody. Ponadto zmień wywołanie z UseMauiApp<App> na 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. MauiProgram W klasie dodaj CreateMauiApp przeciążenie, które akceptuje opcjonalny Action<MauiAppBuilder> argument:

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

Następnie należy dodać wymagany interfejs użytkownika .NET MAUI do projektu, w tym wszelkie zależności i zasoby, i upewnić się, że projekt jest kompilowany poprawnie.

Włączanie obsługi interfejsu MAUI platformy .NET

Aby korzystać z kontrolek MAUI platformy .NET, które pochodzą z Element platformy .NET dla systemu Android, .NET dla systemów iOS, .NET dla komputerów Mac Catalyst lub aplikacji WinUI, należy dodać projekt aplikacji natywnej do tego samego rozwiązania co utworzony wcześniej projekt biblioteki klas .NET MAUI. Następnie należy włączyć obsługę .NET MAUI w pliku projektu aplikacji natywnej, ustawiając $(UseMaui) właściwości i $(MauiEnablePlatformUsings) kompilacji na true w pierwszym <PropertyGroup> węźle w pliku projektu:

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

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

W przypadku aplikacji .NET for Mac Catalyst należy również ustawić $(SupportedOSPlatformVersion) właściwość kompilacji na co najmniej 14.0:

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

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

W przypadku aplikacji .NET for Mac Catalyst należy również ustawić właściwość kompilacji $(SupportedOSPlatformVersion) na co najmniej 15.0:

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

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

W przypadku aplikacji WinUI należy również ustawić $(EnableDefaultXamlItems) właściwość build na :false

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

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

Spowoduje to zatrzymanie otrzymywania błędów kompilacji dotyczących już zdefiniowanej InitializeComponent metody.

Następnie dodaj $(PackageReference) elementy kompilacji do pliku projektu dla Microsoft.Maui.Controls pakietów NuGet i Microsoft.Maui.Controls.Compatiblity :

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

Następnie dodaj $(PackageReference) elementy kompilacji do pliku projektu dla Microsoft.Maui.Controls pakietu NuGet:

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

Inicjowanie interfejsu MAUI platformy .NET

Aby projekt aplikacji natywnej mógł utworzyć kontrolkę .NET MAUI, należy zainicjować program .NET MAUI. Wybór, kiedy zainicjować go przede wszystkim zależy od tego, kiedy jest on najbardziej wygodny w przepływie aplikacji — może zostać wykonany podczas uruchamiania lub tuż przed skonstruowaniem kontrolki MAUI platformy .NET. Podejście opisane tutaj polega na zainicjowaniu interfejsu użytkownika platformy .NET MAUI podczas tworzenia początkowego interfejsu użytkownika aplikacji.

Zazwyczaj wzorzec inicjowania interfejsu MAUI platformy .NET w projekcie aplikacji natywnej wygląda następująco:

W systemie Android OnCreate przesłonięcia w MainActivity klasie to zazwyczaj miejsce do wykonywania zadań związanych z uruchamianiem aplikacji. Poniższy przykład kodu przedstawia zainicjowanie interfejsu MainActivity MAUI platformy .NET w klasie:

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

        ...              
    }
}

W systemach iOS i Mac Catalyst należy zmodyfikować klasę w AppDelegate celu zwrócenia true przesłonięcia 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;
}

WillConnect Następnie należy zmodyfikować metodę w SceneDelegate klasie w celu utworzenia głównego kontrolera widoku i ustawić ją jako widok elementu 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();
    }

    ...
}

Następnie w edytorze XML otwórz plik Info.plist i dodaj następujący kod XML na końcu pliku:

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

Program .NET MAUI można następnie zainicjować w metodzie ViewDidLoad w głównym kontrolerze widoku:

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

        ...
    }
}

W systemie Windows MainWindow klasa jest zazwyczaj miejscem do wykonywania zadań uruchamiania aplikacji związanych z interfejsem użytkownika:

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

        ...
    }
}

W tym przykładzie MauiApp obiekt jest tworzony przy użyciu inicjowania z opóźnieniem. Metoda UseMauiEmbedding rozszerzenia jest wywoływana MauiAppBuilder w obiekcie . W związku z tym projekt aplikacji natywnej powinien zawierać odwołanie do utworzonego projektu biblioteki klas MAUI platformy .NET zawierającego tę metodę rozszerzenia. Następnie MauiContext obiekt jest tworzony na podstawie MauiApp obiektu z określeniem bool , gdzie kontekst ma zakres. Obiekt MauiContext będzie używany podczas konwertowania kontrolek MAUI platformy .NET na typy natywne.

Osadzanie można wykonać w kontekście aplikacji lub w kontekście okna, ale w celu zapewnienia maksymalnej zgodności programu MAUI platformy .NET należy wykonać je w kontekście okna.

Kontekst aplikacji

Osadzanie natywne można wykonać w kontekście aplikacji, gdzie aplikacja natywna nie zna okna. W przypadku tego podejścia inicjowanie osadzania natywnego wymaga wykonania następujących czynności:

W poniższym przykładzie przedstawiono to podejście:

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

Następnie można utworzyć i przekonwertować widok MAUI platformy .NET na widok macierzysty za pomocą ToPlatformEmbedded metody rozszerzenia, która wymaga MauiContext obiektu jako argumentu.

Takie podejście jest odpowiednie w scenariuszach, w których aplikacja natywna musi osadzić prosty interfejs użytkownika maui platformy .NET, ale nie wymaga dostępu do wszystkich funkcji maui platformy .NET. Wadą tego podejścia jest to, że narzędzia, takie jak przeładowywanie na gorąco, i niektóre funkcje programu .NET MAUI, nie będą działać.

Napiwek

MauiApp Tworzenie obiektu za każdym razem, gdy widok MAUI platformy .NET jest osadzony jako widok macierzysty, nie jest zalecany. Może to być problematyczne, jeśli widoki osadzone uzyskują dostęp do Application.Current właściwości. MauiApp Zamiast tego obiekt można utworzyć jako udostępnione wystąpienie statyczne:

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

Dzięki temu podejściu MauiApp można utworzyć wystąpienie obiektu na wczesnym etapie cyklu życia aplikacji, aby uniknąć małego opóźnienia podczas pierwszego osadzania widoku MAUI platformy .NET w aplikacji.

W systemie Android fragment reprezentuje część interfejsu użytkownika w ramach działania. Poniższy przykład kodu przedstawia zainicjowanie interfejsu MAUI platformy .NET w fragmencie:

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

        ...
    }
}

W systemach iOS i Mac Catalyst należy zmodyfikować klasę w AppDelegate celu zwrócenia true przesłonięcia 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;
}

WillConnect Następnie należy zmodyfikować metodę w SceneDelegate klasie w celu utworzenia głównego kontrolera widoku i ustawić ją jako widok elementu 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();
    }

    ...
}

Następnie w edytorze XML otwórz plik Info.plist i dodaj następujący kod XML na końcu pliku:

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

Program .NET MAUI można następnie zainicjować w metodzie ViewDidLoad w głównym kontrolerze widoku:

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

        ...
    }
}

W systemie Windows MainWindow klasa jest zazwyczaj miejscem do wykonywania zadań uruchamiania aplikacji związanych z interfejsem użytkownika:

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

        ...
    }
}

W tym przykładzie MauiApp obiekt jest tworzony jako udostępnione wystąpienie statyczne. Po utworzeniu tego obiektu jest wywoływany, MauiProgram.CreateMauiApp który z kolei wywołuje metodę UseMauiEmbedding rozszerzenia w MauiAppBuilder obiekcie. W związku z tym projekt aplikacji natywnej powinien zawierać odwołanie do utworzonego projektu biblioteki klas .NET MAUI zawierającego MauiProgram klasę i interfejs użytkownika maui platformy .NET. Następnie MauiContext obiekt jest tworzony na podstawie MauiApp obiektu, który jest o określonym zakresie do MauiApp obiektu. Obiekt MauiContext będzie używany podczas konwertowania kontrolek MAUI platformy .NET na typy natywne.

Kontekst okna

Osadzanie natywne można wykonać w kontekście okna, w którym aplikacja natywna ma wiedzę na temat okna. W niektórych scenariuszach widoki MAUI platformy .NET wymagają dostępu do okna w celu poprawnego działania. Na przykład wyzwalacze adaptacyjne wymagają dostępu do okna widoku, a jeśli nie ma okna, nie działają.

W przypadku tego podejścia inicjowanie osadzania natywnego wymaga wykonania następujących czynności:

  • Utwórz MauiApp obiekt.
  • MauiContext Utwórz obiekt za pomocą CreateEmbeddedWindowContext metody . Obiekt MauiContext zostanie użyty do uzyskania widoku natywnego z widoku MAUI platformy .NET.

Metoda CreateEmbeddedWindowContext tworzy kontekst okna, który wiąże okno natywne z oknem .NET MAUI:

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

Następnie można utworzyć i przekonwertować widok MAUI platformy .NET na widok macierzysty za pomocą ToPlatformEmbedded metody rozszerzenia, która wymaga MauiContext obiektu jako argumentu.

Uwaga

Metoda ToPlatformEmbedded rozszerzenia ma przeciążenie, które dodaje widok MAUI platformy .NET do okna osadzonego.

Zaletą tego podejścia jest to, że istnieje jedno okno MAUI platformy .NET dla każdego okna natywnego, interfejsy API związane z oknem będą działać poprawnie, a narzędzia, takie jak ponowne ładowanie na gorąco, działa poprawnie.

Napiwek

MauiApp Tworzenie obiektu za każdym razem, gdy widok MAUI platformy .NET jest osadzony jako widok macierzysty, nie jest zalecany. Może to być problematyczne, jeśli widoki osadzone uzyskują dostęp do Application.Current właściwości. MauiApp Zamiast tego obiekt można utworzyć jako udostępnione wystąpienie statyczne:

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

Dzięki temu podejściu MauiApp można utworzyć wystąpienie obiektu na wczesnym etapie cyklu życia aplikacji, aby uniknąć małego opóźnienia podczas pierwszego osadzania widoku MAUI platformy .NET w aplikacji.

W systemie Android fragment reprezentuje część interfejsu użytkownika w ramach działania. Poniższy przykład kodu przedstawia zainicjowanie interfejsu MAUI platformy .NET w fragmencie:

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;

        ...
    }
}

W systemach iOS i Mac Catalyst należy zmodyfikować klasę w AppDelegate celu zwrócenia true przesłonięcia 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;
}

WillConnect Następnie należy zmodyfikować metodę w SceneDelegate klasie w celu utworzenia głównego kontrolera widoku i ustawić ją jako widok elementu 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();
    }

    ...
}

Następnie w edytorze XML otwórz plik Info.plist i dodaj następujący kod XML na końcu pliku:

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

Program .NET MAUI można następnie zainicjować w metodzie ViewDidLoad w głównym kontrolerze widoku:

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;

        ...
    }
}

W systemie Windows MainWindow klasa jest zazwyczaj miejscem do wykonywania zadań uruchamiania aplikacji związanych z interfejsem użytkownika:

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;

        ...
    }
}

W tym przykładzie MauiApp obiekt jest tworzony jako udostępnione wystąpienie statyczne. Po utworzeniu tego obiektu jest wywoływany, MauiProgram.CreateMauiApp który z kolei wywołuje metodę UseMauiEmbedding rozszerzenia w MauiAppBuilder obiekcie. W związku z tym projekt aplikacji natywnej powinien zawierać odwołanie do utworzonego projektu biblioteki klas .NET MAUI zawierającego MauiProgram klasę i interfejs użytkownika maui platformy .NET. Następnie MauiContext obiekt jest tworzony za CreateEmbeddedWindowContext pomocą metody , która jest ograniczona do okna. Obiekt MauiContext będzie używany podczas konwertowania kontrolek MAUI platformy .NET na typy natywne.

Korzystanie z kontrolek MAUI platformy .NET

Po zainicjowaniu interfejsu użytkownika .NET MAUI w aplikacji natywnej możesz dodać interfejs użytkownika maui platformy .NET do układu aplikacji natywnej. Można to osiągnąć, tworząc wystąpienie interfejsu użytkownika i konwertując go na odpowiedni typ natywny za ToPlatformEmbedded pomocą metody rozszerzenia.

W systemie Android ToPlatformEmbedded metoda rozszerzenia konwertuje kontrolkę .NET MAUI na obiekt systemu Android View :

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

W tym przykładzie ContentViewobiekt pochodny jest konwertowany na obiekt systemu Android View .

Uwaga

ToPlatformEmbedded Metoda rozszerzenia znajduje się w utworzonej wcześniej bibliotece klas .NET MAUI. W związku z tym projekt aplikacji natywnej powinien zawierać odwołanie do tego projektu.

Uwaga

Metoda ToPlatformEmbedded rozszerzenia znajduje się w Microsoft.Maui.Controls.Embedding przestrzeni nazw. W związku z tym projekt aplikacji natywnej powinien zawierać instrukcję using dla tej przestrzeni nazw.

Obiekt View można następnie dodać do układu w aplikacji natywnej:

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

W systemach iOS i Mac Catalyst ToPlatformEmbedded metoda rozszerzenia konwertuje kontrolkę UIView .NET MAUI na obiekt:

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

W tym przykładzie obiekt pochodny jest konwertowany na UIView obiekt, ContentViewa następnie ustawiane są na nim ograniczenia szerokości i wysokości, aby umożliwić interakcję.

Uwaga

ToPlatformEmbedded Metoda rozszerzenia znajduje się w utworzonej wcześniej bibliotece klas .NET MAUI. W związku z tym projekt aplikacji natywnej powinien zawierać odwołanie do tego projektu.

Obiekt UIView można następnie dodać do widoku na kontrolerze widoku:

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

W tym przykładzie ContentViewobiekt pochodny jest konwertowany na UIView obiekt.

Uwaga

Metoda ToPlatformEmbedded rozszerzenia znajduje się w Microsoft.Maui.Controls.Embedding przestrzeni nazw. W związku z tym projekt aplikacji natywnej powinien zawierać instrukcję using dla tej przestrzeni nazw.

Obiekt UIView można następnie dodać do widoku na kontrolerze widoku:

stackView.AddArrangedSubView(new ContainerView(nativeView));

ContainerView jest typem niestandardowym, który opakowuje widok MAUI platformy .NET, aby upewnić się, że rozmiar jest poprawny. Jest to osiągane przez przekierowanie IntrinsicContentSize do widoku .NET MAUI:SizeThatFits

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

Ponadto ToUIViewController można użyć metody rozszerzenia w programie .NET MAUI w celu przekonwertowania strony .NET MAUI na :UIViewController

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

W tym przykładzie ContentPageobiekt -pochodny jest konwertowany na UIViewControllerobiekt .

W systemie Windows ToPlatformEmbedded metoda rozszerzenia konwertuje kontrolkę FrameworkElement .NET MAUI na obiekt:

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

W tym przykładzie ContentViewobiekt pochodny jest konwertowany na FrameworkElement obiekt. Następnie FrameworkElement obiekt można ustawić jako zawartość strony WinUI.

Uwaga

ToPlatformEmbedded Metoda rozszerzenia znajduje się w utworzonej wcześniej bibliotece klas .NET MAUI. W związku z tym projekt aplikacji natywnej powinien zawierać odwołanie do tego projektu.

Uwaga

Metoda ToPlatformEmbedded rozszerzenia znajduje się w Microsoft.Maui.Controls.Embedding przestrzeni nazw. W związku z tym projekt aplikacji natywnej powinien zawierać instrukcję using dla tej przestrzeni nazw.

Obiekt FrameworkElement można następnie dodać do układu w aplikacji natywnej:

stackPanel.Children.Add(nativeView);

Ważne

Aby uniknąć wystąpienia błędu, ponowne ładowanie kodu XAML na gorąco powinno zostać wyłączone przed uruchomieniem natywnej osadzonej aplikacji w konfiguracji debugowania.

Obsługa przeładowywania kodu XAML na gorąco

Ponowne ładowanie kodu XAML na gorąco nie jest obsługiwane w natywnych osadzonych aplikacjach. Można jednak nadal używać przeładowywania kodu XAML na gorąco, aby szybko iterować interfejs użytkownika .NET MAUI, tworząc aplikację MAUI platformy .NET, która korzysta z interfejsu użytkownika .NET MAUI.

Aby wyświetlić interfejs użytkownika .NET MAUI z przeładowywaniem kodu XAML na gorąco:

  1. W projekcie zawierającym interfejs użytkownika maui platformy .NET zaktualizuj MauiProgram klasę, aby dodać przeciążenie, i zmodyfikuj istniejącą CreateMauiApp CreateMauiApp metodę tak, aby akceptowała argument ogólny:

    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. W projekcie zawierającym interfejs użytkownika programu .NET MAUI przekonwertuj każdy słownik zasobów z autonomicznego pliku XAML na słownik zasobów, który jest wspierany przez plik z kodem.

  3. W projekcie zawierającym interfejs użytkownika .NET MAUI zaktualizuj wystąpienie słownika zasobów, zazwyczaj w pliku App.xaml, aby Source właściwość określała również zestaw zawierający słownik zasobów:

    <ResourceDictionary Source="Resources/Styles/Colors.xaml;assembly=NativeEmbeddingDemo" />
    <ResourceDictionary Source="Resources/Styles/Styles.xaml;assembly=NativeEmbeddingDemo" />
    
  4. Utwórz nową aplikację .NET MAUI i dodaj ją do rozwiązania zawierającego projekt interfejsu użytkownika maUI platformy .NET i natywne aplikacje osadzone.

  5. W projekcie aplikacji .NET MAUI dodaj odwołanie do projektu zawierającego interfejs użytkownika maUI platformy .NET.

  6. W projekcie aplikacji .NET MAUI usuń wszystkie foldery podrzędne zasobów , w których zasób jest udostępniany przez projekt interfejsu użytkownika programu .NET MAUI. Jeśli na przykład projekt interfejsu użytkownika maui platformy .NET zawiera foldery Zasoby > Czcionki, Obrazy zasobów > i Style zasobów>, te foldery powinny zostać usunięte z właśnie utworzonej aplikacji .NET MAUI. Dzięki temu aplikacja .NET MAUI może korzystać z zasobów z projektu zawierającego interfejs użytkownika maui platformy .NET.

  7. W aplikacji .NET MAUI zaktualizuj App klasę, aby pochodziła z App klasy w projekcie interfejsu użytkownika maui platformy .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>
    

    Następnie zaktualizuj plik za kodem dla App klasy, aby pochodził z App klasy w projekcie interfejsu użytkownika programu .NET MAUI i ładuje wszystkie zasoby XAML z tego projektu:

    public partial class TestApp : myMauiUIProject.App
    {
        public TestApp()
        {
            var baseResources = Resources;
            InitializeComponent();
            Resources.MergedDictionaries.Add(baseResources);
            MainPage = new HostPage();
        }
    }
    
  8. W aplikacji .NET MAUI dodaj stronę wyświetlającą interfejs użytkownika z projektu zawierającego interfejs użytkownika .NET MAUI UI:

    <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. W aplikacji .NET MAUI zaktualizuj klasę MauiProgram , aby wywołać CreateMauiApp metodę w projekcie zawierającym interfejs użytkownika maui .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.
            });
    }
    

Teraz powinno być możliwe uruchomienie projektu aplikacji .NET MAUI na każdej platformie i użycie przeładowywania kodu XAML na gorąco w celu iteracji interfejsu użytkownika maui platformy .NET.

Aby zapoznać się z przykładem tego podejścia, zobacz przykładową aplikację.