Skip to content

Added embedding extensions#5218

Merged
Redth merged 1 commit into
dotnet:mainfrom
Clancey:Embedded
Mar 15, 2022
Merged

Added embedding extensions#5218
Redth merged 1 commit into
dotnet:mainfrom
Clancey:Embedded

Conversation

@Clancey

@Clancey Clancey commented Mar 11, 2022

Copy link
Copy Markdown
Contributor

Description of Change

This adds a new Api that will allow us to control registration for Maui Native embedding.

Issues Fixed

Fixes (partially) #1718

Usage:
Maui Embedding.md

@Clancey

Clancey commented Mar 11, 2022

Copy link
Copy Markdown
Contributor Author

Maui Embedding

So you have a Net 6.0 App (iOS MacOS, Android, or Windows) , and you want to add a few Maui Screens. No Problem!

Setup

First you need to add UseMaui to the CSProj

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

iOS/Mac

First create a MauiContext. This is best done in your AppDelegate

    	public static MauiContext MauiContext;
		public override bool FinishedLaunching(UIApplication app, NSDictionary options)
		{
			///Your normal iOS registration
			
			//Setup MauiBits
			var builder = MauiApp.CreateBuilder();
			
			//Add Maui Controls
			builder.UseMauiEmbedded();
			
			//Using comet?
			//builder.UseComet();
			
			//iOS/Mac need to register the Window
			
			builder.Services.Add( new Microsoft.Extensions.DependencyInjection.ServiceDescriptor(typeof(UIKit.UIWindow),window));
			    
			var mauiApp = builder.Build();
			
			//Create and save a Maui Context. This is needed for creating Platform UI
			mauiContext = new MauiContext(mauiApp.Services);
			return true;
		}

Now you can create and use a MauiView!

		//Create a Maui Page
		var myMauiPage = new MyMauiPage();
		
		//Turn the Maui page into an Android View
		UIView view = myMauiPage.ToPlatform(mauiContext);

Android

using Android.App;
using Android.OS;
using Microsoft.Maui.Platform;
using Microsoft.Maui.Embedding;


[Activity(Label = "@string/app_name", MainLauncher = true)]
public class MainActivity : Activity
{
	MauiContext mauiContext;
	protected override void OnCreate(Bundle? savedInstanceState)
	{
		base.OnCreate(savedInstanceState);
		
		//Setup MauiBits
		var builder = MauiApp.CreateBuilder();
		
		//Add Maui Controls
		builder.UseMauiEmbedded();
		
		//Using comet?
		//builder.UseComet();
		    
		var mauiApp = builder.Build();
		
		//Create and save a Maui Context. This is needed for creating Platform UI
		mauiContext = new MauiContext(mauiApp.Services,this);
		
		//Create a Maui Page
		var myMauiPage = new MyMauiPage();
		
		//Turn the Maui page into an Android View
		var view = myMauiPage.ToPlatform(mauiContext);
		
		//Use the Android View
		SetContentView(view);
	}
}

@mattleibow

mattleibow commented Mar 11, 2022

Copy link
Copy Markdown
Member

Maybe you can make use of the extensions in MauiContextExtensions to capture and store the platform app and window for use in other places:

  • MakeApplicationScope
  • MakeWindowScope

For example, it could be possible to make a new extension method for MauiApp:

// this can be stored in a static location
var mauiEmbeddedApp = MauiApp
    .CreateBuilder()
    .UseMauiEmbedded()
    .Build()
    .ToEmbedded(); // new method

// this runs on each window or activity
var platformWindow = ... // Window on iOS, this on Android, this on WinUI
var mauiContext = mauiEmbeddedApp.CreateWindowContext(platformWindow);

// back to normal things
var page = new ContentPage {
    new Label { Text = "w00t!" }
};
var platformView = page.ToPlatform(mauiContext);

The new extension method just returns a wrapped MauiApp that holds the context:

static class EmbeddedExtensions {
    public static MauiEmbeddedApp ToEmbedded(this MauiApp mauiApp) {
        var platformApp = UIApplication.SharedApplication;
        var platformApp = Android.App.Application.Context as Android.App.Application;
        var platformApp = UI.Xaml.Application.Current;

        // create scopes to make sure the platform app is added (ie: UIAppDelegate is in the services)
        var mauiContext = new MauiContext(mauiApp.Services, platformApp);
        var appContext = mauiContext.MakeAppScope(platformApp);

        var embedded = new MauiEmbeddedApp(mauiApp, appContext);
        return embedded;
    }

    public static MauiContext CreateWindowContext(this MauiEmbeddedApp mauiApp, PlatformWindow platformWindow) {
        // create scopes to make sure the platform window is added (ie: UIWindow is in the services)
        var windowContext = mauiApp.MauiApplicationContext.MakeWindowScope(platformWindow);
        return windowContext;
    }
}

class MauiEmbeddedApp : IDisposable {
    internal MauiEmbeddedApp(MauiApp mauiApp, MauiContext appContext);
    public MauiApp { get; }
    public MauiContext MauiApplicationContext { get; }
    public IServiceProvider Services => MauiApp.Services;
    public IConfiguration Configuration => MauiApp.Configuration;
}

@Redth

Redth commented Mar 15, 2022

Copy link
Copy Markdown
Member

Moved @mattleibow 's comments to the original issue for tracking in future work.

@Redth Redth merged commit c5d2f15 into dotnet:main Mar 15, 2022
@SparkieLabs

Copy link
Copy Markdown

I tried adding UseMaui to a WinUI project and got the following errors:

..\WinUIApp\Microsoft.Maui.Controls.SourceGen\Microsoft.Maui.Controls.SourceGen.CodeBehindGenerator\App.xaml.sg.cs(20,16,20,35): error CS0111: Type 'App' already defines a member called 'InitializeComponent' with the same parameter types
..\WinUIApp\Microsoft.Maui.Controls.SourceGen\Microsoft.Maui.Controls.SourceGen.CodeBehindGenerator\MainWindow.xaml.sg.cs(24,16,24,35): error CS0111: Type 'MainWindow' already defines a member called 'InitializeComponent' with the same parameter types

It looks like both Maui and WinUI are source generating from the xaml files. Is there a way to disable the Maui xaml source generator?

@mattleibow

Copy link
Copy Markdown
Member

@sparkie108 could you open a new issue with you problem? I think there may be some extra steps, but I think the discussion is going to be lost here.

@SparkieLabs

Copy link
Copy Markdown

I have created a WinUI example that now works here:

https://github.com/sparkie108/MauiWinUIEmbedding

@devjama

devjama commented Apr 28, 2022

Copy link
Copy Markdown

Is there (or will there be) a possibility to embed MAUI to UWP application?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-controls-general General issues that span multiple controls, or common base classes such as View or Element fixed-in-6.0.300-rc.1 Look for this fix in 6.0.300-rc.1! t/native-embedding

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants