.NET MAUI Source Of Truth – Exploring IWindow

This is post #1 in a series called ‘.NET MAUI Source of Truth’.

About Source Of Truth – As any developer knows, source code is the purest form of truth in working software. So I’ve decided the best way to get deep into .NET MAUI is to look at the source code.

Exploring IWindow

Recently I was exploring the .NET MAUI codebase and came across something that seemed interesting, IWindow. ‘Windows in MAUI? that doesn’t make sense’ because Xamarin.Forms never had windows. I set about to find out what IWindow was.

A Xamarin.Forms Recap

Before we take a look at Windows in .NET MAUI let’s refresh ourselves on view hierarchies in Xamarin.Forms. In Xamarin.Forms we have an Application class with a MainPage property which takes a Page. You’re able to set the MainPage to either a single page or a navigation page.

So our hierarchies looks something like this:
Application->Page(Navigation/Page)->Page->Content

Windows in MAUI

Important Note: In this article whenever I make reference to Window/Windows most of the time it’s going to be Windows concept from .NET MAUI, not the Windows platform support of .NET MAUI.

If I look into any samples of MAUI applications then they follow the same hierarchy we find in Xamarin.Forms. So where’s the Windows?

Initially looking at the latest preview10 of .NET MAUI it seems the functionality of Windows is limited. So in order to see what Windows are going to look like in the future of .NET MAUI then we need to look at the latest source code.

If we remember that we’ve always started in Forms applications using MainPage,

eg MainPage = new ContentPage();

then let’s start with that MainPage property on the application class, FYI this is code from the MAUI github repository. If we dig into that method we can see that the MainPage still is part of the hierarchy but now Window is a parent of that page.

public Page? MainPage
{
	get
	{
		...
	}
	set
	{
		if (MainPage == value)
			return;

		OnPropertyChanging();

		if (Windows.Count == 0)
		{
			_pendingMainPage = value;
		}
		else
		{
			Windows[0].Page = value;
		}

		OnPropertyChanged();
	}
}

Now we can see that Window is a parent of Page, and Window has a property called Page.

If we look further into the implementation of the application class then we can see a new method that creates a new Window. I guess with the variable _pendingMainPage that we require some type of lazy loading.

IWindow IApplication.CreateWindow(IActivationState? activationState)
{
	Window? window = null;

	// try get the window that is pending
	if (activationState?.State?.TryGetValue(MauiWindowIdKey, out var requestedWindowId) ?? false)
	{
		if (requestedWindowId != null && _requestedWindows.TryGetValue(requestedWindowId, out var w))
			window = w;
	}

	// create a new one if there is no pending windows
	if (window == null)
	{
		window = CreateWindow(activationState);

		if (_pendingMainPage != null && window.Page != null && window.Page != _pendingMainPage)
			throw new InvalidOperationException($"Both {nameof(MainPage)} was set and {nameof(Application.CreateWindow)} was overridden to provide a page.");

		// clear out the pending main page as this will never be used again
		_pendingMainPage = null;
	}

	// make sure it is added to the windows list
	if (!_windows.Contains(window))
		AddWindow(window);

	return window;
}

Even more, is revealed if we take a look at IApplication. It looks like we will be able to OpenWindow, CloseWindow, and CreateWindow.

/// <summary>
/// Class that represents a cross-platform .NET MAUI application.
/// </summary>
public interface IApplication : IElement
{
	/// <summary>
	/// Gets the instantiated windows in an application.
	/// </summary>
	IReadOnlyList<IWindow> Windows { get; }

	/// <summary>
	/// Instantiate a new window.
	/// </summary>
	/// <param name="activationState">Argument containing specific information on each platform.</param>
	/// <returns>The created window.</returns>
	IWindow CreateWindow(IActivationState? activationState);

	void OpenWindow(IWindow window);

	/// <summary>
	/// Requests that the application closes the window.
	/// </summary>
	/// <param name="window">The window to close.</param>
	void CloseWindow(IWindow window);

	/// <summary>
	/// Notify a theme change.
	/// </summary>
	void ThemeChanged();
}

Here we can see one of the commits which is an initial implementation of Windows support: https://github.com/dotnet/maui/commit/6743036c67c4c19263ca180deb7523e0750b4820

From within .NET MAUI codebase, we can see a sample of how to use multiple windows in the .NET MAUI samples projects, look for MultiWindowPage.

public partial class MultiWindowPage : BasePage
{
	static int windowCounter = 1;

	public MultiWindowPage()
	{
		InitializeComponent();

		label.Text = "Window Count: " + (windowCounter++).ToString();
	}

	void OnNewWindowClicked(object sender, EventArgs e)
	{
		Application.Current.OpenWindow(new Window(new MultiWindowPage()));
	}

	void OnCloseWindowClicked(object sender, EventArgs e)
	{
		var window = this.GetParentWindow();
		if (window is not null)
			Application.Current.CloseWindow(window);
	}
}

It’s awesome to see that we have multiple windows going on, this is good for multiple reasons including support for Desktop Applications and IPad. This Window functionality will probably become more useful in future iOS/Android OS releases if the native OS build out the Windowing functionality further.

The current preview of .NET MAUI does not have the code changes for IWindow support so you will either need to download the .NET MAUI source or wait until we get our next preview release.

Here are the windows events all explained: https://github.com/dotnet/maui/issues/1720

Summary

  • Windows is a new concept built in .NET MAUI
  • Windows will allow you to open and close Windows
  • It looks like it will be very useful for Desktop applications

This is only a brief look at IWindow in .NET MAUI, there will be a lot more info to come as I discover more and the .NET team builds out the functionality further. I’m looking forward to sharing the knowledge. If you have any questions or need some .NET MAUI Consulting and XAM is here to help.

Leave a Reply