Skip to content

[MacCatalyst] Fix DatePicker Opened/Closed events not being raised#34970

Merged
kubaflo merged 7 commits into
dotnet:inflight/currentfrom
SubhikshaSf4851:Fix-34848
Apr 16, 2026
Merged

[MacCatalyst] Fix DatePicker Opened/Closed events not being raised#34970
kubaflo merged 7 commits into
dotnet:inflight/currentfrom
SubhikshaSf4851:Fix-34848

Conversation

@SubhikshaSf4851
Copy link
Copy Markdown
Contributor

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 the issue where the DatePicker control on MacCatalyst did not correctly raise its Opened and Closed events. The changes implement a more robust mechanism for detecting when the DatePicker is opened and closed, specifically for MacCatalyst, and add new tests to verify this behavior.

Description of Change :

MacCatalyst DatePicker Event Handling Improvements:

  • Added logic to traverse the internal view hierarchy of the compact UIDatePicker to find and wire up UITextField subviews, allowing detection of when the DatePicker is opened via the EditingDidBegin event. A one-shot observer is registered to detect when the picker popover window closes, ensuring the Closed event is raised reliably. (DatePickerHandler.MacCatalyst.cs)
  • Implemented cleanup logic to unwire event handlers and remove observers during disconnect, preventing memory leaks and spurious event firing. (DatePickerHandler.MacCatalyst.cs)
  • Removed previous event handler attachments (EditingDidBegin/EditingDidEnd) from the proxy, as the new mechanism supersedes them. (DatePickerHandler.MacCatalyst.cs) [1] [2]

Testing Enhancements:

  • Added a new test case page (Issue34848) and a corresponding UI test to verify that the Opened and Closed events are raised correctly on MacCatalyst and other platforms, using platform-specific logic to close the DatePicker. (TestCases.HostApp/Issues/Issue34848.cs, TestCases.Shared.Tests/Tests/Issues/Issue34848.cs) [1] [2]

General Codebase Improvements:

  • Minor code cleanup and improved organization in the DatePicker handler for MacCatalyst, including the addition of necessary using directives. (DatePickerHandler.MacCatalyst.cs)

Issues Fixed

Fixes #34848

Tested the behavior in the following platforms

  • Windows
  • Android
  • iOS
  • Mac
Before Issue Fix After Issue Fix
BeforeFix34848.mov
AfterFix34848.mov

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 15, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34970

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34970"

@dotnet-policy-service dotnet-policy-service Bot added the community ✨ Community Contribution label Apr 15, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

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.

@dotnet-policy-service dotnet-policy-service Bot added the partner/syncfusion Issues / PR's with Syncfusion collaboration label Apr 15, 2026
@Tamilarasan-Paranthaman Tamilarasan-Paranthaman added platform/macos macOS / Mac Catalyst area-controls-datetimepicker DatePicker, TimePicker labels Apr 15, 2026
@sheiksyedm sheiksyedm marked this pull request as ready for review April 15, 2026 10:55
Copilot AI review requested due to automatic review settings April 15, 2026 10:55
@sheiksyedm
Copy link
Copy Markdown
Contributor

/azp run maui-pr-uitests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes MacCatalyst DatePicker Opened/Closed event behavior by hooking into the compact UIDatePicker’s internal text field lifecycle and observing popover/window close, plus adds a regression UI test for issue #34848.

Changes:

  • MacCatalyst: traverse UIDatePicker subviews to wire UITextField.EditingDidBegin and observe window-close to reliably toggle IsOpen/IsFocused.
  • MacCatalyst: add disconnect cleanup to unwire text field handlers and remove the notification observer.
  • Tests: add HostApp issue page + Appium UI test validating Opened/Closed events.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/Core/src/Handlers/DatePicker/DatePickerHandler.MacCatalyst.cs Adds MacCatalyst-specific open/close detection via internal text fields + window-close observer, with cleanup on disconnect.
src/Controls/tests/TestCases.HostApp/Issues/Issue34848.cs New HostApp repro page that updates labels when DatePicker.Opened/Closed fire.
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34848.cs New UI test that opens/closes the DatePicker and asserts both events were raised.

Comment thread src/Controls/tests/TestCases.HostApp/Issues/Issue34848.cs Outdated
Comment thread src/Core/src/Handlers/DatePicker/DatePickerHandler.MacCatalyst.cs
Comment thread src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34848.cs Outdated
@MauiBot
Copy link
Copy Markdown
Collaborator

MauiBot commented Apr 15, 2026

🚦 Gate — Test Before and After Fix

👋 @SubhikshaSf4851 — new gate results are available. Please review the latest session below.

🚦 Gate Sessionfe3199d · Updated sugggestion · 2026-04-16 11:33 UTC

Gate Result: ✅ PASSED

Platform: CATALYST · Base: main · Merge base: eb0b82fe

