-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add embedding sample and code #23642
Conversation
844b484
to
27f27b2
Compare
/// <summary> | ||
/// A set of extension methods that allow for embedding a MAUI view within a native application. | ||
/// </summary> | ||
internal static class EmbeddingExtensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class is internal for now since this is a new API and we cannot add APIs to net8.0. However, we can make this public in net9.0.
This API is added here to make development easier as well as to allow for testing/usage in the Community Toolkit (if they want). Instead of trying to do complex things from the outside, we can make it internal and the [InternalsVisibleTo]
attributes effectively expose all these to them.
|
||
namespace Microsoft.Maui.Controls.Hosting; | ||
|
||
public static partial class AppHostBuilderExtensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class used to be in the Controls.Xaml assembly, however all of this was meant to be in Controls.Core. There is 2 lines in the old file that is referencing XAML types, so we rather move this logic into Controls.Core and call it from Controls.Xaml.
/// <summary> | ||
/// A set of extension methods that allow for embedding a MAUI view within a native application. | ||
/// </summary> | ||
internal static class EmbeddingExtensions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also is internal for net8.0 and should be public for net9.0. This is also visible to the Community Toolkit.
DependencyService.Register<Xaml.ResourcesLoader>(); | ||
DependencyService.Register<Xaml.ValueConverterProvider>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is the one I moved into Controls.Core - except for these 2 lines. The UseMauiApp
API is still here, but now just calls into Controls.Core and then calls this one (SetupXamlDefaults
).
/rebase |
e7be5ab
to
fcebdbe
Compare
Description of Change
This PR adds some overloads for MAUI to embed MAUI views in a platform app.
There are a few ways to embed things after this PR, each with increasing levels of steps, but also increasing levels of developer enjoyment.
With each case here, the
MauiProgram
is the same as before, except thatUseMauiApp
is replaced withUseMauiEmbeddedApp
to enable the embedding infrastructure. This is needed because unlike a traditional MAUI app, the platform application (eg:UIApplication
) andIPlatformApplication
needs to be registered in the service provider for the rest of MAUI to be rooted. There may be cases where this is not needed, but this will probably break tooling and other things because everything expects there to be a current and running MAUI application. In a typical MAUI app, this is done in the platform application setup code. But, in an embedded scenario, the platform application is not controlled by MAUI and is instead a user instance.Simplest
For the very simplest of cases, embedding can be done without any additional code besides the construction of the app and then creating a context to get the native view:
This will work because many situations may not care if it is attached to anything in the MAUI world. This is effectively a floating view in the MAUI universe that just has access to app-specific things. Some things, such as Hot Reload or MAUI features may not work because the view has no idea how to handle a world in which it is detached from the app.
In addition to the potentially missing features, we are also creating a brand new app each time we want to embed a control. This is fine for a single case and maybe if none of the components are using
Application.Current
. However, this is fairly common in apps and libraries, so the better way to do this is to create a shared, static instance of the MAUI app:This will also allow you to instantiate the
MauiApp
early in your app lifecycle and not have a small delay when instantiating the actual MAUI views.Window Scopes
.NET MAUI uses scoped services to manage the services and instances that are needed for each window. In some cases, a window may have a different dispatcher than the app or other windows. There may also be a case where a control needs to have access to a Window to do things. For example, adaptive triggers require access to a view's window, and if there is no window, it cannot work.
In order to wrap the view in a window, there is a
ToPlatformEmbedded
extension method that will do the same thing as the existingToPlatform
, but also make sure that it attaches to the application correctly. This means that it creates an embedded window that is attached to the application, and then the control is attached to that. This results in the window-related APIs working as well as tooling (Hot Reload) now starting to function.Correct Window Scopes
One downside of using the
ToPlatformEmbedded
extension method that accepts a platform window is that it will create a new embedded window for each invocation. This means, if you have 3 embedded views, you will also have 3 embedded windows attached to the app.To correctly relate a single native window with a single MAUI window, we can use the
CreateEmbeddedWindowContext
to first create a window context and then use that (instead of the app context) to attach windows:Final
If we put all this together, we can have a single, shared instance of our MAUI app, a single MAUI window for each native window, and all the tooling works correctly. For example, if we want to embed two different MAUI views on to a single WinUI window:
Issues Fixed
Fixes #