Maui: [BUG] Popup doesn't work with hot reload

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

Popup xaml changes aren’t reflected with hot reload. I’m not sure if this was part of the original intended functionality, but it can be quite tedious to iterate on Popup design changes.

Expected Behavior

Popup xaml changes should ideally be reflected during runtime, just like other Views in .NET MAUI.

Steps To Reproduce

  1. Open and run the solution in the project repository
  2. Click the button to show a popup
  3. Make changes in the popup’s xaml during runtime
  4. Observe that your changes have not been reflected

PopupHotReloadNotWorking

Link to public reproduction project repository

https://github.com/mavispuford/PopupHotReloadNotWorking

Environment

- .NET MAUI CommunityToolkit: 1.2.0
- OS:
Edition	Windows 10 Enterprise
Version	20H2
OS build	19042.1889
Experience	Windows Feature Experience Pack 120.2212.4180.0
- .NET MAUI: 6.0.486

Anything else?

I’ve also reproduced this bug in Android. I haven’t tested platforms outside of Windows/Android.

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 1
  • Comments: 15 (6 by maintainers)

Most upvoted comments

@mavispuford IHotReloadabieView has nothing to do with XAML Hot Reload, it has to do with Comet. Implementing it won’t do anything for XAML Hot Reload.

@pictos For XAML Hot Reload to work, you need to implement IVisualTreeElement, https://github.com/dotnet/maui/blob/main/src/Core/src/Core/IVisualTreeElement.cs

Most base MAUI controls (Apart from ListView) implement this out of the box. XAML Hot Reload checks if the control implements this and uses it to then go through the children. If your control doesn’t implement this, it will not show up in the Live Visual Tree, and will then not be tracked at all for XAML Hot Reload.

Also, I would leave an issue in the MAUI repo about docs for this, since none of that is obvious unless you’re me, lol.

While I wouldn’t normally suggest this approach, given .NET 7 is not really going to change anything in this area of the code, it is probably safe enough to use some reflection if you really want to multitarget this support. Here’s what I used in Maui.VirtualListView before the methods were added in .NET 8:

internal static class LogicalChildrenHelpers
{
	static MethodInfo removeLogicalChildMethod = null;

	internal static void RemoveLogicalChild(this Element parent, IView view)
	{
		if (view is Element elem)
		{
			removeLogicalChildMethod ??= GetLogicalChildMethod(parent, "RemoveLogicalChildInternal", "RemoveLogicalChild");
			removeLogicalChildMethod?.Invoke(parent, new[] { elem });
		}
	}

	static MethodInfo addLogicalChildMethod = null;

	internal static void AddLogicalChild(this Element parent, IView view)
	{
		if (view is Element elem)
		{
			addLogicalChildMethod ??= GetLogicalChildMethod(parent, "AddLogicalChildInternal", "AddLogicalChild");
			addLogicalChildMethod?.Invoke(parent, new[] { elem });
		}
	}

	static MethodInfo GetLogicalChildMethod(Element parent, string internalName, string publicName)
	{
		var internalMethod = parent.GetType().GetMethod(
				internalName,
				BindingFlags.Instance | BindingFlags.NonPublic,
				new[] { typeof(Element) });

		if (internalMethod is null)
		{
			internalMethod = parent.GetType().GetMethod(
				publicName,
				BindingFlags.Instance | BindingFlags.Public,
				new[] { typeof(Element) });
		}

		return internalMethod;
	}
}

@LennoxP90 not yet

It depends on the control, but generally you should only need to place it on the top most level, unless the control handles child elements in a weird way. Basically, if you don’t see the child elements in the Live Visual Tree, it is not tracked and can’t be hot reloaded.

You may also need to make sure whenever the popup is invoked, that VisualDiagnostics OnVisualTree changes are fired, https://github.com/dotnet/maui/blob/main/src/Core/src/VisualDiagnostics/VisualDiagnostics.cs#L77-L80