[Windows] Fix SwipeItem IsVisible not refreshing native swipe items when binding changes#35361
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 35361Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 35361" |
|
Hey there @@SubhikshaSf4851! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
There was a problem hiding this comment.
Pull request overview
This PR fixes a Windows-specific gap where SwipeItem.IsVisible binding changes didn’t refresh the native WinUI swipe items, by ensuring visibility changes propagate through handlers and by rebuilding WinUI SwipeItems when needed.
Changes:
- Added an
IsVisiblePropertypropertyChangedcallback onSwipeItemto callHandler.UpdateValue(nameof(ISwipeItemMenuItem.Visibility)). - Updated Windows swipe item/SwipeView handlers to (a) rebuild native swipe items when a child
SwipeItemvisibility changes and (b) create handlers even for initially-collapsed swipe items so later visibility toggles can propagate. - Added a new Windows UI test + HostApp repro page for issue #35216.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/Core/src/Handlers/SwipeView/SwipeViewHandler.Windows.cs | Ensures handlers are created even for collapsed swipe items; only visible items are added to WinUI SwipeItems. |
| src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.Windows.cs | Rebuilds the parent SwipeView’s swipe items when a menu item visibility changes (WinUI SwipeItem lacks a Visibility property). |
| src/Controls/src/Core/SwipeView/SwipeItem.cs | Adds propertyChanged callback to propagate IsVisible changes through handler mapping. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue35216.cs | Adds a repro page to toggle a SwipeItem’s visibility via binding. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35216.cs | Adds a Windows UI test validating swipe items appear/disappear when the bound visibility changes. |
MauiBot
left a comment
There was a problem hiding this comment.
Expert Review — 9 findings
See inline comments for details.
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the ai's suggestions?
|
/azp run maui-pr-uitests, maui-pr-devicetests |
|
/review -b feature/enhanced-reviewer -p windows |
|
/azp run maui-pr-uitests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/review -b feature/enhanced-reviewer |
kubaflo
left a comment
There was a problem hiding this comment.
Could you please check the ai's suggestions?
|
/review rerun |
|
/review -b feature/enhanced-reviewer -p windows |
MauiBot
left a comment
There was a problem hiding this comment.
AI Review Summary
@SubhikshaSf4851 — new AI review results are available based on this last commit:
8853e24.
Added recommended suggestion To request a fresh review after new comments or commits, comment/review rerun.
Review Sessions — click to expand
Gate — Test Before & After Fix
Gate Result: ✅ PASSED
Platform: WINDOWS · Base: main · Merge base: dd5b6d2e
| Test | Without Fix (expect FAIL) | With Fix (expect PASS) |
|---|---|---|
🖥️ Issue35216 Issue35216 |
✅ FAIL — 613s | ✅ PASS — 504s |
🔴 Without fix — 🖥️ Issue35216: FAIL ✅ · 613s
Determining projects to restore...
Restored D:\a\1\s\src\Graphics\src\Graphics\Graphics.csproj (in 21.67 sec).
Restored D:\a\1\s\src\Graphics\src\Graphics.Win2D\Graphics.Win2D.csproj (in 21.77 sec).
Restored D:\a\1\s\src\Essentials\src\Essentials.csproj (in 9.04 sec).
Restored D:\a\1\s\src\Core\src\Core.csproj (in 16.87 sec).
Restored D:\a\1\s\src\Core\maps\src\Maps.csproj (in 15.33 sec).
Restored D:\a\1\s\src\Controls\tests\TestCases.HostApp\Controls.TestCases.HostApp.csproj (in 7.44 sec).
Restored D:\a\1\s\src\Controls\src\Xaml\Controls.Xaml.csproj (in 39 ms).
Restored D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj (in 34 ms).
Restored D:\a\1\s\src\Controls\Maps\src\Controls.Maps.csproj (in 13 ms).
Restored D:\a\1\s\src\Controls\Foldable\src\Controls.Foldable.csproj (in 20 ms).
Restored D:\a\1\s\src\BlazorWebView\src\Maui\Microsoft.AspNetCore.Components.WebView.Maui.csproj (in 27 ms).
3 of 14 projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Graphics.Win2D -> D:\a\1\s\artifacts\bin\Graphics.Win2D\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.dll
Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Maps -> D:\a\1\s\artifacts\bin\Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Maps.dll
Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Microsoft.AspNetCore.Components.WebView.Maui -> D:\a\1\s\artifacts\bin\Microsoft.AspNetCore.Components.WebView.Maui\Debug\net10.0-windows10.0.19041.0\Microsoft.AspNetCore.Components.WebView.Maui.dll
Controls.Xaml -> D:\a\1\s\artifacts\bin\Controls.Xaml\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Xaml.dll
Controls.Foldable -> D:\a\1\s\artifacts\bin\Controls.Foldable\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Foldable.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Controls.Maps -> D:\a\1\s\artifacts\bin\Controls.Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Maps.dll
Controls.TestCases.HostApp -> D:\a\1\s\artifacts\bin\Controls.TestCases.HostApp\Debug\net10.0-windows10.0.19041.0\win-x64\Controls.TestCases.HostApp.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:06:21.45
Determining projects to restore...
Restored D:\a\1\s\src\TestUtils\src\VisualTestUtils\VisualTestUtils.csproj (in 1.02 sec).
Restored D:\a\1\s\src\TestUtils\src\UITest.NUnit\UITest.NUnit.csproj (in 2.09 sec).
Restored D:\a\1\s\src\TestUtils\src\UITest.Core\UITest.Core.csproj (in 4 ms).
Restored D:\a\1\s\src\TestUtils\src\UITest.Appium\UITest.Appium.csproj (in 1.47 sec).
Restored D:\a\1\s\src\TestUtils\src\VisualTestUtils.MagickNet\VisualTestUtils.MagickNet.csproj (in 5.19 sec).
Restored D:\a\1\s\src\TestUtils\src\UITest.Analyzers\UITest.Analyzers.csproj (in 10.92 sec).
Restored D:\a\1\s\src\Controls\tests\CustomAttributes\Controls.CustomAttributes.csproj (in 6 ms).
Restored D:\a\1\s\src\Controls\tests\TestCases.WinUI.Tests\Controls.TestCases.WinUI.Tests.csproj (in 10.26 sec).
7 of 15 projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0\Microsoft.Maui.Graphics.dll
Controls.CustomAttributes -> D:\a\1\s\artifacts\bin\Controls.CustomAttributes\Debug\net10.0\Controls.CustomAttributes.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0\Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0\Microsoft.Maui.dll
Controls.Core.Design -> D:\a\1\s\artifacts\bin\Controls.Core.Design\Debug\net472\Microsoft.Maui.Controls.DesignTools.dll
Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0\Microsoft.Maui.Controls.dll
UITest.Core -> D:\a\1\s\artifacts\bin\UITest.Core\Debug\net10.0\UITest.Core.dll
UITest.Appium -> D:\a\1\s\artifacts\bin\UITest.Appium\Debug\net10.0\UITest.Appium.dll
UITest.NUnit -> D:\a\1\s\artifacts\bin\UITest.NUnit\Debug\net10.0\UITest.NUnit.dll
VisualTestUtils -> D:\a\1\s\artifacts\bin\VisualTestUtils\Debug\netstandard2.0\VisualTestUtils.dll
VisualTestUtils.MagickNet -> D:\a\1\s\artifacts\bin\VisualTestUtils.MagickNet\Debug\netstandard2.0\VisualTestUtils.MagickNet.dll
UITest.Analyzers -> D:\a\1\s\artifacts\bin\UITest.Analyzers\Debug\netstandard2.0\UITest.Analyzers.dll
Controls.TestCases.WinUI.Tests -> D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
Test run for D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
NUnit3TestExecutor discovered 2 of 2 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 6/11/2026 11:48:19 AM FixtureSetup for Issue35216(Windows)
>>>>> 6/11/2026 11:48:31 AM Issue35216SwipeItemInitiallyHiddenBecomesVisibleAfterBindingChanges Start
>>>>> 6/11/2026 11:48:38 AM Issue35216SwipeItemInitiallyHiddenBecomesVisibleAfterBindingChanges Stop
>>>>> 6/11/2026 11:48:38 AM Log types:
Visual difference 0.69% within tolerance 1% for 'Issue35216SwipeOpen_BecomeVisible' on windows
Failed Issue35216SwipeItemInitiallyHiddenBecomesVisibleAfterBindingChanges [8 s]
Error Message:
VisualTestUtils.VisualTestFailedException :
Snapshot different than baseline: Issue35216SwipeOpen_InitiallyHidden.png (3.71% difference)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.
More info: https://aka.ms/visual-test-workflow
Stack Trace:
at Microsoft.Maui.TestCases.Tests.Issues.Issue35216.Issue35216SwipeItemInitiallyHiddenBecomesVisibleAfterBindingChanges() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35216.cs:line 41
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Standard Output Messages:
Visual difference 0.69% within tolerance 1% for 'Issue35216SwipeOpen_BecomeVisible' on windows
>>>>> 6/11/2026 11:48:39 AM Issue35216SwipeItemBecomesHiddenAfterBindingChanges Start
>>>>> 6/11/2026 11:48:45 AM Issue35216SwipeItemBecomesHiddenAfterBindingChanges Stop
>>>>> 6/11/2026 11:48:45 AM Log types:
Failed Issue35216SwipeItemBecomesHiddenAfterBindingChanges [6 s]
Error Message:
VisualTestUtils.VisualTestFailedException :
Snapshot different than baseline: Issue35216SwipeOpen_DeleteHidden.png (3.72% difference)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.
More info: https://aka.ms/visual-test-workflow
Stack Trace:
at Microsoft.Maui.TestCases.Tests.Issues.Issue35216.Issue35216SwipeItemBecomesHiddenAfterBindingChanges() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35216.cs:line 71
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
NUnit Adapter 4.5.0.0: Test execution complete
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.13] Discovering: Controls.TestCases.WinUI.Tests
[xUnit.net 00:00:00.47] Discovered: Controls.TestCases.WinUI.Tests
Results File: D:\a\1\s\CustomAgentLogsTmp\UITests\TestResults\Issue35216.trx
Total tests: 2
Failed: 2
Total time: 47.8178 Seconds
Test Run Failed.
>>> TRX_RESULT_FILE: D:\a\1\s\CustomAgentLogsTmp\UITests\TestResults\Issue35216.trx
🟢 With fix — 🖥️ Issue35216: PASS ✅ · 504s
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Essentials.dll
Graphics.Win2D -> D:\a\1\s\artifacts\bin\Graphics.Win2D\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.dll
Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Controls.Xaml -> D:\a\1\s\artifacts\bin\Controls.Xaml\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Xaml.dll
Microsoft.AspNetCore.Components.WebView.Maui -> D:\a\1\s\artifacts\bin\Microsoft.AspNetCore.Components.WebView.Maui\Debug\net10.0-windows10.0.19041.0\Microsoft.AspNetCore.Components.WebView.Maui.dll
Maps -> D:\a\1\s\artifacts\bin\Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Maps.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Controls.Maps -> D:\a\1\s\artifacts\bin\Controls.Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Maps.dll
Controls.Foldable -> D:\a\1\s\artifacts\bin\Controls.Foldable\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Foldable.dll
Controls.TestCases.HostApp -> D:\a\1\s\artifacts\bin\Controls.TestCases.HostApp\Debug\net10.0-windows10.0.19041.0\win-x64\Controls.TestCases.HostApp.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:06:08.84
Determining projects to restore...
All projects are up-to-date for restore.
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0\Microsoft.Maui.Graphics.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0\Microsoft.Maui.Essentials.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0\Microsoft.Maui.dll
Controls.CustomAttributes -> D:\a\1\s\artifacts\bin\Controls.CustomAttributes\Debug\net10.0\Controls.CustomAttributes.dll
Controls.Core.Design -> D:\a\1\s\artifacts\bin\Controls.Core.Design\Debug\net472\Microsoft.Maui.Controls.DesignTools.dll
Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
##vso[build.updatebuildnumber]10.0.80-ci+azdo.14346781
Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0\Microsoft.Maui.Controls.dll
UITest.Core -> D:\a\1\s\artifacts\bin\UITest.Core\Debug\net10.0\UITest.Core.dll
UITest.NUnit -> D:\a\1\s\artifacts\bin\UITest.NUnit\Debug\net10.0\UITest.NUnit.dll
VisualTestUtils -> D:\a\1\s\artifacts\bin\VisualTestUtils\Debug\netstandard2.0\VisualTestUtils.dll
VisualTestUtils.MagickNet -> D:\a\1\s\artifacts\bin\VisualTestUtils.MagickNet\Debug\netstandard2.0\VisualTestUtils.MagickNet.dll
UITest.Appium -> D:\a\1\s\artifacts\bin\UITest.Appium\Debug\net10.0\UITest.Appium.dll
UITest.Analyzers -> D:\a\1\s\artifacts\bin\UITest.Analyzers\Debug\netstandard2.0\UITest.Analyzers.dll
Controls.TestCases.WinUI.Tests -> D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
Test run for D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
NUnit3TestExecutor discovered 2 of 2 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 6/11/2026 11:56:51 AM FixtureSetup for Issue35216(Windows)
>>>>> 6/11/2026 11:57:03 AM Issue35216SwipeItemInitiallyHiddenBecomesVisibleAfterBindingChanges Start
>>>>> 6/11/2026 11:57:08 AM Issue35216SwipeItemInitiallyHiddenBecomesVisibleAfterBindingChanges Stop
Visual difference 0.68% within tolerance 1% for 'Issue35216SwipeOpen_InitiallyHidden' on windows
Visual difference 0.7% within tolerance 1% for 'Issue35216SwipeOpen_BecomeVisible' on windows
Passed Issue35216SwipeItemInitiallyHiddenBecomesVisibleAfterBindingChanges [5 s]
>>>>> 6/11/2026 11:57:08 AM Issue35216SwipeItemBecomesHiddenAfterBindingChanges Start
>>>>> 6/11/2026 11:57:14 AM Issue35216SwipeItemBecomesHiddenAfterBindingChanges Stop
Visual difference 0.56% within tolerance 1% for 'Issue35216SwipeOpen_DeleteVisible' on windows
Visual difference 0.7% within tolerance 1% for 'Issue35216SwipeOpen_DeleteHidden' on windows
Passed Issue35216SwipeItemBecomesHiddenAfterBindingChanges [5 s]
NUnit Adapter 4.5.0.0: Test execution complete
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.27] Discovering: Controls.TestCases.WinUI.Tests
[xUnit.net 00:00:00.61] Discovered: Controls.TestCases.WinUI.Tests
Results File: D:\a\1\s\CustomAgentLogsTmp\UITests\TestResults\Issue35216.trx
Test Run Successful.
Total tests: 2
Passed: 2
Total time: 38.5725 Seconds
>>> TRX_RESULT_FILE: D:\a\1\s\CustomAgentLogsTmp\UITests\TestResults\Issue35216.trx
📁 Fix files reverted (4 files)
eng/pipelines/ci-copilot.ymlsrc/Controls/src/Core/SwipeView/SwipeItem.cssrc/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.Windows.cssrc/Core/src/Handlers/SwipeView/SwipeViewHandler.Windows.cs
UI Tests — SwipeView,ViewBaseTests
Detected UI test categories: SwipeView,ViewBaseTests
✅ Deep UI tests — 136 passed, 0 failed across 2 categories on platform-pool agent (replaces in-process counts above).
🧪 UI Test Execution Results (deep, platform pool)
| Category | Tests | Snapshot diffs |
|---|---|---|
SwipeView |
21/21 ✓ | 3 diff PNGs |
ViewBaseTests |
115/115 ✓ | — |
📎 Download drop-deep-uitests artifact (TRX + snapshot diffs) |
Pre-Flight — Context & Validation
Issue: #35216 - [Windows] SwipeItem.IsVisible has no effect on Windows
PR: #35361 - [Windows] Fix SwipeItem IsVisible not refreshing native swipe items when binding changes
Platforms Affected: Windows
Files Changed: 3 implementation, 6 test/snapshot
Key Findings
- Issue #35216 reports that toggling
SwipeItem.IsVisibledynamically hides the item on Android but has no effect on Windows; the item remains visible after binding changes. - PR #35361 fixes this by adding a
SwipeItem.IsVisibleproperty-changed callback, rebuilding the owning WindowsSwipeViewswipe item collection fromMapVisibility, creating handlers for collapsed items, and filtering collapsed items out of the native WinUI collection. - Prior inline feedback flagged re-entrancy during initial handler setup and fragile
Parent?.Parentlookup; the current PR revision addresses those with a SwipeView rebuild guard and ancestor walk. - Test type is Windows UI test coverage in
UITestCategories.SwipeViewfor issue 35216.
Code Review Summary
Verdict: NEEDS_DISCUSSION
Confidence: medium
Errors: 0 | Warnings: 1 | Suggestions: 0
Key code review findings:
- Required CI is not green. Static review found no actionable code defects, but CI failures/cancellations need rerun or classification before final approval.
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #35361 | Add SwipeItem.IsVisible property-changed callback, rebuild the owning Windows SwipeView item collection from the child item mapper, guard re-entrancy during handler creation, and filter collapsed items from native WinUI SwipeItems. |
PASSED (Gate) | SwipeItem.cs, SwipeItemMenuItemHandler.Windows.cs, SwipeViewHandler.Windows.cs, Windows UI tests/snapshots |
Original PR |
Code Review — Deep Analysis
Code Review PR #35361
Independent Assessment
What this changes: Adds a Controls-layer SwipeItem.IsVisible property-changed callback that updates the ISwipeItemMenuItem.Visibility mapper, and implements the Windows mapper by rebuilding the owning SwipeView item collection. Windows CreateSwipeItems now creates handlers for collapsed menu items so later visibility changes can reach a handler, while only adding visible items to the native SwipeItems collection. The PR also adds a Windows HostApp regression page, UI tests, and snapshots for toggling a bound Delete SwipeItem.
Inferred motivation: WinUI SwipeItem has no native Visibility property, so a bound SwipeItem.IsVisible change previously did not refresh the native swipe menu unless the entire SwipeItems collection was rebuilt.
Reconciliation with PR Narrative
Author claims: The PR says it fixes Windows SwipeItem.IsVisible not refreshing native swipe items when bindings change, by adding a property-changed callback, Windows handler rebuild logic, and Windows UI coverage for issue #35216.
Agreement/disagreement: This matches the code. The Windows-specific mapper rebuild is a reasonable workaround for WinUI's missing per-item visibility support. The added re-entrancy guard addresses the main risk from calling UpdateValue while creating child item handlers. The cross-platform Controls callback will also trigger existing non-empty Android/iOS/Tizen mappers, but the PR intentionally scopes test coverage to Windows.
Findings
No actionable code findings. The expert reviewer returned no inline findings, and my independent pass did not find a concrete defect on added/modified lines that should block on code changes.
Warning Required CI is not green
maui-pr is failing in the Windows Release build, with the first observed error in Azure DevOps: .buildtasks\Microsoft.Maui.Core.After.targets(8,3): error MSB4024: ... Microsoft.Maui.Core.BundledVersions.targets could not be loaded. maui-pr-uitests also has macOS UI failures/cancellations (WebView failure, CollectionView/Shell timeouts). These do not appear directly caused by the Windows SwipeView code, but required CI is not green, so I cannot mark the PR LGTM until CI is rerun/understood.
Devil's Advocate
The riskiest part is rebuilding the parent SwipeView from a child SwipeItem mapper. I specifically checked initial handler creation/re-entrancy: CreateSwipeItems sets _isRebuildingSwipeItems before item.ToHandler(...), and all four item mappers return while that guard is set, so the previous recursion concern is mitigated. I also checked repeated visibility toggles: existing handlers are reused by ToHandler, while the rebuilt native collection filters on menuItem.Visibility, which matches the intended behavior. I cannot fully validate WinUI runtime animation/snapshot stability from static review, and CI is currently not green.
Verdict: NEEDS_DISCUSSION
Confidence: medium
Summary: The code approach looks sound and I have no actionable code-change requests. However, required CI is failing, so this should not be treated as ready for approval until the CI failures are rerun or classified as unrelated infrastructure/flakes.
Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix-1 | Windows SwipeViewHandler observes swipe-item PropertyChanged events, caches virtual-to-native item mappings, and synchronizes the native WSwipeItems collection in place when IsVisible changes. |
PASS | 1 file | Simpler than PR: avoids Controls-layer callback, child-to-parent mapper update, parent walking, and re-entrancy guard. |
| PR | PR #35361 | SwipeItem.IsVisible property-changed callback updates the child item handler; Windows child mapper walks to parent SwipeView and asks the matching side to rebuild; parent handler creates handlers for collapsed items and filters them out with a rebuild guard. |
PASSED (Gate) | 3 implementation files + tests | Original PR. |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| claude-opus-4.6 | 1 | Yes | Produced Candidate 1: observer/synchronization inside SwipeViewHandler.Windows.cs. |
| remaining models | N/A | Not run | Stop criteria met: Candidate 1 passed all tests and is demonstrably simpler/better than the PR fix, so additional candidates would be lower-value variations. |
Exhausted: No - stopped because Candidate 1 passed all tests and is demonstrably better than the PR's current fix.
Selected Fix: Candidate #1 - It preserves the same Windows behavior validated by the regression tests while reducing implementation surface from three implementation files to one, avoiding cross-handler UpdateValue re-entrancy, avoiding parent-chain lookup from child handlers, and reusing existing native item handlers.
Candidate 1 Details
Approach: Observer pattern at the Windows SwipeViewHandler level. Subscribe to item property changes while creating native swipe items, cache each ISwipeItemMenuItem to its WSwipeItem, and on IsVisible changes clear/re-add only visible cached native items for the affected side.
Test Results: PASS. BuildAndRunHostApp.ps1 -Platform windows -TestFilter "Issue35216" completed successfully; both issue 35216 UI tests passed with screenshot comparisons within tolerance.
Failure Analysis: Not applicable; candidate passed. Self-review recorded 0 findings.
Diff:
diff --git a/src/Core/src/Handlers/SwipeView/SwipeViewHandler.Windows.cs b/src/Core/src/Handlers/SwipeView/SwipeViewHandler.Windows.cs
index fea1902e2d..699bff1bfd 100644
--- a/src/Core/src/Handlers/SwipeView/SwipeViewHandler.Windows.cs
+++ b/src/Core/src/Handlers/SwipeView/SwipeViewHandler.Windows.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.ComponentModel;
using System.Linq;
using Microsoft.Maui.Graphics;
using WSwipeControl = Microsoft.UI.Xaml.Controls.SwipeControl;
@@ -9,6 +11,11 @@ namespace Microsoft.Maui.Handlers
{
public partial class SwipeViewHandler : ViewHandler<ISwipeView, WSwipeControl>
{
+ // Tracks the association between virtual swipe items and their native counterparts
+ // so we can surgically add/remove native items when visibility changes.
+ readonly Dictionary<ISwipeItemMenuItem, WSwipeItem> _itemHandlerMap = new();
+ readonly HashSet<INotifyPropertyChanged> _subscribedItems = new();
+
protected override WSwipeControl CreatePlatformView() => new();
public override void SetVirtualView(IView view)
@@ -63,6 +70,70 @@ namespace Microsoft.Maui.Handlers
{
base.DisconnectHandler(platformView);
platformView.Loaded -= OnLoaded;
+ UnsubscribeAllItems();
+ }
+
+ void UnsubscribeAllItems()
+ {
+ foreach (var item in _subscribedItems)
+ {
+ item.PropertyChanged -= OnSwipeItemPropertyChanged;
+ }
+ _subscribedItems.Clear();
+ _itemHandlerMap.Clear();
+ }
+
+ void OnSwipeItemPropertyChanged(object? sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName != "IsVisible" || sender is not ISwipeItemMenuItem menuItem)
+ return;
+
+ if (!PlatformView.IsLoaded)
+ return;
+
+ // Find which native collection this item belongs to and synchronize
+ SyncItemVisibility(menuItem);
+ }
+
+ void SyncItemVisibility(ISwipeItemMenuItem menuItem)
+ {
+ var swipeView = VirtualView;
+ if (swipeView == null)
+ return;
+
+ if (swipeView.LeftItems?.Contains(menuItem) == true)
+ SyncNativeCollection(PlatformView.LeftItems, swipeView.LeftItems);
+ else if (swipeView.RightItems?.Contains(menuItem) == true)
+ SyncNativeCollection(PlatformView.RightItems, swipeView.RightItems);
+ else if (swipeView.TopItems?.Contains(menuItem) == true)
+ SyncNativeCollection(PlatformView.TopItems, swipeView.TopItems);
+ else if (swipeView.BottomItems?.Contains(menuItem) == true)
+ SyncNativeCollection(PlatformView.BottomItems, swipeView.BottomItems);
+ }
+
+ void SyncNativeCollection(WSwipeItems? nativeItems, ISwipeItems virtualItems)
+ {
+ if (nativeItems == null)
+ return;
+
+ // Rebuild the native collection contents based on current visibility.
+ // We clear and re-add only visible items using our cached handler map,
+ // without recreating handlers.
+ nativeItems.Clear();
+
+ foreach (var item in virtualItems)
+ {
+ if (item is ISwipeItemMenuItem menuItem &&
+ menuItem.Visibility != Visibility.Collapsed &&
+ _itemHandlerMap.TryGetValue(menuItem, out var nativeItem))
+ {
+ if (CanAddSwipeItems(nativeItems))
+ {
+ nativeItem.BehaviorOnInvoked = virtualItems.SwipeBehaviorOnInvoked.ToPlatform();
+ nativeItems.Add(nativeItem);
+ }
+ }
+ }
}
void OnLoaded(object sender, UI.Xaml.RoutedEventArgs e)
@@ -180,11 +251,29 @@ namespace Microsoft.Maui.Handlers
foreach (var item in items)
{
- if (CanAddSwipeItems(swipeItems) && item is ISwipeItemMenuItem &&
+ if (item is ISwipeItemMenuItem menuItem &&
item.ToHandler(handler.MauiContext!).PlatformView is WSwipeItem swipeItem)
{
- swipeItem.BehaviorOnInvoked = items.SwipeBehaviorOnInvoked.ToPlatform();
- swipeItems.Add(swipeItem);
+ // Always track the mapping for later visibility synchronization,
+ // regardless of current visibility or Execute mode limits.
+ if (handler is SwipeViewHandler concreteHandler)
+ {
+ concreteHandler._itemHandlerMap[menuItem] = swipeItem;
+
+ if (item is INotifyPropertyChanged notifiable &&
+ !concreteHandler._subscribedItems.Contains(notifiable))
+ {
+ notifiable.PropertyChanged += concreteHandler.OnSwipeItemPropertyChanged;
+ concreteHandler._subscribedItems.Add(notifiable);
+ }
+ }
+
+ // Only add visible items (respecting Execute mode limit) to the native collection
+ if (menuItem.Visibility != Visibility.Collapsed && CanAddSwipeItems(swipeItems))
+ {
+ swipeItem.BehaviorOnInvoked = items.SwipeBehaviorOnInvoked.ToPlatform();
+ swipeItems.Add(swipeItem);
+ }
}
}
Report — Final Recommendation
Comparative Candidate Report
Candidates
| Candidate | Result | Summary |
|---|---|---|
pr |
PASS | Submitted PR fix. Adds SwipeItem.IsVisible property-change propagation, maps Windows visibility by rebuilding the owning SwipeView item side, creates handlers for collapsed items, and filters collapsed items out of the native WinUI collection. Expert review found no actionable code findings. |
pr-plus-reviewer |
PASS | Same as pr; the expert reviewer produced no actionable feedback to apply. |
try-fix-1 |
PASS | Alternative one-file Windows SwipeViewHandler observer/cache implementation. It passed the regression tests and is smaller, but it adds manual PropertyChanged subscriptions and virtual-to-native item caches that must remain synchronized with collection replacement and handler lifecycle. |
Analysis
All available candidates passed the regression gate, so the winner is selected on correctness and lifecycle safety rather than test result priority. try-fix-1 is attractive because it keeps the fix in one Windows handler file and avoids child-to-parent mapper updates, but its implementation introduces long-lived subscriptions and cached mappings for swipe items. That creates additional lifecycle/cache-invalidation surface when swipe item collections are replaced or items are removed, even if the specific issue regression passes.
The submitted PR fix is broader, but it uses the existing mapper/update pipeline and avoids adding new event subscriptions or native-item caches. The expert reviewer found no actionable defects in the PR diff, and the current PR revision already addresses the earlier re-entrancy and fragile-parent-walk concerns noted in pre-flight context.
Winner
pr wins. pr-plus-reviewer is equivalent because no reviewer changes were needed; try-fix-1 is ranked lower despite passing tests because its manual observer/cache approach has higher lifecycle maintenance risk than the PR's mapper-based rebuild.
Future Action — review latest findings
No alternative fix was selected for this run. Review the session findings and CI results before merging.
…hen binding changes (#35361) <!-- Please keep the note below for people who 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 whether this change resolves your issue. Thank you! <!-- !!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING MAIN. !!!!!!! --> This pull request addresses an issue where changes to the `IsVisible` property of `SwipeItem` were not properly reflected in the native UI, especially on Windows. The main updates ensure that dynamic visibility changes to swipe items are accurately propagated and tested. The changes include updates to property change handling, platform-specific handler logic, and the addition of new tests to verify the fix. ### Description of Change **SwipeItem Visibility Handling Improvements:** * Added a `propertyChanged` callback (`OnIsVisibleChanged`) to the `IsVisibleProperty` bindable property in `SwipeItem`, ensuring that UI updates occur when visibility changes. (`src/Controls/src/Core/SwipeView/SwipeItem.cs`) [[1]](diffhunk://#diff-02137eba63ee191b8329fd05cccc083f8c9341ffd9891773420fb3cb9753c4b9L17-R17) [[2]](diffhunk://#diff-02137eba63ee191b8329fd05cccc083f8c9341ffd9891773420fb3cb9753c4b9L38-R42) * Implemented the `OnIsVisibleChanged` method to call the handler's `UpdateValue` for visibility, triggering necessary UI updates. (`src/Controls/src/Core/SwipeView/SwipeItem.cs`) **Windows Platform Handler Logic:** * Updated the `MapVisibility` method in the Windows-specific `SwipeItemMenuItemHandler` to rebuild the parent `SwipeView`'s swipe items when a child item's visibility changes, working around the lack of direct visibility support in WinUI's `SwipeItem`. (`src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.Windows.cs`) * Modified `CreateSwipeItems` in the Windows `SwipeViewHandler` to always create handlers for swipe items (regardless of visibility) so that visibility changes can be propagated later, but only add visible items to the UI. (`src/Core/src/Handlers/SwipeView/SwipeViewHandler.Windows.cs`) **Automated Test Coverage:** * Added a new test case and view model (`Issue35216.cs`) to verify that toggling the visibility of a `SwipeItem` updates the UI as expected. (`src/Controls/tests/TestCases.HostApp/Issues/Issue35216.cs`) * Introduced automated UI tests for Windows to check that swipe items appear and disappear correctly when their visibility is toggled via data binding. (`src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35216.cs`) <!-- Enter description of the fix in this section --> ### Issues Fixed <!-- Please make sure that there is a bug logged for the issue being fixed. The bug should describe the problem and how to reproduce it. --> Fixes #35216 ### Tested the behavior in the following platforms - [x] Windows - [ ] Android - [ ] iOS - [ ] Mac | Before Issue Fix | After Issue Fix | |----------|----------| | <video src="https://github.com/user-attachments/assets/1f4f4d06-f564-4501-b1d0-7e6595ad1a8e"> | <video src="https://github.com/user-attachments/assets/6c6ea397-c06c-4a81-a85d-7f3727be18fd"> | <!-- Are you targeting main? All PRs should target the main branch unless otherwise noted. -->
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 whether this change resolves your issue. Thank you!
This pull request addresses an issue where changes to the
IsVisibleproperty ofSwipeItemwere not properly reflected in the native UI, especially on Windows. The main updates ensure that dynamic visibility changes to swipe items are accurately propagated and tested. The changes include updates to property change handling, platform-specific handler logic, and the addition of new tests to verify the fix.Description of Change
SwipeItem Visibility Handling Improvements:
propertyChangedcallback (OnIsVisibleChanged) to theIsVisiblePropertybindable property inSwipeItem, ensuring that UI updates occur when visibility changes. (src/Controls/src/Core/SwipeView/SwipeItem.cs) [1] [2]OnIsVisibleChangedmethod to call the handler'sUpdateValuefor visibility, triggering necessary UI updates. (src/Controls/src/Core/SwipeView/SwipeItem.cs)Windows Platform Handler Logic:
MapVisibilitymethod in the Windows-specificSwipeItemMenuItemHandlerto rebuild the parentSwipeView's swipe items when a child item's visibility changes, working around the lack of direct visibility support in WinUI'sSwipeItem. (src/Core/src/Handlers/SwipeItemMenuItem/SwipeItemMenuItemHandler.Windows.cs)CreateSwipeItemsin the WindowsSwipeViewHandlerto always create handlers for swipe items (regardless of visibility) so that visibility changes can be propagated later, but only add visible items to the UI. (src/Core/src/Handlers/SwipeView/SwipeViewHandler.Windows.cs)Automated Test Coverage:
Issue35216.cs) to verify that toggling the visibility of aSwipeItemupdates the UI as expected. (src/Controls/tests/TestCases.HostApp/Issues/Issue35216.cs)src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35216.cs)Issues Fixed
Fixes #35216
Tested the behavior in the following platforms
BeforeFix35216.mp4
AfterFix35216.mp4