dotnet / dotnet/maui

Handlers are not disconnected when a ContentView is unloaded via ControlTemplate change

Open
#31,044 4 comments 0 reactions 0 assignees View on GitHub
area-controls-general area-core-lifecycle platform/android platform/ios platform/windows s/triaged s/verified t/bug
Dominant language
C#
Stars
23.3k
Forks
2k
Avg merge
1d 14h
Merged PRs (30d)
296

Description

### Description

When switching ControlTemplates or replacing the Content of a ContentView, the previous ContentView is correctly unloaded, as confirmed by the Unloaded event. However, both the unloaded ContentView and its child controls in the disconnected visual tree still retain their Handler references.
This behavior appears to contradict the expectations set by the official documentation:

"By default, handlers automatically disconnect from their controls when possible, such as when navigating backwards in an app."
[Microsoft Docs – Create a Handler](https://learn.microsoft.com/en-us/dotnet/maui/user-interface/handlers/create?view=net-maui-9.0#control-handler-disconnection)

From a user's perspective, it seems reasonable to expect that handlers should automatically disconnect when a control is removed from the visual tree, especially when the Unloaded event is raised and the view is no longer visible or part of the layout hierarchy.
A common scenario like switching views or templates via ControlTemplate or ContentView.Content assignment would seem to fall within the scope of "when possible", as referenced in the documentation.

### Steps to Reproduce

1. Compile the MauiLifeCycleTest project provided in the linked git repo and launch the app
2. Add breakpoints to the Unloaded & HandlerChanged event, and inspect the ContentViewHandler in the Template1.xaml.cs
3. Press the _toggle template_ button
Expected outcome: The Handler gets set to null
Actual outcome: The Unloaded event is called, but the Handler doesn't get disconnected

### Link to public reproduction project repository

https://github.com/CWI-augmensys/maui-handler-lifecycle-bug/tree/main/MauiLifeCycleTest

### Version with bug

9.0.80 SR8

### Is this a regression from previous behavior?

Not sure, did not test other versions

### Last version that worked well

Unknown/Other

### Affected platforms

Windows, iOS, Android

### Affected platform versions

_No response_

### Did you find any workaround?

_No response_

### Relevant log output

```shell

```

Contributor guide

Open the contributing guide

Research direction

Start by compiling and running the linked MauiLifeCycleTest reproduction, then inspect Template1.xaml.cs with breakpoints on Unloaded and HandlerChanged. Toggle the template and compare the handler state for the unloaded ContentView and its child controls. The fix is complete when the handler references are disconnected as expected after unloading.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
frontend, mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.