Skip to content
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

Added embedding extensions #5218

Merged
merged 1 commit into from
Mar 15, 2022
Merged

Added embedding extensions #5218

merged 1 commit into from
Mar 15, 2022

Conversation

Clancey
Copy link
Contributor

@Clancey Clancey commented Mar 11, 2022

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
Copy link
Contributor Author

Clancey commented Mar 11, 2022

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
Copy link
Member

mattleibow commented Mar 11, 2022

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
Copy link
Member

Redth commented Mar 15, 2022

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

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

I have created a WinUI example that now works here:

https://github.com/sparkie108/MauiWinUIEmbedding

@devjama
Copy link

devjama commented Apr 28, 2022

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