Nativní vkládání
Aplikace .NET Pro víceplatformní aplikace (.NET MAUI) obvykle obsahuje stránky obsahující rozložení, například Grida rozložení, která obsahují zobrazení, například Button. Stránky, rozložení a zobrazení jsou odvozeny od Element. Nativní vkládání umožňuje všechny ovládací prvky .NET MAUI odvozené od Element použití v .NET pro Android, .NET pro iOS, .NET pro Mac Catalyst a nativní aplikace WinUI.
Proces využívání ovládacího prvku .NET MAUI v nativní aplikaci je následující:
- Vytvořte metody rozšíření pro spuštění nativní vložené aplikace. Další informace naleznete v tématu Vytvoření rozšiřujících metod.
- Vytvořte jeden projekt .NET MAUI, který obsahuje uživatelské rozhraní .NET MAUI a všechny závislosti. Další informace najdete v tématu Vytvoření jednoho projektu .NET MAUI.
- Vytvořte nativní aplikaci a povolte v ní podporu .NET MAUI. Další informace najdete v tématu Povolení podpory .NET MAUI.
- Inicializace rozhraní .NET MAUI voláním
UseMauiEmbedding
metody rozšíření. Další informace najdete v tématu Inicializace rozhraní .NET MAUI. - Vytvořte uživatelské rozhraní .NET MAUI a pomocí metody rozšíření ho
ToPlatformEmbedding
převeďte na příslušný nativní typ. Další informace najdete v tématu Využití ovládacích prvků .NET MAUI.
Poznámka:
Při použití nativního vkládání stále funguje modul datových vazeb .NET MAUI. Navigace na stránce se ale musí provádět pomocí nativního navigačního rozhraní API.
Vytvoření rozšiřujících metod
Před vytvořením nativní aplikace, která využívá ovládací prvky .NET MAUI, byste nejprve měli vytvořit projekt knihovny tříd .NET MAUI a odstranit složku Platformy a Class1
třídu z ní. Pak do ní EmbeddedExtensions
přidejte třídu, která obsahuje následující kód:
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>();
}
}
Tyto metody rozšíření jsou v Microsoft.Maui.Controls
oboru názvů a používají se ke spuštění nativní vložené aplikace na každé platformě. Metody rozšíření odkazují EmbeddedPlatformApplication
na , EmbeddedWindowHandler
a EmbeddedWindowProvider
typy, které musíte také přidat do projektu knihovny .NET MAUI.
Následující kód ukazuje EmbeddedPlatformApplication
třídu, která by se měla přidat do stejného projektu knihovny .NET MAUI jako EmbeddedExtensions
třída:
#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);
}
}
Následující kód ukazuje EmbeddedWindowHandler
třídu, která by se měla přidat do stejného projektu knihovny .NET MAUI jako EmbeddedExtensions
třída:
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.");
}
Následující kód ukazuje EmbeddedWindowProvider
třídu, která by se měla přidat do stejného projektu knihovny .NET MAUI jako EmbeddedExtensions
třída:
#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;
}
Vytvoření jednoho projektu .NET MAUI
Před vytvořením nativní aplikace, která využívá ovládací prvky .NET MAUI, byste měli přidat projekt aplikace .NET MAUI do stejného řešení jako projekt knihovny tříd .NET MAUI, který jste vytvořili dříve. Projekt aplikace .NET MAUI uloží uživatelské rozhraní, které chcete znovu použít v nativní vložené aplikaci. Po přidání nového projektu aplikace .NET MAUI do řešení proveďte následující kroky:
Odstraňte složku Vlastnosti z projektu.
Odstraňte složku Platformy z projektu.
Odstraňte složku Resources/AppIcon z projektu.
Odstraňte složku Resources/raw z projektu.
Odstraňte složku Resources/Splash z projektu.
Odstraňte třídu
AppShell
z projektu.App
Upravte třídu tak, aby nenastavilMainPage
vlastnost:public partial class App : Application { public App() { InitializeComponent(); } }
Odstraňte třídu
MainPage
z projektu.Upravte soubor projektu tak, aby
$(TargetFrameworks)
byla vlastnost sestavení nastavena nanet8.0
hodnotu a$(OutputType)
vlastnost sestavení se odebere:<PropertyGroup> <TargetFrameworks>net8.0</TargetFrameworks> <RootNamespace>MyMauiApp</RootNamespace> <UseMaui>true</UseMaui> <SingleProject>true</SingleProject> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> ... </PropertyGroup>
Upravte metodu
CreateMauiApp
MauiProgram
ve třídě tak, aby přijímá volitelnýAction<MauiAppBuilder>
argument vyvolaný před vrácením 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(); }
V tomto okamžiku byste měli do projektu přidat požadované uživatelské rozhraní .NET MAUI, včetně všech závislostí a prostředků, a zajistit správné sestavení projektu.
Povolení podpory rozhraní .NET MAUI
Pokud chcete využívat ovládací prvky .NET MAUI odvozené z Element aplikace .NET pro Android, .NET pro iOS, .NET for Mac Catalyst nebo WinUI, měli byste svůj nativní projekt aplikace přidat do stejného řešení jako projekt knihovny tříd .NET MAUI, který jste vytvořili dříve. Potom byste měli povolit podporu .NET MAUI v souboru projektu vaší nativní aplikace nastavením $(UseMaui)
vlastností sestavení $(MauiEnablePlatformUsings)
na true
první <PropertyGroup>
uzel v souboru projektu:
<PropertyGroup>
...
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<UseMaui>true</UseMaui>
<MauiEnablePlatformUsings>true</MauiEnablePlatformUsings>
</PropertyGroup>
Pro aplikace .NET for Mac Catalyst budete také muset nastavit $(SupportedOSPlatformVersion)
vlastnost sestavení na minimálně 14.0:
<PropertyGroup>
...
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<SupportedOSPlatformVersion>14.2</SupportedOSPlatformVersion>
<UseMaui>true</UseMaui>
<MauiEnablePlatformUsings>true</MauiEnablePlatformUsings>
</PropertyGroup>
U aplikací WinUI budete také muset nastavit $(EnableDefaultXamlItems)
vlastnost sestavení na false
:
<PropertyGroup>
...
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<UseMaui>true</UseMaui>
<MauiEnablePlatformUsings>true</MauiEnablePlatformUsings>
<EnableDefaultXamlItems>false</EnableDefaultXamlItems>
</PropertyGroup>
Tím přestanete dostávat chyby sestavení týkající se InitializeComponent
již definované metody.
Potom přidejte $(PackageReference)
položky sestavení do souboru projektu pro Microsoft.Maui.Controls
balíčky NuGet:Microsoft.Maui.Controls.Compatiblity
<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="$(MauiVersion)" />
</ItemGroup>
Inicializace rozhraní .NET MAUI
Před vytvořením ovládacího prvku .NET MAUI je nutné inicializovat nativní projekt aplikace. Volba, kdy se má inicializovat, závisí především na tom, kdy je to v toku aplikace nejvhodnější – dá se provést při spuštění nebo těsně před vytvořením ovládacího prvku .NET MAUI. Zde uvedený přístup spočívá v inicializaci rozhraní .NET MAUI při vytvoření počátečního uživatelského rozhraní aplikace.
Vzor pro inicializaci .NET MAUI v nativním projektu aplikace je obvykle následující:
- Vytvoření objektu MauiApp
- Vytvoření MauiContext objektu z objektu MauiApp
V Androidu OnCreate
MainActivity
je přepsání třídy obvykle místem pro provádění úloh souvisejících se spuštěním aplikace. Následující příklad kódu ukazuje inicializaci .NET MAUI ve MainActivity
třídě:
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
...
}
}
}
V systému iOS a Mac Catalyst by se přepsání ve AppDelegate
třídě mělo upravit tak, FinishedLaunching
aby se vytvořil hlavní kontroler zobrazení:
namespace MyNativeEmbeddedApp.iOS
{
[Register("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
public override UIWindow? Window { get; set; }
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
Window = new UIWindow(UIScreen.MainScreen.Bounds);
var vc = new MainViewController();
Window.RootViewController = vc;
Window.MakeKeyAndVisible();
return true;
}
}
}
Rozhraní .NET MAUI je pak možné inicializovat v ViewDidLoad
metodě v hlavním kontroleru zobrazení:
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
...
}
}
}
Ve MainWindow
Windows je třída obvykle místem pro provádění úloh spuštění aplikace souvisejících s uživatelským rozhraním:
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
...
}
}
}
V tomto příkladu MauiApp se objekt vytvoří pomocí opožděné inicializace. Rozšiřující UseMauiEmbedding
metoda je vyvolána na objektu MauiAppBuilder . Proto by váš nativní projekt aplikace měl obsahovat odkaz na projekt knihovny tříd .NET MAUI, který jste vytvořili, který obsahuje tuto metodu rozšíření. Objekt MauiContext se pak vytvoří z objektu MauiApp s určením bool
, odkud je kontext vymezen. Objekt MauiContext se použije při převodu ovládacích prvků .NET MAUI na nativní typy.
Využívání ovládacích prvků .NET MAUI
Po inicializaci rozhraní .NET MAUI v nativní aplikaci můžete do rozložení nativní aplikace přidat uživatelské rozhraní .NET MAUI. Toho lze dosáhnout vytvořením instance uživatelského rozhraní a jeho převodem na příslušný nativní typ pomocí ToPlatformEmbedded
rozšiřující metody.
V Androidu ToPlatformEmbedded
metoda rozšíření převede ovládací prvek .NET MAUI na objekt Androidu View :
var mauiView = new MyMauiContent();
Android.Views.View nativeView = mauiView.ToPlatformEmbedded(mauiContext);
V tomto příkladu je odvozený ContentViewobjekt převeden na objekt Androidu View .
Poznámka:
Metoda ToPlatformEmbedded
rozšíření je v knihovně tříd .NET MAUI, kterou jste vytvořili dříve. Proto by váš nativní projekt aplikace měl obsahovat odkaz na tento projekt.
Objekt View pak můžete přidat do rozložení v nativní aplikaci:
rootLayout.AddView(nativeView, new LinearLayout.LayoutParams(MatchParent, WrapContent));
V systému iOS a Mac Catalyst ToPlatformEmbedded
metoda rozšíření převede ovládací prvek .NET MAUI na UIView objekt:
var mauiView = new MyMauiContent();
UIView nativeView = mauiView.ToPlatformEmbedded(mauiContext);
nativeView.WidthAnchor.ConstraintEqualTo(View.Frame.Width).Active = true;
nativeView.HeightAnchor.ConstraintEqualTo(500).Active = true;
V tomto příkladu se odvozený ContentViewobjekt převede na UIView objekt a pak jsou na něm nastavena omezení šířky a výšky, aby umožňovala interakci.
Poznámka:
Metoda ToPlatformEmbedded
rozšíření je v knihovně tříd .NET MAUI, kterou jste vytvořili dříve. Proto by váš nativní projekt aplikace měl obsahovat odkaz na tento projekt.
Objekt UIView pak můžete přidat do zobrazení v kontroleru zobrazení:
stackView.AddArrangedSubView(nativeView);
Kromě toho lze metodu ToUIViewController
rozšíření v .NET MAUI použít k pokusu o převod stránky .NET MAUI na UIViewController:
MyMauiPage myMauiPage = new MyMauiPage();
UIViewController myPageController = myMauiPage.ToUIViewController(mauiContext);
V tomto příkladu ContentPageje odvozený objekt převeden na .UIViewController
Ve Windows ToPlatformEmbedded
metoda rozšíření převede ovládací prvek .NET MAUI na FrameworkElement
objekt:
var mauiView = new MyMauiContent();
FrameworkElement nativeView = myMauiPage.ToPlatformEmbedded(mauiContext);
V tomto příkladu je odvozený ContentViewobjekt převeden na FrameworkElement
objekt. Objekt FrameworkElement
lze pak nastavit jako obsah stránky WinUI.
Objekt FrameworkElement
pak můžete přidat do rozložení v nativní aplikaci:
stackPanel.Children.Add(nativeView);
Důležité
Aby nedocházelo k chybě, mělo by být opětovné načítání XAML za provozu zakázané před spuštěním nativní vložené aplikace v konfiguraci ladění.
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro