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, wywołując metodę UseMauiEmbedding rozszerzenia. 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.

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. Zmodyfikuj klasę App , aby nie ustawiała MainPage właściwości:

    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.

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

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

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

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.

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

Ponadto ToUIViewController metoda rozszerzenia w programie .NET MAUI może służyć do próby przekonwertowania strony .NET MAUI na :UIViewController

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

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

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

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ą CreateMauiAppCreateMauiApp 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ę.