Test Without Fix (expect FAIL) With Fix (expect PASS)
🖥️ Issue34848 Issue34848 ✅ FAIL — 128s ✅ PASS — 90s
🔴 Without fix — 🖥️ Issue34848: FAIL ✅ · 128s
  Determining projects to restore...
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 1.09 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 5.17 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Xaml/Controls.Xaml.csproj (in 5.8 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 5.8 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/maps/src/Maps.csproj (in 5.81 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 5.8 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj (in 5.8 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/Foldable/src/Controls.Foldable.csproj (in 5.81 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/Maps/src/Controls.Maps.csproj (in 5.81 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj (in 5.92 sec).
  1 of 11 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Maps.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Controls.Xaml.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-maccatalyst26.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Foldable -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Controls.Foldable.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Controls.Maps.dll
  Detected signing identity:
    Code Signing Key: "" (-)
    Provisioning Profile: "" () - no entitlements
    Bundle Id: com.microsoft.maui.uitests
    App Id: com.microsoft.maui.uitests
  Detected signing identity:
    Code Signing Key: "" (-)
    Provisioning Profile: "" () - no entitlements
    Bundle Id: com.microsoft.maui.uitests
    App Id: com.microsoft.maui.uitests
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.TestCases.HostApp -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-maccatalyst/maccatalyst-x64/Controls.TestCases.HostApp.dll
  Optimizing assemblies for size may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
  Optimizing assemblies for size. This process might take a while.
  Detected signing identity:
    Code Signing Key: "" (-)
    Provisioning Profile: "" () - no entitlements
    Bundle Id: com.microsoft.maui.uitests
    App Id: com.microsoft.maui.uitests
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.TestCases.HostApp -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-maccatalyst/maccatalyst-arm64/Controls.TestCases.HostApp.dll
  Optimizing assemblies for size may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
  Optimizing assemblies for size. This process might take a while.

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:01:03.26
  Determining projects to restore...
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Core/UITest.Core.csproj (in 688 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/CustomAttributes/Controls.CustomAttributes.csproj (in 721 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/VisualTestUtils/VisualTestUtils.csproj (in 721 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.NUnit/UITest.NUnit.csproj (in 1.18 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Appium/UITest.Appium.csproj (in 1.47 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Analyzers/UITest.Analyzers.csproj (in 3 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/VisualTestUtils.MagickNet/VisualTestUtils.MagickNet.csproj (in 17.65 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.Mac.Tests/Controls.TestCases.Mac.Tests.csproj (in 17.7 sec).
  5 of 13 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.CustomAttributes -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
  Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  UITest.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
  VisualTestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
  VisualTestUtils.MagickNet -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
  UITest.NUnit -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
  UITest.Appium -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
  UITest.Analyzers -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
  Controls.TestCases.Mac.Tests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.Mac.Tests/Debug/net10.0/Controls.TestCases.Mac.Tests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.Mac.Tests/Debug/net10.0/Controls.TestCases.Mac.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
/Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.Mac.Tests/Debug/net10.0/Controls.TestCases.Mac.Tests.dll
[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.04]   Discovering: Controls.TestCases.Mac.Tests
[xUnit.net 00:00:00.12]   Discovered:  Controls.TestCases.Mac.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.Mac.Tests/Debug/net10.0/Controls.TestCases.Mac.Tests.dll
   NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 4/16/2026 4:32:13 AM FixtureSetup for Issue34848(Mac)
>>>>> 4/16/2026 4:32:13 AM DatePickerOpenedAndClosedEventsAreRaised Start
>>>>> 4/16/2026 4:32:18 AM DatePickerOpenedAndClosedEventsAreRaised Stop
>>>>> 4/16/2026 4:32:18 AM Log types: 
  Failed DatePickerOpenedAndClosedEventsAreRaised [5 s]
  Error Message:
     Assert.That(App.WaitForElement("Issue34848OpenStatusLabel").GetText(), Is.EqualTo("Opened"))
  Expected string length 6 but was 15. Strings differ at index 6.
  Expected: "Opened"
  But was:  "Opened: Unknown"
  -----------------^

  Stack Trace:
     at Microsoft.Maui.TestCases.Tests.Issues.Issue34848.DatePickerOpenedAndClosedEventsAreRaised() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34848.cs:line 38

1)    at Microsoft.Maui.TestCases.Tests.Issues.Issue34848.DatePickerOpenedAndClosedEventsAreRaised() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34848.cs:line 38


NUnit Adapter 4.5.0.0: Test execution complete

Total tests: 1
     Failed: 1
Test Run Failed.
 Total time: 18.1909 Seconds

🟢 With fix — 🖥️ Issue34848: PASS ✅ · 90s
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Maps.dll
  Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Controls.Maps.dll
  Controls.Foldable -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Controls.Foldable.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-maccatalyst26.0/Microsoft.Maui.Controls.Xaml.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-maccatalyst26.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Detected signing identity:
    Code Signing Key: "" (-)
    Provisioning Profile: "" () - no entitlements
    Bundle Id: com.microsoft.maui.uitests
    App Id: com.microsoft.maui.uitests
  Detected signing identity:
    Code Signing Key: "" (-)
    Provisioning Profile: "" () - no entitlements
    Bundle Id: com.microsoft.maui.uitests
    App Id: com.microsoft.maui.uitests
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.TestCases.HostApp -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-maccatalyst/maccatalyst-x64/Controls.TestCases.HostApp.dll
  Optimizing assemblies for size may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
  Optimizing assemblies for size. This process might take a while.
  Detected signing identity:
    Code Signing Key: "" (-)
    Provisioning Profile: "" () - no entitlements
    Bundle Id: com.microsoft.maui.uitests
    App Id: com.microsoft.maui.uitests
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.TestCases.HostApp -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-maccatalyst/maccatalyst-arm64/Controls.TestCases.HostApp.dll
  Optimizing assemblies for size may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink
  Optimizing assemblies for size. This process might take a while.

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:56.20
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.CustomAttributes -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
  Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13856004
  Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  UITest.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
  VisualTestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
  UITest.Appium -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
  VisualTestUtils.MagickNet -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
  UITest.NUnit -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
  UITest.Analyzers -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
  Controls.TestCases.Mac.Tests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.Mac.Tests/Debug/net10.0/Controls.TestCases.Mac.Tests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.Mac.Tests/Debug/net10.0/Controls.TestCases.Mac.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (arm64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
/Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.Mac.Tests/Debug/net10.0/Controls.TestCases.Mac.Tests.dll
[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.04]   Discovering: Controls.TestCases.Mac.Tests
[xUnit.net 00:00:00.13]   Discovered:  Controls.TestCases.Mac.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.Mac.Tests/Debug/net10.0/Controls.TestCases.Mac.Tests.dll
   NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 4/16/2026 4:33:44 AM FixtureSetup for Issue34848(Mac)
>>>>> 4/16/2026 4:33:44 AM DatePickerOpenedAndClosedEventsAreRaised Start
>>>>> 4/16/2026 4:33:49 AM DatePickerOpenedAndClosedEventsAreRaised Stop
  Passed DatePickerOpenedAndClosedEventsAreRaised [5 s]
NUnit Adapter 4.5.0.0: Test execution complete

Test Run Successful.
Total tests: 1
     Passed: 1
 Total time: 12.2314 Seconds

📁 Fix files reverted (1 files)
  • src/Core/src/Handlers/DatePicker/DatePickerHandler.MacCatalyst.cs


🚦 Gate Session846faa4 · modified observer changes · 2026-04-15 17:09 UTC

Gate Result: ⚠️ ENV ERROR

Platform: ANDROID · Base: main · Merge base: 5fef66dd

Test Without Fix (expect FAIL) With Fix (expect PASS)
🖥️ Issue34848 Issue34848 ⚠️ ENV ERROR ✅ PASS — 542s
🔴 Without fix — 🖥️ Issue34848: ⚠️ ENV ERROR · 1791s

(truncated to last 15,000 chars)

or ADB0010:    at Xamarin.Android.Tasks.FastDeploy.InstallPackage(Boolean installed) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at Xamarin.Android.Tasks.FastDeploy.InstallPackage(Boolean installed) [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
/home/vsts/work/1/s/.dotnet/packs/Microsoft.Android.Sdk.Linux/36.1.2/tools/Xamarin.Android.Common.Debugging.targets(333,5): error ADB0010:    at Xamarin.Android.Tasks.FastDeploy.RunInstall() [/home/vsts/work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-android]
    0 Warning(s)
    1 Error(s)

Time Elapsed 00:16:40.23
* daemon not running; starting now at tcp:5037
* daemon started successfully
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0-android36.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0-android36.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0-android36.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Maps -> /home/vsts/work/1/s/artifacts/bin/Maps/Debug/net10.0-android36.0/Microsoft.Maui.Maps.dll
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-android36.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Foldable.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-android36.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Xaml.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Maps.dll
  Controls.TestCases.HostApp -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Controls.TestCases.HostApp.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Maps.dll
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Xaml.dll
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Foldable.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.AspNetCore.Components.WebView.Maui.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Maps.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:08:52.98
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
  Determining projects to restore...
  Restored /home/vsts/work/1/s/src/TestUtils/src/VisualTestUtils/VisualTestUtils.csproj (in 1.62 sec).
  Restored /home/vsts/work/1/s/src/Controls/tests/CustomAttributes/Controls.CustomAttributes.csproj (in 15 ms).
  Restored /home/vsts/work/1/s/src/TestUtils/src/VisualTestUtils.MagickNet/VisualTestUtils.MagickNet.csproj (in 4.23 sec).
  Restored /home/vsts/work/1/s/src/Controls/tests/TestCases.Android.Tests/Controls.TestCases.Android.Tests.csproj (in 5.92 sec).
  Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.Core/UITest.Core.csproj (in 2 ms).
  Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.Appium/UITest.Appium.csproj (in 2 ms).
  Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.NUnit/UITest.NUnit.csproj (in 515 ms).
  Restored /home/vsts/work/1/s/src/TestUtils/src/UITest.Analyzers/UITest.Analyzers.csproj (in 1.94 sec).
  5 of 13 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Controls.CustomAttributes -> /home/vsts/work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  VisualTestUtils -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
  UITest.Core -> /home/vsts/work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
  VisualTestUtils.MagickNet -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
  UITest.NUnit -> /home/vsts/work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
  UITest.Appium -> /home/vsts/work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
  UITest.Analyzers -> /home/vsts/work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
  Controls.TestCases.Android.Tests -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.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.
/home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
[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.11]   Discovering: Controls.TestCases.Android.Tests
[xUnit.net 00:00:00.37]   Discovered:  Controls.TestCases.Android.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
   NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 04/15/2026 16:59:28 FixtureSetup for Issue34848(Android)
>>>>> 04/15/2026 16:59:45 The FixtureSetup threw an exception. Attempt 0/1.
Exception details: System.TimeoutException: DatePicker Opened and Closed events are not raised on MacCatalyst
   at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
   at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
   at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
   at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
>>>>> 04/15/2026 16:59:48 FixtureSetup for Issue34848(Android)
>>>>> 04/15/2026 17:00:04 The FixtureSetup threw an exception. Attempt 1/1.
Exception details: System.TimeoutException: DatePicker Opened and Closed events are not raised on MacCatalyst
   at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
   at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
   at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
   at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
>>>>> 04/15/2026 17:00:04 Log types: logcat, bugreport, server
>>>>> 04/15/2026 17:00:05 Log types: logcat, bugreport, server
  Failed DatePickerOpenedAndClosedEventsAreRaised [48 s]
  Error Message:
   OneTimeSetUp: System.TimeoutException : DatePicker Opened and Closed events are not raised on MacCatalyst
  Stack Trace:
     at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
   at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
   at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
   at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
   at UITest.Appium.NUnit.UITestBase.OneTimeSetup() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 221
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
   at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)

Setup failed for test fixture Microsoft.Maui.TestCases.Tests.Issues.Issue34848(Android)
System.TimeoutException : DatePicker Opened and Closed events are not raised on MacCatalyst
StackTrace:    at UITest.Appium.HelperExtensions.Wait(Func`1 query, Func`2 satisfactory, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2757
   at UITest.Appium.HelperExtensions.WaitForAtLeastOne(Func`1 query, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 2784
   at UITest.Appium.HelperExtensions.WaitForElement(IApp app, String marked, String timeoutMessage, Nullable`1 timeout, Nullable`1 retryFrequency, Nullable`1 postTimeout) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 793
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.NavigateToIssue(String issue) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 54
   at Microsoft.Maui.TestCases.Tests._IssuesUITest.TryToResetTestState() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/_IssuesUITest.cs:line 25
   at Microsoft.Maui.TestCases.Tests.UITest.FixtureSetup() in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 576
   at UITest.Appium.NUnit.UITestBase.OneTimeSetup() in /_/src/TestUtils/src/UITest.NUnit/UITestBase.cs:line 221
   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

Total tests: 1
     Failed: 1
Test Run Failed.
 Total time: 59.5078 Seconds

🟢 With fix — 🖥️ Issue34848: PASS ✅ · 542s
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0-android36.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0-android36.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0-android36.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Maps -> /home/vsts/work/1/s/artifacts/bin/Maps/Debug/net10.0-android36.0/Microsoft.Maui.Maps.dll
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-android36.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Foldable.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-android36.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Xaml.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-android36.0/Microsoft.Maui.Controls.Maps.dll
  Controls.TestCases.HostApp -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Controls.TestCases.HostApp.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Maps.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Controls.Foldable -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Foldable.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Xaml -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Xaml.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Controls.Maps -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-android/Microsoft.Maui.Controls.Maps.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:06:58.79
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
Broadcasting: Intent { act=android.intent.action.CLOSE_SYSTEM_DIALOGS flg=0x400000 }
Broadcast completed: result=0
  Determining projects to restore...
  All projects are up-to-date for restore.
  Controls.CustomAttributes -> /home/vsts/work/1/s/artifacts/bin/Controls.CustomAttributes/Debug/net10.0/Controls.CustomAttributes.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Graphics -> /home/vsts/work/1/s/artifacts/bin/Graphics/Debug/net10.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Essentials -> /home/vsts/work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Core -> /home/vsts/work/1/s/artifacts/bin/Core/Debug/net10.0/Microsoft.Maui.dll
  Controls.BindingSourceGen -> /home/vsts/work/1/s/artifacts/bin/Controls.BindingSourceGen/Debug/netstandard2.0/Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13844848
  Controls.Core -> /home/vsts/work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  UITest.Core -> /home/vsts/work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
  VisualTestUtils -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
  UITest.NUnit -> /home/vsts/work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
  VisualTestUtils.MagickNet -> /home/vsts/work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
  UITest.Appium -> /home/vsts/work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
  UITest.Analyzers -> /home/vsts/work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
  Controls.TestCases.Android.Tests -> /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
Test run for /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.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.
/home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
[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.14]   Discovering: Controls.TestCases.Android.Tests
[xUnit.net 00:00:00.44]   Discovered:  Controls.TestCases.Android.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /home/vsts/work/1/s/artifacts/bin/Controls.TestCases.Android.Tests/Debug/net10.0/Controls.TestCases.Android.Tests.dll
   NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 04/15/2026 17:09:31 FixtureSetup for Issue34848(Android)
>>>>> 04/15/2026 17:09:33 DatePickerOpenedAndClosedEventsAreRaised Start
>>>>> 04/15/2026 17:09:40 DatePickerOpenedAndClosedEventsAreRaised Stop
  Passed DatePickerOpenedAndClosedEventsAreRaised [6 s]
NUnit Adapter 4.5.0.0: Test execution complete

Test Run Successful.
Total tests: 1
     Passed: 1
 Total time: 21.7133 Seconds

⚠️ Issues found
  • ⚠️ Issue34848 without fix: Exception calling "Matches" with "2" argument(s): "Value cannot be null. (Parameter 'input')"
📁 Fix files reverted (1 files)
  • src/Core/src/Handlers/DatePicker/DatePickerHandler.MacCatalyst.cs

@MauiBot
Copy link
Copy Markdown
Collaborator

MauiBot commented Apr 15, 2026

🤖 AI Summary

👋 @SubhikshaSf4851 — new AI review results are available. Please review the latest session below.

📊 Review Sessionfe3199d · Updated sugggestion · 2026-04-16 13:33 UTC
🔍 Pre-Flight — Context & Validation

Issue: #34848 - [MacCatalyst] DatePicker Opened and Closed events are not raised on Mac platform
PR: #34970 - [MacCatalyst] Fix DatePicker Opened/Closed events not being raised
Platforms Affected: MacCatalyst (primary fix); tests run on Android/iOS/Windows/MacCatalyst
Files Changed: 1 implementation, 2 test

Key Findings

  • On MacCatalyst, compact UIDatePicker renders date segments as internal UITextField subviews; the normal UIDatePicker EditingDidBegin/EditingDidEnd events never fire when the picker popover is opened/dismissed via AppKit
  • The fix traverses internal view hierarchy to wire EditingDidBegin on those UITextField subviews, and listens for NSWindowDidCloseNotification to detect the popover closing
  • NSWindowDidCloseNotification is observed globally (no fromObject filter) — any window close in the process can falsely trigger the Closed event while the picker is still open
  • Test code uses inline #if directives, which is explicitly prohibited by MAUI UI testing guidelines
  • Prior review comments from Copilot (naming, magic string, unused import) were all resolved by the author

Code Review Summary

Verdict: NEEDS_CHANGES
Confidence: medium
Errors: 0 | Warnings: 3 | Suggestions: 1

Key code review findings:

  • ⚠️ NSWindowDidCloseNotification observer has no fromObject filter — any window close raises Closed event spuriously (DatePickerHandler.MacCatalyst.cs:110)
  • ⚠️ Inline #if IOS / #elif WINDOWS / #elif ANDROID / #else in test method violates UI testing guidelines (Issue34848.cs:25-35)
  • ⚠️ GetTextFields walks undocumented UIDatePicker internal subviews; if layout hasn't happened at ConnectHandler time, wiring silently fails (DatePickerHandler.MacCatalyst.cs:61-78)
  • 💡 ResignTextFields lambda captures platformView without disposed-state guard; potential native crash during rapid teardown (DatePickerHandler.MacCatalyst.cs:143-154)

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #34970 UITextField traversal + NSWindowDidCloseNotification one-shot observer ✅ PASSED (Gate) DatePickerHandler.MacCatalyst.cs, 2 test files Original PR

🔬 Code Review — Deep Analysis

Code Review — PR #34970

Independent Assessment

What this changes: The MacCatalyst DatePickerHandler is refactored to fix Opened/Closed events that weren't firing. The old approach subscribed EditingDidBegin/EditingDidEnd directly on the UIDatePicker platform view via the proxy (which never fired on MacCatalyst's compact picker). The new approach:

  1. Recursively walks the internal view hierarchy of the UIDatePicker to find hidden UITextField subviews
  2. Subscribes EditingDidBegin on each found text field to detect the picker opening
  3. When opened, registers a one-shot NSNotificationCenter observer for NSWindowDidCloseNotification to detect when the MacCatalyst popover AppKit window closes (since EditingDidEnd never fires in this scenario)
  4. Includes cleanup in DisconnectHandler, a ResignTextFields deferred call, and the _isDatePickerOpen guard to prevent duplicate open events across the three date segment fields

A UI test covering all four platforms is also added.

Inferred motivation: On MacCatalyst, the compact UIDatePicker uses an AppKit popover window for its picker UI. Dismissal (tap outside) happens at the AppKit level, not the UIKit level, so UITextField.EditingDidEnd never fires. The fix correctly identifies that the close signal must come from AppKit's window notification system.


Reconciliation with PR Narrative

Author claims: Fix for DatePicker Opened/Closed events not raising on MacCatalyst. Removed old EditingDidBegin/End from the proxy; replaced with text-field traversal + window-close notification.

Agreement: The diagnosis and general approach are correct. The old proxy-based subscriptions on UIDatePicker didn't work on MacCatalyst for exactly the reason described.

Concern to investigate: The NSWindowDidCloseNotification observer is registered with AddObserver(name, handler) — the 2-parameter overload with no fromObject filter. This means it fires for any window close in the process, not specifically the DatePicker's popover window. On multi-window macOS/MacCatalyst apps (or when an alert/sheet closes), this could spuriously raise the Closed event while the picker is still visually open.


Findings

⚠️ Warning — NSWindowDidCloseNotification fires for any window, not just the DatePicker popover

DatePickerHandler.MacCatalyst.cs, line 110:

_windowCloseObserver = NSNotificationCenter.DefaultCenter.AddObserver(
    WindowDidCloseNotification, OnWindowClosed);  // no fromObject filter

The 2-parameter AddObserver overload does not filter by sender object, so this observer fires when any NSWindow in the process closes — including alert sheets, secondary windows, or floating panels. If a different window closes while the date picker is open, OnWindowClosed fires, IsOpen is set to false, and the Closed event is raised even though the picker is still displayed.

The correct overload is AddObserver(NSString name, Action<NSNotification> handler, NSObject? fromObject, NSOperationQueue? queue). However, there is a catch: the DatePicker's popover window object needs to be identified first (it's not directly available from UIKit). One approach is to capture PlatformView.Window at the moment EditingDidBegin fires. If the popover opens in a new window (which is the MacCatalyst behavior), PlatformView.Window would change. Alternatively, sender as UITextField in OnEditingDidBegin could be used to walk up to its Window and pass that as the fromObject filter.

In the short term, an _isDatePickerOpen guard partially mitigates this (a second window close won't re-trigger once the picker is marked closed), but the first spurious close from a non-picker window during an open picker will still incorrectly raise Closed.

⚠️ Warning — Inline #if directives in the test method violate MAUI UI testing guidelines

TestCases.Shared.Tests/Tests/Issues/Issue34848.cs, lines 25–35:

#if IOS
    App.Tap("Done");
#elif WINDOWS
    App.Tap("16");
#elif ANDROID
    App.Tap("Cancel");
#else
    App.TapCoordinates(30, 30);
#endif

Per .github/instructions/uitests.instructions.md (explicitly stated):

"No inline #if directives in test code (use extension methods)"
"Do NOT use #if ANDROID, #if IOS, etc. directly in test methods. Platform-specific behavior must be hidden behind extension methods for readability."

The platform-specific close logic should be moved to an extension method (e.g., App.CloseDatePicker()) that encapsulates each branch internally.

Additionally, the Windows case App.Tap("16") is fragile: it hardcodes a day number that may render differently depending on the calendar view's current state or layout.

⚠️ Warning — Internal UIDatePicker subview traversal depends on undocumented UIKit internals

GetTextFields recursively walks UIDatePicker.Subviews to find private UITextField instances that Apple does not document as part of its public API:

static IEnumerable<UITextField> GetTextFields(UIView view)
{
    foreach (var subview in view.Subviews)
    {
        if (subview is UITextField textField)
            yield return textField;
        else
            foreach (var nested in GetTextFields(subview))
                yield return nested;
    }
}

If WireTextFields finds zero text fields (e.g., Apple restructures the internal hierarchy in a future OS update, or the picker hasn't laid out internal subviews yet at ConnectHandler time), the fix silently stops working with no error or fallback. This has happened to similar approaches across macOS OS updates in other frameworks.

Two sub-concerns:

  1. Timing: WireTextFields is called in ConnectHandler, before the view has been added to the window or performed its first layout pass. The internal UITextField subviews may not be created yet. Consider deferring wiring to MovedToWindow or verifying at ConnectHandler time that at least one text field is found (and logging a warning if not).
  2. Future-proofing: The comment should note which macOS/MacCatalyst version(s) this was verified on so future reviewers know when to recheck.

💡 Suggestion — ResignTextFields lambda captures platformView without a disposed-state guard

void ResignTextFields()
{
    var platformView = PlatformView;
    CoreFoundation.DispatchQueue.MainQueue.DispatchAsync(() =>
    {
        foreach (var textField in GetTextFields(platformView))
        {
            if (textField.IsFirstResponder)
                textField.ResignFirstResponder();
        }
    });
}

OnWindowClosed queues a deferred dispatch to ResignTextFields. If DisconnectHandler is called between the notification firing and the dispatch executing (possible when the view is being torn down rapidly), platformView could be in an inconsistent state. A defensive guard like if (platformView?.Handle == IntPtr.Zero) return; at the top of the lambda would prevent a potential native crash accessing a disposed view (per review rule §7: "Check Handle == IntPtr.Zero for disposed native objects").


Devil's Advocate

Challenging the NSWindowDidCloseNotification concern: MacCatalyst apps are typically single-window, so the spurious-close risk is lower than it would be on a full macOS app. If the target use case is standard MAUI apps (single window), this might be "good enough" — though it's still architecturally wrong and would be a surprising bug if encountered.

Challenging the internal-API concern: The MAUI codebase already has other UIKit internal-API workarounds for MacCatalyst quirks. This is pragmatic for a platform that has limited first-class DatePicker support. The risk is real but the fix is better than the current broken state.

Challenging the test #if concern: The inline #if pattern exists in many other test files in the repo. While documented as an anti-pattern, calling this out as blocking may feel inconsistent with existing tests. However, this is a new test file, so it should follow current guidelines.

On verdict: The core logic for OnEditingDidBegin + _isDatePickerOpen guard is sound. The DisconnectHandler cleanup is symmetric. CI is green. The change is meaningfully better than the status quo. The NSWindowDidCloseNotification scope issue is the substantive concern that could cause a regression in multi-window scenarios.


Verdict: NEEDS_CHANGES

Confidence: medium

Summary: The root cause analysis is correct and the general approach is sound, but the NSWindowDidCloseNotification observer lacks a fromObject filter, meaning any window close in the process can falsely raise the Closed event while the picker is still visible — a real bug in multi-window MacCatalyst apps. The test additionally uses inline #if directives, which is explicitly prohibited by MAUI's UI testing guidelines. Both issues should be addressed before merge. The internal-subview-traversal approach is pragmatic given the MacCatalyst constraint, though documentation of its OS-version dependency would reduce future maintenance risk.


🔧 Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 claude-opus-4.6 Broadcast UITextFieldTextDidBeginEditingNotification + IsDescendantOfView filter (no view traversal) ✅ PASS 1 file Eliminates fragile subview walk; same NSWindowDidCloseNotification concern
2 claude-sonnet-4.6 NSWindowDidBecomeKeyNotification open + filtered close (3 iterations) ❌ FAIL 1 file NSWindowDidBecomeKeyNotification doesn't fire on macOS 26
3 gpt-5.3-codex Layout-driven subview tracking via custom UIDatePicker subclass + EditingDidEnd for close ❌ FAIL 1 file Open worked; Close detection via EditingDidEnd failed (AppKit dismissal bypasses UIKit)
4 gpt-5.4 UITextFieldTextDidBeginEditingNotification + captured UITextField.Window as fromObject filter ❌ FAIL 1 file UIKit window object ≠ AppKit notification source for popover close
PR PR #34970 UITextField traversal + NSWindowDidCloseNotification one-shot observer ✅ PASSED (Gate) 3 files Original PR

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 2 No All viable detection mechanisms exhausted; UITextField first-responder + NSWindowDidCloseNotification is the only working pattern
claude-sonnet-4.6 2 Yes (low priority) NSApplication.SharedApplication.Windows diff to capture exact popover NSWindow AppKit reference for filter — technically novel but too complex, PR simpler

Exhausted: Yes
Selected Fix: PR #34970 — The PR's approach works and has correct cleanup. Attempt 1 offers a marginally cleaner open detection (no subview traversal) but shares the same NSWindowDidCloseNotification limitation. Both passing approaches require the same core mechanism; the PR's fix with the code-review improvements is the recommended path.

Cross-Pollination

Model Round New Ideas? Details
(pending) 2

Exhausted: No
Selected Fix: (pending)


📋 Report — Final Recommendation

⚠️ Final Recommendation: REQUEST CHANGES

Phase Status

Phase Status Notes
Pre-Flight ✅ COMPLETE 3 changed files classified; linked issue #34848 read
Code Review NEEDS_CHANGES (medium confidence) 0 errors, 3 warnings, 1 suggestion
Gate ✅ PASSED MacCatalyst — Issue34848 FAIL without fix, PASS with fix
Try-Fix ✅ COMPLETE 4 attempts, 1 passing (Attempt 1: broadcast notification approach)
Report ✅ COMPLETE

Code Review Impact on Try-Fix

The ⚠️ warning about WireTextFields being called at ConnectHandler before subviews exist directly motivated Attempt 1 (claude-opus-4.6), which eliminated the fragile subview traversal entirely by using a broadcast UITextFieldTextDidBeginEditingNotification with IsDescendantOfView filtering. This is a cleaner design that avoids the timing fragility. The ⚠️ warning about NSWindowDidCloseNotification having no fromObject filter motivated Attempts 2 and 4 to try scoped window filtering — both failed because the AppKit NSWindow is not accessible as a UIKit UIWindow reference. Cross-pollination confirmed that NSWindowDidCloseNotification without a filter is the only reliable close signal on MacCatalyst.

Summary

PR #34970 correctly fixes a real MacCatalyst-specific bug: the compact UIDatePicker's Opened/Closed events never fired because UIKit-level events don't propagate through the AppKit NSWindow popover boundary. The core approach (UITextField first-responder for open + NSWindowDidCloseNotification for close) is validated as the only viable mechanism by exhaustive try-fix exploration (4 models, 6 total iterations). Two specific issues need to be addressed before merge:

  1. Test #if directives — The test uses inline #if IOS / #elif WINDOWS / #elif ANDROID / #else in the test method body, which explicitly violates MAUI's UI testing guidelines (uitests.instructions.md). The platform-specific DatePicker close logic must be moved to an extension method.

  2. NSWindowDidCloseNotification without fromObject filter — The observer fires for any NSWindow close in the process, which can falsely raise Closed while the picker is still open (if an unrelated window closes). Attempt 4 confirmed that filtering by UIKit window reference doesn't work; however, Attempt 1's UITextFieldTextDidBeginEditingNotification approach is a cleaner alternative for open detection that also removes the subview timing concern.

An optional improvement from Try-Fix: replacing the GetTextFields/WireTextFields subview traversal with a global UITextFieldTextDidBeginEditingNotification + IsDescendantOfView approach (Attempt 1) removes the need for System.Collections.Generic, eliminates the recursive view walk, and works regardless of when UIDatePicker creates its internal subviews.

Root Cause

On MacCatalyst, the compact UIDatePicker renders date segments as internal UITextField subviews. When tapped, the picker opens in an AppKit NSWindow popover. This AppKit-level dismissal never triggers UIKit's EditingDidEnd on the UIDatePicker or its text fields — only NSWindowDidCloseNotification fires reliably. The old proxy subscriptions (EditingDidBegin/EditingDidEnd on the UIDatePicker itself) were never invoked on MacCatalyst, leaving both Opened and Closed events perpetually unfired.

Fix Quality

The fix correctly addresses the root cause. The _isDatePickerOpen guard prevents duplicate Opened events when multiple date segment text fields gain focus in sequence. Cleanup in DisconnectHandler is symmetric and correct. The ResignTextFields deferred dispatch handles the MacCatalyst quirk where text fields stay visually highlighted after the popover closes.

Changes needed before merge:

  1. Move platform-specific DatePicker close logic in the test out of inline #if directives into an extension method (per MAUI UI testing guidelines)
  2. Address or acknowledge the NSWindowDidCloseNotification global observer scope (⚠️ — acceptable for single-window apps but brittle for multi-window scenarios)


📊 Review Session846faa4 · modified observer changes · 2026-04-15 18:20 UTC
🔍 Pre-Flight — Context & Validation

Issue: #34848 - [MacCatalyst] DatePicker Opened and Closed events are not raised on Mac platform
PR: #34970 - [MacCatalyst] Fix DatePicker Opened/Closed events not being raised
Platforms Affected: MacCatalyst (primary fix); test runs on Android/iOS/Windows too
Files Changed: 1 implementation, 2 test

Key Findings

  • On MacCatalyst, the compact UIDatePicker renders date segments as internal UITextField subviews; the normal EditingDidBegin/EditingDidEnd proxy events on the UIDatePicker never fire
  • The fix traverses the internal view hierarchy to find UITextField subviews and wires EditingDidBegin per field to detect "opened"
  • For "closed" detection: the picker popover is dismissed at the AppKit level (NSWindow close) without firing UITextField EditingDidEnd; fix uses a one-shot NSWindowDidCloseNotification observer registered only while the picker is open
  • ResignTextFields() dispatches on main queue to resign first responders after close — needed because UIKit state lags the notification
  • Prior agent review (commit 846faa4, 2026-04-15 15:39 UTC): Ran 5 try-fix attempts, found 3 passing alternatives; all converged on the same two-signal approach as the PR's fix. Recommended REQUEST CHANGES for 3 code quality issues
  • Issues flagged (prior review + inline Copilot comments) — NOT yet addressed:
    1. new("NSWindowDidCloseNotification") is a hard-coded string — should be a const or static readonly to prevent typos and enable rename
    2. _OpenstatusLabel / _ClosestatusLabel in HostApp violate camelCase convention — should be _openStatusLabel / _closeStatusLabel
    3. Unused using System.Diagnostics; in TestCases.Shared.Tests/Tests/Issues/Issue34848.cs
  • Gate result (current run): ENV ERROR without fix / PASS with fix — the ENV ERROR is expected (without the fix the test page doesn't exist)
  • Test uses inline #if platform directives in test method — common codebase pattern for platform-specific close gestures, acceptable

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #34970 Traverse UIDatePicker hierarchy for UITextFields; wire EditingDidBegin per field; NSWindowDidCloseNotification one-shot observer for close; async ResignFirstResponder ✅ PASSED (Gate) DatePickerHandler.MacCatalyst.cs + 2 test files Original PR; 3 minor code quality issues remain unaddressed

🔧 Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix (claude-opus-4.6) AppKit NSWindowDidBecomeKeyNotification for open + NSWindowDidCloseNotification for close; confirm first-responder descendant via deferred run-loop check ✅ PASS 1 file Different interception point from PR; still uses hard-coded AppKit notification string
2 try-fix (claude-sonnet-4.6) UIKit UIWindowDidBecomeKeyNotification + UIWindowDidResignKeyNotification; track popover UIWindow by object identity ✅ PASS 1 file Avoids AppKit string literals; stays in UIKit layer
3 try-fix (gpt-5.3-codex) UIDatePicker.TouchUpInside for open; outside-window UITapGestureRecognizer for close; MapIsOpen implements BecomeFirstResponder/ResignFirstResponder ✅ PASS 1 file Touch/gesture-driven; most moving parts of all passing approaches
4 try-fix (gemini-3-pro-preview) ⚠️ BLOCKED Model unavailable in environment
5 try-fix (claude-sonnet-4.6 R2) UIAdaptivePresentationControllerDelegate.DidDismiss for close; leverages UIKit presentation lifecycle, no AppKit dependency ✅ PASS 1 file Semantically correct UIKit pattern; uses same EditingDidBegin trigger for open as PR
6 try-fix (claude-opus-4.6 R2) NSEvent.AddLocalMonitorForEventsMatchingMask P/Invoke block trampoline; geometric hit-testing for open/close ✅ PASS 1 file Most architecturally novel; ~237 lines, high complexity, overkill
PR PR #34970 Traverse UIDatePicker view hierarchy for UITextFields; wire EditingDidBegin per field; one-shot NSWindowDidCloseNotification observer; async ResignFirstResponder ✅ PASSED (Gate) 1 impl + 2 test Original PR; 3 minor code quality issues unaddressed

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 2 NO NEW IDEAS All paradigms covered by attempts 1-8
claude-sonnet-4.6 2 NEW IDEA NSEvent.AddLocalMonitorForEventsMatchingMask → ran as Attempt 6
gpt-5.3-codex 2 NEW IDEA UIAdaptivePresentationControllerDelegate → ran as Attempt 5
claude-opus-4.6 3 NO NEW IDEAS Space exhausted
gpt-5.3-codex 3 Minor variation UIControl.AddTarget/RemoveTarget on UITextFields — same root cause hypothesis as PR's fix, not meaningfully different

Exhausted: Yes — Round 3 models confirmed no genuinely new directions; gpt-5.3-codex R3 proposal is a syntax variation of the PR's own approach.

Selected Fix: PR's fix — Gate confirmed working on MacCatalyst; functionally correct; most explicit and readable. Minor code quality issues should be addressed before merge.

Best alternative: Attempt 5 (UIAdaptivePresentationControllerDelegate) — semantically cleanest UIKit approach, no AppKit dependency, no hard-coded strings, no private view hierarchy traversal for close detection.


📋 Report — Final Recommendation

⚠️ Final Recommendation: REQUEST CHANGES

Phase Status

Phase Status Notes
Pre-Flight ✅ COMPLETE Issue #34848, MacCatalyst DatePicker events; prior agent review found same issues
Gate ✅ PASSED Android — ENV ERROR without fix (test page didn't exist), PASS with fix
Try-Fix ✅ COMPLETE 6 attempts (5 pass, 1 blocked); cross-pollination exhausted at Round 3
Report ✅ COMPLETE

Summary

PR #34970 correctly fixes the MacCatalyst DatePicker.Opened/Closed events by traversing the compact UIDatePicker's internal UITextField view hierarchy and wiring EditingDidBegin per field for open detection, combined with a one-shot NSWindowDidCloseNotification observer for close detection. Gate confirmed correctness, and try-fix found multiple working alternatives (all converge on the same two-signal requirement: UITextField focus for open, window close signal for close).

However, three code quality issues flagged in the prior agent review (2026-04-15 15:39 UTC) and by inline Copilot comments remain unaddressed in the current commit (846faa4). REQUEST CHANGES to require the author to fix these before merge.

Root Cause

On MacCatalyst, the compact UIDatePicker renders its date segments as internal UITextField subviews. The UIDatePicker-level UIKit events (EditingDidBegin/EditingDidEnd via the proxy) never fire. The popover dismissal additionally bypasses UIKit entirely — the AppKit NSWindow closes without firing UITextField's EditingDidEnd. The original MAUI handler wired only to the proxy UIDatePicker events, so Opened/Closed were never raised on MacCatalyst.

Fix Quality

Correctness: ✅ The fix is correct. The two-signal approach is validated by Gate (MacCatalyst, prior session), and independently confirmed by 5 passing try-fix alternatives in two review sessions. All passing approaches converge on the same fundamental insight (UITextField focus for open, window lifecycle for close).

Unaddressed issues (from prior review, still present):

  1. Hard-coded notification name string (medium priority)new("NSWindowDidCloseNotification") at line 108 is a raw string literal. A typo won't be caught at compile time. It should be a private const string or static readonly NSString used consistently by both the registration call and the removal call (currently the removal uses the _windowCloseObserver reference, but centralizing the constant is still good practice):

    // Suggested:
    const string WindowDidCloseNotification = "NSWindowDidCloseNotification";
  2. Inconsistent field naming in HostApp test page (minor)_OpenstatusLabel and _ClosestatusLabel in Issue34848.cs violate standard C# camelCase private field naming. Should be _openStatusLabel and _closeStatusLabel.

  3. Unused using System.Diagnostics in shared test (trivial) — The import in TestCases.Shared.Tests/Tests/Issues/Issue34848.cs is unused and should be removed.

  4. Inline #if platform directives in test method (informational) — Per UI test guidelines, platform-specific logic should live in extension methods. However, this pattern is common throughout the codebase for simple platform-specific close gestures and is acceptable here. No action required.

Selected Fix

PR's fix — Gate passed. Functionally correct. The three quality issues above should be addressed before merge. The best alternative (Attempt 5, UIAdaptivePresentationControllerDelegate) is semantically cleaner and avoids both private view hierarchy traversal for close detection and AppKit string literals, but the PR's approach is also valid — the team may choose either.


@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Apr 15, 2026
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Apr 15, 2026

/azp run maui-pr-uitests , maui-pr-devicetests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

@kubaflo kubaflo added the s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation label Apr 16, 2026
@kubaflo kubaflo changed the base branch from main to inflight/current April 16, 2026 18:35
@kubaflo kubaflo merged commit ea6127a into dotnet:inflight/current Apr 16, 2026
25 of 34 checks passed
devanathan-vaithiyanathan pushed a commit to Tamilarasan-Paranthaman/maui that referenced this pull request Apr 21, 2026
…otnet#34970)

<!-- 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 the issue where the `DatePicker` control on
MacCatalyst did not correctly raise its `Opened` and `Closed` events.
The changes implement a more robust mechanism for detecting when the
DatePicker is opened and closed, specifically for MacCatalyst, and add
new tests to verify this behavior.
### Description of Change :

**MacCatalyst DatePicker Event Handling Improvements:**

* Added logic to traverse the internal view hierarchy of the compact
`UIDatePicker` to find and wire up `UITextField` subviews, allowing
detection of when the DatePicker is opened via the `EditingDidBegin`
event. A one-shot observer is registered to detect when the picker
popover window closes, ensuring the `Closed` event is raised reliably.
(`DatePickerHandler.MacCatalyst.cs`)
* Implemented cleanup logic to unwire event handlers and remove
observers during disconnect, preventing memory leaks and spurious event
firing. (`DatePickerHandler.MacCatalyst.cs`)
* Removed previous event handler attachments
(`EditingDidBegin`/`EditingDidEnd`) from the proxy, as the new mechanism
supersedes them. (`DatePickerHandler.MacCatalyst.cs`)
[[1]](diffhunk://#diff-2107542f6f788907263db46eab6a80232ed765aa515806945e8f65681c8421d1L105-L113)
[[2]](diffhunk://#diff-2107542f6f788907263db46eab6a80232ed765aa515806945e8f65681c8421d1L125-L136)

**Testing Enhancements:**

* Added a new test case page (`Issue34848`) and a corresponding UI test
to verify that the `Opened` and `Closed` events are raised correctly on
MacCatalyst and other platforms, using platform-specific logic to close
the DatePicker. (`TestCases.HostApp/Issues/Issue34848.cs`,
`TestCases.Shared.Tests/Tests/Issues/Issue34848.cs`)
[[1]](diffhunk://#diff-652f2cd8a1e252cf8db29bf33034066d08ec5e3b43ec76a77d477824a08a1f44R1-R46)
[[2]](diffhunk://#diff-a57ba10bf75c97b2a6f28c075585a1066df8c7c2c31751e3c799177fca6560b4R1-R42)

**General Codebase Improvements:**

* Minor code cleanup and improved organization in the DatePicker handler
for MacCatalyst, including the addition of necessary using directives.
(`DatePickerHandler.MacCatalyst.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 dotnet#34848 

### Tested the behavior in the following platforms

- [ ] Windows
- [ ] Android
- [ ] iOS
- [x] Mac

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/73c4686f-30d0-4a57-bb8d-be6b2d4b7cda">
| <video
src="https://github.com/user-attachments/assets/65d6f44e-b145-48de-b41a-77b6abefabc4">
|
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
PureWeen pushed a commit that referenced this pull request Apr 22, 2026
…34970)

<!-- 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 the issue where the `DatePicker` control on
MacCatalyst did not correctly raise its `Opened` and `Closed` events.
The changes implement a more robust mechanism for detecting when the
DatePicker is opened and closed, specifically for MacCatalyst, and add
new tests to verify this behavior.
### Description of Change :

**MacCatalyst DatePicker Event Handling Improvements:**

* Added logic to traverse the internal view hierarchy of the compact
`UIDatePicker` to find and wire up `UITextField` subviews, allowing
detection of when the DatePicker is opened via the `EditingDidBegin`
event. A one-shot observer is registered to detect when the picker
popover window closes, ensuring the `Closed` event is raised reliably.
(`DatePickerHandler.MacCatalyst.cs`)
* Implemented cleanup logic to unwire event handlers and remove
observers during disconnect, preventing memory leaks and spurious event
firing. (`DatePickerHandler.MacCatalyst.cs`)
* Removed previous event handler attachments
(`EditingDidBegin`/`EditingDidEnd`) from the proxy, as the new mechanism
supersedes them. (`DatePickerHandler.MacCatalyst.cs`)
[[1]](diffhunk://#diff-2107542f6f788907263db46eab6a80232ed765aa515806945e8f65681c8421d1L105-L113)
[[2]](diffhunk://#diff-2107542f6f788907263db46eab6a80232ed765aa515806945e8f65681c8421d1L125-L136)

**Testing Enhancements:**

* Added a new test case page (`Issue34848`) and a corresponding UI test
to verify that the `Opened` and `Closed` events are raised correctly on
MacCatalyst and other platforms, using platform-specific logic to close
the DatePicker. (`TestCases.HostApp/Issues/Issue34848.cs`,
`TestCases.Shared.Tests/Tests/Issues/Issue34848.cs`)
[[1]](diffhunk://#diff-652f2cd8a1e252cf8db29bf33034066d08ec5e3b43ec76a77d477824a08a1f44R1-R46)
[[2]](diffhunk://#diff-a57ba10bf75c97b2a6f28c075585a1066df8c7c2c31751e3c799177fca6560b4R1-R42)

**General Codebase Improvements:**

* Minor code cleanup and improved organization in the DatePicker handler
for MacCatalyst, including the addition of necessary using directives.
(`DatePickerHandler.MacCatalyst.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 #34848 

### Tested the behavior in the following platforms

- [ ] Windows
- [ ] Android
- [ ] iOS
- [x] Mac

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/73c4686f-30d0-4a57-bb8d-be6b2d4b7cda">
| <video
src="https://github.com/user-attachments/assets/65d6f44e-b145-48de-b41a-77b6abefabc4">
|
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
PureWeen pushed a commit that referenced this pull request Apr 28, 2026
…34970)

<!-- 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 the issue where the `DatePicker` control on
MacCatalyst did not correctly raise its `Opened` and `Closed` events.
The changes implement a more robust mechanism for detecting when the
DatePicker is opened and closed, specifically for MacCatalyst, and add
new tests to verify this behavior.
### Description of Change :

**MacCatalyst DatePicker Event Handling Improvements:**

* Added logic to traverse the internal view hierarchy of the compact
`UIDatePicker` to find and wire up `UITextField` subviews, allowing
detection of when the DatePicker is opened via the `EditingDidBegin`
event. A one-shot observer is registered to detect when the picker
popover window closes, ensuring the `Closed` event is raised reliably.
(`DatePickerHandler.MacCatalyst.cs`)
* Implemented cleanup logic to unwire event handlers and remove
observers during disconnect, preventing memory leaks and spurious event
firing. (`DatePickerHandler.MacCatalyst.cs`)
* Removed previous event handler attachments
(`EditingDidBegin`/`EditingDidEnd`) from the proxy, as the new mechanism
supersedes them. (`DatePickerHandler.MacCatalyst.cs`)
[[1]](diffhunk://#diff-2107542f6f788907263db46eab6a80232ed765aa515806945e8f65681c8421d1L105-L113)
[[2]](diffhunk://#diff-2107542f6f788907263db46eab6a80232ed765aa515806945e8f65681c8421d1L125-L136)

**Testing Enhancements:**

* Added a new test case page (`Issue34848`) and a corresponding UI test
to verify that the `Opened` and `Closed` events are raised correctly on
MacCatalyst and other platforms, using platform-specific logic to close
the DatePicker. (`TestCases.HostApp/Issues/Issue34848.cs`,
`TestCases.Shared.Tests/Tests/Issues/Issue34848.cs`)
[[1]](diffhunk://#diff-652f2cd8a1e252cf8db29bf33034066d08ec5e3b43ec76a77d477824a08a1f44R1-R46)
[[2]](diffhunk://#diff-a57ba10bf75c97b2a6f28c075585a1066df8c7c2c31751e3c799177fca6560b4R1-R42)

**General Codebase Improvements:**

* Minor code cleanup and improved organization in the DatePicker handler
for MacCatalyst, including the addition of necessary using directives.
(`DatePickerHandler.MacCatalyst.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 #34848 

### Tested the behavior in the following platforms

- [ ] Windows
- [ ] Android
- [ ] iOS
- [x] Mac

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/73c4686f-30d0-4a57-bb8d-be6b2d4b7cda">
| <video
src="https://github.com/user-attachments/assets/65d6f44e-b145-48de-b41a-77b6abefabc4">
|
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
PureWeen pushed a commit that referenced this pull request Apr 29, 2026
…34970)

<!-- 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 the issue where the `DatePicker` control on
MacCatalyst did not correctly raise its `Opened` and `Closed` events.
The changes implement a more robust mechanism for detecting when the
DatePicker is opened and closed, specifically for MacCatalyst, and add
new tests to verify this behavior.
### Description of Change :

**MacCatalyst DatePicker Event Handling Improvements:**

* Added logic to traverse the internal view hierarchy of the compact
`UIDatePicker` to find and wire up `UITextField` subviews, allowing
detection of when the DatePicker is opened via the `EditingDidBegin`
event. A one-shot observer is registered to detect when the picker
popover window closes, ensuring the `Closed` event is raised reliably.
(`DatePickerHandler.MacCatalyst.cs`)
* Implemented cleanup logic to unwire event handlers and remove
observers during disconnect, preventing memory leaks and spurious event
firing. (`DatePickerHandler.MacCatalyst.cs`)
* Removed previous event handler attachments
(`EditingDidBegin`/`EditingDidEnd`) from the proxy, as the new mechanism
supersedes them. (`DatePickerHandler.MacCatalyst.cs`)
[[1]](diffhunk://#diff-2107542f6f788907263db46eab6a80232ed765aa515806945e8f65681c8421d1L105-L113)
[[2]](diffhunk://#diff-2107542f6f788907263db46eab6a80232ed765aa515806945e8f65681c8421d1L125-L136)

**Testing Enhancements:**

* Added a new test case page (`Issue34848`) and a corresponding UI test
to verify that the `Opened` and `Closed` events are raised correctly on
MacCatalyst and other platforms, using platform-specific logic to close
the DatePicker. (`TestCases.HostApp/Issues/Issue34848.cs`,
`TestCases.Shared.Tests/Tests/Issues/Issue34848.cs`)
[[1]](diffhunk://#diff-652f2cd8a1e252cf8db29bf33034066d08ec5e3b43ec76a77d477824a08a1f44R1-R46)
[[2]](diffhunk://#diff-a57ba10bf75c97b2a6f28c075585a1066df8c7c2c31751e3c799177fca6560b4R1-R42)

**General Codebase Improvements:**

* Minor code cleanup and improved organization in the DatePicker handler
for MacCatalyst, including the addition of necessary using directives.
(`DatePickerHandler.MacCatalyst.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 #34848 

### Tested the behavior in the following platforms

- [ ] Windows
- [ ] Android
- [ ] iOS
- [x] Mac

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/73c4686f-30d0-4a57-bb8d-be6b2d4b7cda">
| <video
src="https://github.com/user-attachments/assets/65d6f44e-b145-48de-b41a-77b6abefabc4">
|
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
github-actions Bot pushed a commit that referenced this pull request May 6, 2026
…34970)

<!-- 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 the issue where the `DatePicker` control on
MacCatalyst did not correctly raise its `Opened` and `Closed` events.
The changes implement a more robust mechanism for detecting when the
DatePicker is opened and closed, specifically for MacCatalyst, and add
new tests to verify this behavior.
### Description of Change :

**MacCatalyst DatePicker Event Handling Improvements:**

* Added logic to traverse the internal view hierarchy of the compact
`UIDatePicker` to find and wire up `UITextField` subviews, allowing
detection of when the DatePicker is opened via the `EditingDidBegin`
event. A one-shot observer is registered to detect when the picker
popover window closes, ensuring the `Closed` event is raised reliably.
(`DatePickerHandler.MacCatalyst.cs`)
* Implemented cleanup logic to unwire event handlers and remove
observers during disconnect, preventing memory leaks and spurious event
firing. (`DatePickerHandler.MacCatalyst.cs`)
* Removed previous event handler attachments
(`EditingDidBegin`/`EditingDidEnd`) from the proxy, as the new mechanism
supersedes them. (`DatePickerHandler.MacCatalyst.cs`)
[[1]](diffhunk://#diff-2107542f6f788907263db46eab6a80232ed765aa515806945e8f65681c8421d1L105-L113)
[[2]](diffhunk://#diff-2107542f6f788907263db46eab6a80232ed765aa515806945e8f65681c8421d1L125-L136)

**Testing Enhancements:**

* Added a new test case page (`Issue34848`) and a corresponding UI test
to verify that the `Opened` and `Closed` events are raised correctly on
MacCatalyst and other platforms, using platform-specific logic to close
the DatePicker. (`TestCases.HostApp/Issues/Issue34848.cs`,
`TestCases.Shared.Tests/Tests/Issues/Issue34848.cs`)
[[1]](diffhunk://#diff-652f2cd8a1e252cf8db29bf33034066d08ec5e3b43ec76a77d477824a08a1f44R1-R46)
[[2]](diffhunk://#diff-a57ba10bf75c97b2a6f28c075585a1066df8c7c2c31751e3c799177fca6560b4R1-R42)

**General Codebase Improvements:**

* Minor code cleanup and improved organization in the DatePicker handler
for MacCatalyst, including the addition of necessary using directives.
(`DatePickerHandler.MacCatalyst.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 #34848 

### Tested the behavior in the following platforms

- [ ] Windows
- [ ] Android
- [ ] iOS
- [x] Mac

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/73c4686f-30d0-4a57-bb8d-be6b2d4b7cda">
| <video
src="https://github.com/user-attachments/assets/65d6f44e-b145-48de-b41a-77b6abefabc4">
|
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
@github-actions github-actions Bot locked and limited conversation to collaborators May 17, 2026
@kubaflo kubaflo added the s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) label May 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-controls-datetimepicker DatePicker, TimePicker community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/macos macOS / Mac Catalyst s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[MacCatalyst] DatePicker Opened and Closed events are not raised on Mac platform

6 participants