Fix handler not disconnected when removing non visible pages using RemovePage()#32289
Fix handler not disconnected when removing non visible pages using RemovePage()#32289PureWeen merged 12 commits intodotnet:inflight/currentfrom
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a bug where RemovePage fails to disconnect handlers when the removed page is not currently visible in the navigation stack. The fix ensures proper cleanup of page handlers to prevent memory leaks and resource issues.
Key changes:
- Added
DisconnectHandlers()call in bothNavigationPage.csandNavigationPage.Legacy.cswhen a non-visible page is removed from the navigation stack - Added comprehensive UI test to verify handlers are properly disconnected when removing pages
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
src/Controls/src/Core/NavigationPage/NavigationPage.cs |
Added handler disconnection in OnRemovePage method for non-visible pages |
src/Controls/src/Core/NavigationPage/NavigationPage.Legacy.cs |
Added handler disconnection in RemovePage method for non-visible pages (legacy implementation) |
src/Controls/tests/TestCases.HostApp/Issues/Issue32239.cs |
Created UI test page with navigation stack setup to reproduce the issue |
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32239.cs |
Created NUnit test to verify handler disconnection when removing non-visible pages |
| // Only disconnect handlers if the removed page is not visible. | ||
| // When the current page is removed, the handler is disconnected through PopAsync(). |
There was a problem hiding this comment.
The comment is misleading. According to the code logic above (lines 897-902), when the current page is removed, PopAsync() is called and the method returns early. This means the DisconnectHandlers() call on line 914 is ONLY executed for non-visible pages. The comment should be revised to: 'Disconnect handlers for the removed non-visible page. Note: When the current page is removed, the handler disconnection is handled through PopAsync() (see lines 897-902).' Alternatively, remove the second sentence entirely since it doesn't accurately describe what happens in this code path.
| // Only disconnect handlers if the removed page is not visible. | |
| // When the current page is removed, the handler is disconnected through PopAsync(). | |
| // Disconnect handlers for the removed non-visible page. | |
| // Note: When the current page is removed, the handler disconnection is handled through PopAsync() (see lines 897-902). |
| // Only disconnect handlers if the removed page is not visible. | ||
| // When the current page is removed, the handler is disconnected through PopAsync(). |
There was a problem hiding this comment.
The comment is misleading. According to the code logic above (lines 242-247), when the current page is removed, PopAsync() is called and the method returns early. This means the DisconnectHandlers() call on line 257 is ONLY executed for non-visible pages. The comment should be revised to: 'Disconnect handlers for the removed non-visible page. Note: When the current page is removed, the handler disconnection is handled through PopAsync() (see lines 242-247).' Alternatively, remove the second sentence entirely since it doesn't accurately describe what happens in this code path.
| // Only disconnect handlers if the removed page is not visible. | |
| // When the current page is removed, the handler is disconnected through PopAsync(). | |
| // Disconnect handlers for the removed non-visible page. | |
| // Note: When the current page is removed, the handler disconnection is handled through PopAsync() (see lines 242-247). |
| // Only disconnect handlers if the removed page is not visible. | ||
| // When the current page is removed, the handler is disconnected through PopAsync(). | ||
| page?.DisconnectHandlers(); |
There was a problem hiding this comment.
This creates duplicate handler disconnection logic. The NavigationProxy.OnRemovePage method (line 255 in NavigationProxy.cs) already calls page?.DisconnectHandlers() after calling currentInner.RemovePage(page). This means when RemovePage is invoked through the navigation proxy, handlers will be disconnected twice - once in this implementation and once in the proxy. Consider whether this duplication is intentional or if the NavigationProxy call should be removed to avoid redundant disconnection attempts.
| // Only disconnect handlers if the removed page is not visible. | |
| // When the current page is removed, the handler is disconnected through PopAsync(). | |
| page?.DisconnectHandlers(); | |
| // Handler disconnection is now handled by the NavigationProxy. |
There was a problem hiding this comment.
I’ve removed the redundant disconnection logic from NavigationProxy and updated the implementation in ShellSection. This ensures that DisconnectHandler is called only once and avoids any duplicate disconnection.
|
/azp run MAUI-UITests-public |
|
Azure Pipelines successfully started running 1 pipeline(s). |
- Updated comments in NavigationPage.cs and NavigationPage.Legacy.cs to accurately describe the code flow - Added missing trailing newlines to test files
StephaneDelcroix
left a comment
There was a problem hiding this comment.
✅ Approved
This PR correctly fixes the handler disconnection issue when removing non-visible pages using RemovePage().
Summary of Changes
| File | Change |
|---|---|
NavigationPage.cs |
Added page?.DisconnectHandlers() in OnRemovePage |
NavigationPage.Legacy.cs |
Added page?.DisconnectHandlers() in RemovePage |
ShellSection.cs |
Added page?.DisconnectHandlers() in OnRemovePage |
NavigationProxy.cs |
Removed duplicate DisconnectHandlers() call |
Improvements Made
I've pushed a commit that:
- Fixed misleading comments - Updated comments to accurately describe the code flow (this code path is only reached for non-visible pages)
- Added missing trailing newlines - Fixed cosmetic issue in test files
Verification
- ✅ Fix addresses the root cause from regression PR #24887
- ✅ Proper test coverage with UI automation
- ✅ All four platforms tested by author
- ✅ Null-safe implementation
- ✅ No duplicate disconnection (NavigationProxy call removed)
Great work! 🚀
StephaneDelcroix
left a comment
There was a problem hiding this comment.
Requesting changes: Adding a unit test in Controls.Core.UnitTests to complement the UI test.
Added two unit tests to verify handler disconnection behavior: - RemovePageDisconnectsHandlerForNonVisiblePage: Verifies the page is properly removed from navigation stack - RemovePageCallsDisconnectHandlersOnRemovedPage: Verifies handler is disconnected when page with handler is removed
StephaneDelcroix
left a comment
There was a problem hiding this comment.
✅ Approved
This PR correctly fixes the handler disconnection issue when removing non-visible pages using RemovePage().
Summary of Changes
| File | Change |
|---|---|
NavigationPage.cs |
Added page?.DisconnectHandlers() in OnRemovePage |
NavigationPage.Legacy.cs |
Added page?.DisconnectHandlers() in RemovePage |
ShellSection.cs |
Added page?.DisconnectHandlers() in OnRemovePage |
NavigationProxy.cs |
Removed duplicate DisconnectHandlers() call |
Improvements Made
I've pushed commits that:
- Fixed misleading comments - Updated comments to accurately describe the code flow
- Added missing trailing newlines - Fixed cosmetic issue in test files
- Added unit tests - New tests in
NavigationUnitTest.cs:RemovePageDisconnectsHandlerForNonVisiblePage- Verifies page is properly removed from navigation stackRemovePageCallsDisconnectHandlersOnRemovedPage- Verifies handler is disconnected when page with handler is removed
Test Coverage
| Test Type | Location | Purpose |
|---|---|---|
| Unit Test | NavigationUnitTest.cs |
Verifies handler disconnection logic |
| UI Test | Issue32239.cs |
End-to-end validation on device |
Verification
- ✅ Fix addresses the root cause from regression PR #24887
- ✅ Unit tests pass locally
- ✅ All four platforms tested by author
- ✅ Null-safe implementation
- ✅ No duplicate disconnection (NavigationProxy call removed)
Great work! 🚀
The unit tests in NavigationUnitTest.cs adequately verify the handler disconnection behavior. The UI test adds maintenance burden without additional value.
StephaneDelcroix
left a comment
There was a problem hiding this comment.
✅ Approved
Clean, minimal fix for handler disconnection when removing non-visible pages.
Changes (5 files, +65/-1)
| File | Change |
|---|---|
NavigationPage.cs |
Added page?.DisconnectHandlers() in OnRemovePage |
NavigationPage.Legacy.cs |
Added page?.DisconnectHandlers() in RemovePage |
ShellSection.cs |
Added page?.DisconnectHandlers() in OnRemovePage |
NavigationProxy.cs |
Removed duplicate call (moved to implementations) |
NavigationUnitTest.cs |
Added 2 unit tests |
Unit Tests
RemovePageDisconnectsHandlerForNonVisiblePage- Verifies page removal from stackRemovePageCallsDisconnectHandlersOnRemovedPage- Verifies handler disconnection
All tests pass. LGTM! 🚀
- Remove line number references from comments (prone to becoming stale) - Add handler disconnection verification to existing test - Rename test for clarity (RemovePageCallsDisconnectHandlersOnRemovedPage -> RemovePageDisconnectsHandlerForRemovedRootPage) - Add Shell-specific test for RemovePage handler disconnection
rmarinho
left a comment
There was a problem hiding this comment.
✅ Approved
This PR properly fixes the handler disconnection issue when using RemovePage() on non-visible pages.
Summary of Changes
- Root cause fix: Moves
DisconnectHandlers()fromNavigationProxyto the concrete implementations (NavigationPage,NavigationPage.Legacy,ShellSection) - No duplicate disconnection: By removing from the proxy and adding to implementations, handlers are disconnected exactly once
- Clean comments: Comments explain the behavior without brittle line number references
Test Coverage
- ✅
RemovePageDisconnectsHandlerForNonVisiblePage- Tests removing middle page from 3-page stack - ✅
RemovePageDisconnectsHandlerForRemovedRootPage- Tests removing root page when another page is on top - ✅
RemovePageDisconnectsHandlerInShell- Tests Shell navigation scenario
All tests pass for both useMaui: true and useMaui: false scenarios, covering both the modern and legacy navigation implementations.
LGTM! 🚀
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
…movePage() (#32289) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details When a non-visible page is removed from the navigation stack using RemovePage(), its handler is not disconnected. ### Root Cause The RemovePage() method removes the page from the navigation stack but does not explicitly disconnect its handler. ### Description of Change The handler is now properly disconnected when a page is removed using RemovePage(). Regression PR: #24887 ### Tested the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #32239 ### Screenshots **Android:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/890c3e4b-f520-4826-b942-6ec9e04233d1"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/40ebc025-7298-4b43-8816-4932a01fb563">) | **iOS:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/484e17cd-bd83-415e-af27-99acf893b203"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/062a1c6d-047c-4bde-add2-d2d261763c87">) | --------- Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Rui Marinho <me@ruimarinho.net> Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
…movePage() (#32289) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details When a non-visible page is removed from the navigation stack using RemovePage(), its handler is not disconnected. ### Root Cause The RemovePage() method removes the page from the navigation stack but does not explicitly disconnect its handler. ### Description of Change The handler is now properly disconnected when a page is removed using RemovePage(). Regression PR: #24887 ### Tested the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #32239 ### Screenshots **Android:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/890c3e4b-f520-4826-b942-6ec9e04233d1"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/40ebc025-7298-4b43-8816-4932a01fb563">) | **iOS:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/484e17cd-bd83-415e-af27-99acf893b203"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/062a1c6d-047c-4bde-add2-d2d261763c87">) | --------- Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Rui Marinho <me@ruimarinho.net> Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
…movePage() (#32289) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details When a non-visible page is removed from the navigation stack using RemovePage(), its handler is not disconnected. ### Root Cause The RemovePage() method removes the page from the navigation stack but does not explicitly disconnect its handler. ### Description of Change The handler is now properly disconnected when a page is removed using RemovePage(). Regression PR: #24887 ### Tested the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #32239 ### Screenshots **Android:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/890c3e4b-f520-4826-b942-6ec9e04233d1"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/40ebc025-7298-4b43-8816-4932a01fb563">) | **iOS:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/484e17cd-bd83-415e-af27-99acf893b203"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/062a1c6d-047c-4bde-add2-d2d261763c87">) | --------- Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Rui Marinho <me@ruimarinho.net> Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
…movePage() (#32289) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details When a non-visible page is removed from the navigation stack using RemovePage(), its handler is not disconnected. ### Root Cause The RemovePage() method removes the page from the navigation stack but does not explicitly disconnect its handler. ### Description of Change The handler is now properly disconnected when a page is removed using RemovePage(). Regression PR: #24887 ### Tested the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #32239 ### Screenshots **Android:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/890c3e4b-f520-4826-b942-6ec9e04233d1"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/40ebc025-7298-4b43-8816-4932a01fb563">) | **iOS:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/484e17cd-bd83-415e-af27-99acf893b203"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/062a1c6d-047c-4bde-add2-d2d261763c87">) | --------- Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Rui Marinho <me@ruimarinho.net> Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
…movePage() (#32289) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details When a non-visible page is removed from the navigation stack using RemovePage(), its handler is not disconnected. ### Root Cause The RemovePage() method removes the page from the navigation stack but does not explicitly disconnect its handler. ### Description of Change The handler is now properly disconnected when a page is removed using RemovePage(). Regression PR: #24887 ### Tested the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #32239 ### Screenshots **Android:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/890c3e4b-f520-4826-b942-6ec9e04233d1"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/40ebc025-7298-4b43-8816-4932a01fb563">) | **iOS:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/484e17cd-bd83-415e-af27-99acf893b203"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/062a1c6d-047c-4bde-add2-d2d261763c87">) | --------- Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Rui Marinho <me@ruimarinho.net> Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
…movePage() (#32289) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details When a non-visible page is removed from the navigation stack using RemovePage(), its handler is not disconnected. ### Root Cause The RemovePage() method removes the page from the navigation stack but does not explicitly disconnect its handler. ### Description of Change The handler is now properly disconnected when a page is removed using RemovePage(). Regression PR: #24887 ### Tested the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #32239 ### Screenshots **Android:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/890c3e4b-f520-4826-b942-6ec9e04233d1"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/40ebc025-7298-4b43-8816-4932a01fb563">) | **iOS:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/484e17cd-bd83-415e-af27-99acf893b203"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/062a1c6d-047c-4bde-add2-d2d261763c87">) | --------- Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Rui Marinho <me@ruimarinho.net> Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
…movePage() (#32289) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Issue Details When a non-visible page is removed from the navigation stack using RemovePage(), its handler is not disconnected. ### Root Cause The RemovePage() method removes the page from the navigation stack but does not explicitly disconnect its handler. ### Description of Change The handler is now properly disconnected when a page is removed using RemovePage(). Regression PR: #24887 ### Tested the behavior in the following platforms - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Issues Fixed Fixes #32239 ### Screenshots **Android:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/890c3e4b-f520-4826-b942-6ec9e04233d1"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/40ebc025-7298-4b43-8816-4932a01fb563">) | **iOS:** | Before Issue Fix | After Issue Fix | |----------|----------| | <video width="300" height="600" src="https://github.com/user-attachments/assets/484e17cd-bd83-415e-af27-99acf893b203"> | <video width="300" height="600" src="https://github.com/user-attachments/assets/062a1c6d-047c-4bde-add2-d2d261763c87">) | --------- Co-authored-by: Stephane Delcroix <stephane@delcroix.org> Co-authored-by: Rui Marinho <me@ruimarinho.net> Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
## What's Coming .NET MAUI inflight/candidate introduces significant improvements across all platforms with focus on quality, performance, and developer experience. This release includes 16 commits with various improvements, bug fixes, and enhancements. ## Checkbox - [Android] Implement material3 support for CheckBox by @HarishwaranVijayakumar in #33339 <details> <summary>🔧 Fixes</summary> - [Implement Material3 Support for CheckBox](#33338) </details> ## CollectionView - [Android] Fixed EmptyView doesn’t display when CollectionView is placed inside a VerticalStackLayout by @NanthiniMahalingam in #33134 <details> <summary>🔧 Fixes</summary> - [CollectionView does not show an EmptyView template with an empty collection](#32932) </details> ## Essentials - [Windows]Fix NullReferenceException in OpenReadAsync for FileResult created with full path by @devanathan-vaithiyanathan in #28238 <details> <summary>🔧 Fixes</summary> - [[Windows] FileResult(string fullPath) not initialized properly](#26858) </details> ## Image - Fix Glide IllegalArgumentException in MauiCustomTarget.clear() for destroyed activities by @jfversluis via @Copilot in #29780 <details> <summary>🔧 Fixes</summary> - [java.lang.IllegalArgumentException: You cannot start a load for a destroyed activity - glide](#29699) </details> ## Label - [Android] Fix for Label WordWrap width issue causing HorizontalOptions misalignment by @praveenkumarkarunanithi in #33281 <details> <summary>🔧 Fixes</summary> - [[Android] Unexpected Line Breaks in Android, Label with WordWrap Mode Due to Trailing Space.](#31782) - [Label not sized correctly on Android](#27614) </details> - Fix to Improve Flyout Accessibility by Adjusting UITableViewController Labels by @SuthiYuvaraj in #31619 <details> <summary>🔧 Fixes</summary> - [Navigation section present under hamburger are programmatically define as table :A11y_.NET maui_User can get all the insights of Dashboard_Devtools](#30894) </details> ## Mediapicker - [Regression][iOS] Fix MediaPicker PickPhotosAsync getting file name in contentType property by @devanathan-vaithiyanathan in #33390 <details> <summary>🔧 Fixes</summary> - [[iOS] MediaPicker PickPhotosAsync getting file name in contentType property](#33348) </details> ## Navigation - Fix handler not disconnected when removing non visible pages using RemovePage() by @Vignesh-SF3580 in #32289 <details> <summary>🔧 Fixes</summary> - [NavigationPage.Navigation.RemovePage() fails to disconnect handlers when removing pages, unlike ContentPage.Navigation.RemovePage()](#32239) </details> ## Picker - [Android] Fix Picker IsOpen not reset when picker is dismissed by @devanathan-vaithiyanathan in #33332 <details> <summary>🔧 Fixes</summary> - [[Android] Picker IsOpen not reset when picker is dismissed](#33331) </details> ## Shell - [iOS & Catalyst ] Fixed IsEnabled property should work on Tabs by @SubhikshaSf4851 in #33369 <details> <summary>🔧 Fixes</summary> - [[Catalyst] TabBarBackgroundColor, TabBarUnselectedColor, and IsEnabled Not Working as Expected in Shell](#33158) </details> - [iOS,Windows] Fix navigation bar colors not resetting when switching ShellContent by @Vignesh-SF3580 in #33228 <details> <summary>🔧 Fixes</summary> - [[iOS, Windows] Shell Navigation bar colors are not updated correctly when switching ShellContent](#33227) </details> - [iOS] Fixed Shell navigation on search handler suggestion selection by @SubhikshaSf4851 in #33406 <details> <summary>🔧 Fixes</summary> - [[iOS] Clicking on search suggestions fails to navigate to detail page correctly](#33356) </details> ## Templates - Fix VoiceOver doesnot announces the State of the ComboBox by @SuthiYuvaraj in #32286 ## Xaml - [XSG][BindingSourceGen] Add support for CommunityToolkit.Mvvm ObservablePropertyAttribute by @simonrozsival via @Copilot in #33028 <details> <summary>🔧 Fixes</summary> - [[XSG] Add heuristic to support bindable properties generated by other source generators](#32597) </details> <details> <summary>📦 Other (2)</summary> - [XSG] Improve diagnostic reporting during binding compilation by @simonrozsival via @Copilot in #32905 - [Testing] Fixed Test case failure in PR 33574 - [01/19/2026] Candidate - 1 by @TamilarasanSF4853 in #33602 </details> **Full Changelog**: main...inflight/candidate
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Issue Details
When a non-visible page is removed from the navigation stack using RemovePage(), its handler is not disconnected.
Root Cause
The RemovePage() method removes the page from the navigation stack but does not explicitly disconnect its handler.
Description of Change
The handler is now properly disconnected when a page is removed using RemovePage().
Regression PR: #24887
Tested the behavior in the following platforms
Issues Fixed
Fixes #32239
Screenshots
Android:
32269BeforeFix.mov
32269AfterFix.mov
iOS:
32269iOSBeforeFix.mov
32269iOSAfterFix.mov