File: Embedding\EmbeddingExtensions.cs
Web Access
Project: src\src\Controls\src\Core\Controls.Core.csproj (Microsoft.Maui.Controls)
#if ANDROID || IOS || MACCATALYST || WINDOWS
using System;
using System.Linq;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Maui.Controls.Hosting;
using Microsoft.Maui.Embedding;
using Microsoft.Maui.Hosting;
 
#if ANDROID
using PlatformView = Android.Views.View;
using PlatformWindow = Android.App.Activity;
#elif IOS || MACCATALYST
using PlatformView = UIKit.UIView;
using PlatformWindow = UIKit.UIWindow;
#elif WINDOWS
using PlatformView = Microsoft.UI.Xaml.FrameworkElement;
using PlatformWindow = Microsoft.UI.Xaml.Window;
#endif
 
namespace Microsoft.Maui.Controls.Embedding;
 
/// <summary>
/// A set of extension methods that allow for embedding a MAUI view within a native application.
/// </summary>
public static class EmbeddingExtensions
{
	/// <summary>
	/// Enables MAUI to be embedded in native platform application by injecting embedded handlers into the service collection.
	/// </summary>
	/// <param name="builder">The <see cref="MauiAppBuilder"/> instance.</param>
	/// <returns>The <see cref="MauiAppBuilder"/> instance.</returns>
	/// <remarks>
	/// This is internal as it is exposed in Controls.Xaml since it needs to setup XAML defaults.
	/// </remarks>
	internal static MauiAppBuilder UseMauiEmbedding(this MauiAppBuilder builder)
	{
#if ANDROID
		var platformApplication = (Android.App.Application)Android.App.Application.Context;
#elif IOS || MACCATALYST
		var platformApplication = UIKit.UIApplication.SharedApplication.Delegate;
#elif WINDOWS
		var platformApplication = Microsoft.UI.Xaml.Application.Current;
#endif
 
		// Enable Core embedded features.
		builder.UseMauiEmbedding(platformApplication);
 
		// Register the embedded window handler.
		builder.ConfigureMauiHandlers(handlers =>
		{
			handlers.AddHandler<EmbeddedWindow, EmbeddedWindowHandler>();
		});
 
		return builder;
	}
 
	/// <summary>
	/// Creates a window-scoped <see cref="IMauiContext"/> for the provided native platform window.
	/// </summary>
	/// <param name="mauiApp">The <see cref="MauiApp"/> instance.</param>
	/// <param name="platformWindow">The native platform window instance to create the context for.</param>
	/// <returns>The window-scoped <see cref="IMauiContext"/> instance.</returns>
	/// <remarks>
	/// In addition to the context being created, a new Window instance is created and attached to the app.
	/// </remarks>
	public static IMauiContext CreateEmbeddedWindowContext(this MauiApp mauiApp, PlatformWindow platformWindow)
	{
		var window = new EmbeddedWindow();
 
		// Create the Core embedded window scope.
		var windowContext = mauiApp.CreateEmbeddedWindowContext(platformWindow, window);
 
		// If the app is an embedded app then we need to add the window to the app.
		var embeddedApp = mauiApp.Services.GetRequiredService<EmbeddedPlatformApplication>();
		if (embeddedApp.Application is Application app && !app.Windows.Contains(window))
		{
			app.AddWindow(window);
		}
 
		return windowContext;
	}
 
	/// <summary>
	/// Similar to <see cref="ElementExtensions.ToPlatform(IElement, IMauiContext)"/>, but also adds the element as
	/// a logical child to the embedded window.
	/// </summary>
	/// <param name="element">The element to use when creating the native platform view.</param>
	/// <param name="context">The context to use when creating the native platform view.</param>
	/// <returns>The native platform view that represents the element.</returns>
	/// <remarks>
	/// Only if the window is an embedded window and the element is a <see cref="VisualElement"/> will the element
	/// be added as a logical child of that window.
	/// </remarks>
	public static PlatformView ToPlatformEmbedded(this IElement element, IMauiContext context)
	{
		// If the window is an embedded window, then we need to add the element as a logical child.
		var wndProvider = context.Services.GetService<EmbeddedWindowProvider>();
		if (wndProvider is not null && wndProvider.Window is EmbeddedWindow wnd && element is VisualElement visual)
			wnd.AddLogicalChild(visual);
 
		return element.ToPlatform(context);
	}
 
	/// <summary>
	/// Similar to <see cref="ElementExtensions.ToPlatform(IElement, IMauiContext)"/>, but also adds the element as
	/// a logical child to a new embedded window.
	/// </summary>
	/// <param name="element">The element to use when creating the native platform view.</param>
	/// <param name="mauiApp">The <see cref="MauiApp"/> instance.</param>
	/// <param name="platformWindow">The native platform window that will host this element.</param>
	/// <returns>The native platform view that represents the element.</returns>
	/// <remarks>
	/// Only if the window is an embedded window and the element is a <see cref="VisualElement"/> will the element
	/// be added as a logical child of that window.
	/// </remarks>
	public static PlatformView ToPlatformEmbedded(this IElement element, MauiApp mauiApp, PlatformWindow platformWindow)
	{
		var windowContext = mauiApp.CreateEmbeddedWindowContext(platformWindow);
		return element.ToPlatformEmbedded(windowContext);
	}
}
 
#endif