Skip to content

[Windows] Fix for TimePicker rendering a default time when its value is null#32314

Merged
kubaflo merged 7 commits intodotnet:inflight/currentfrom
SyedAbdulAzeemSF4852:fix-32266
Mar 21, 2026
Merged

[Windows] Fix for TimePicker rendering a default time when its value is null#32314
kubaflo merged 7 commits intodotnet:inflight/currentfrom
SyedAbdulAzeemSF4852:fix-32266

Conversation

@SyedAbdulAzeemSF4852
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 if this change resolves your issue. Thank you!

Issue Details

  • On Windows, TimePicker renders a default time when its value is null, both on first load and after runtime updates, instead of showing an empty state.
  • On macOS, DatePicker and TimePicker render the default date/time when their values are null, again both initially and dynamically, rather than remaining empty.

Root Cause

Windows :

  • The TimePicker handler uses the null-coalescing operator with TimeSpan.Zero when the Time property is null. As a result, it defaults to 12:00 AM in 12-hour format and 00:00 in 24-hour format.

Description of Change

  • Updated TimePickerExtensions.UpdateTime to clear the native control's time value when the logical time is null, instead of defaulting to midnight.
  • Documentation : Time Picker

Regarding Mac Platform :

  • The same behavior is observed on the native platform as well. The values are not cleared when the date or time picker is set to null. In such cases, the default date or time is rendered.

Issues Fixed

Fixes #32266

Validated the behaviour in the following platforms

  • Windows
  • Android
  • iOS
  • Mac

Output

Before After

@dotnet-policy-service dotnet-policy-service bot added the community ✨ Community Contribution label Oct 31, 2025
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Hey there @@SyedAbdulAzeemSF4852! 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 Oct 31, 2025
@jsuarezruiz
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).


[Test]
[Category(UITestCategories.TimePicker)]
public void VerifyTimePickerNotMidnightOnNull()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pending snapshots on Mac and Windows already available in the latest build.

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@jsuarezruiz , Since I’ve modified the test case and its method name, I will add the snapshots for Mac and Windows platforms after the next CI run.

@jsuarezruiz
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).

@SyedAbdulAzeemSF4852 SyedAbdulAzeemSF4852 marked this pull request as ready for review November 4, 2025 06:03
Copilot AI review requested due to automatic review settings November 4, 2025 06:03
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

This PR fixes an issue where the Windows TimePicker incorrectly defaults to displaying midnight (00:00) when the Time value is null, instead of showing an empty/placeholder state. The fix changes the Windows platform implementation to use the SelectedTime property directly, which properly supports null values.

Key changes:

  • Updated Windows platform time assignment from Time (with null-coalescing to TimeSpan.Zero) to SelectedTime (supports nullable)
  • Added comprehensive UI tests verifying null initial state and cleared time behavior
  • Added platform-specific screenshot snapshots for iOS, macOS, and Android

Reviewed Changes

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

Show a summary per file
File Description
src/Core/src/Platform/Windows/TimePickerExtensions.cs Changed from Time property with null-coalescing to SelectedTime property for proper null handling
src/Controls/tests/TestCases.HostApp/Issues/Issue32266.cs Added test page with TimePicker initialized to null and buttons to set/clear time
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32266.cs Added UI tests verifying null state and clear behavior
src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/*.png Added iOS screenshot baselines for both test scenarios
src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/*.png Added macOS screenshot baselines for both test scenarios
src/Controls/tests/TestCases.Android.Tests/snapshots/android/*.png Added Android screenshot baselines for both test scenarios

@jsuarezruiz
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).

@sheiksyedm
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).

@jfversluis
Copy link
Copy Markdown
Member

/rebase

@jfversluis
Copy link
Copy Markdown
Member

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 9, 2025

🚀 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 -- 32314

Or

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

@jfversluis
Copy link
Copy Markdown
Member

jfversluis commented Dec 10, 2025

/azp run MAUI-UITests-public

@dotnet dotnet deleted a comment from azure-pipelines bot Dec 10, 2025
@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@dotnet dotnet deleted a comment from azure-pipelines bot Dec 10, 2025
@dotnet dotnet deleted a comment from azure-pipelines bot Dec 10, 2025
@dotnet dotnet deleted a comment from azure-pipelines bot Dec 10, 2025
@MauiBot
Copy link
Copy Markdown
Collaborator

MauiBot commented Mar 21, 2026

🤖 AI Summary

📊 Expand Full Reviewd92fb19 · Merge branch 'dotnet:main' into fix-32266
🔍 Pre-Flight — Context & Validation

Issue: #32266 - Nullable support is not working properly on Windows TimePicker and macOS DatePicker and TImePicker
PR: #32314 - [Windows] Fix for TimePicker rendering a default time when its value is null
Platforms Affected: Issue reports Windows and macOS; this PR targets Windows
Files Changed: 2 implementation, 10 test

Key Findings

  • The linked issue reports two Windows behaviors that must be covered: TimePicker.Time = null on initial load and after runtime updates should leave the control unset instead of displaying midnight.
  • The same issue also reports macOS null-value behavior, but a maintainer comment says native macOS currently cannot clear these values, so this PR intentionally narrows scope to the Windows fix.
  • Review feedback asked for two concrete test cases: nullable initial state support and clearing after assigning a real time. The PR added a HostApp issue page, shared UI tests, and per-platform screenshot baselines.
  • Review feedback on the Windows implementation explicitly suggested using WinUI's nullable SelectedTime API to preserve the unset state.
  • No prior PRAgent-style review comment was found to resume from.

Changed File Classification

  • Implementation:
    • src/Core/src/Handlers/TimePicker/TimePickerHandler.Windows.cs
    • src/Core/src/Platform/Windows/TimePickerExtensions.cs
  • UI test source:
    • src/Controls/tests/TestCases.HostApp/Issues/Issue32266.cs
    • src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32266.cs
  • UI screenshot baselines:
    • src/Controls/tests/TestCases.Android.Tests/snapshots/android/VerifyClearedTimeDoesNotShowMidnight.png
    • src/Controls/tests/TestCases.Android.Tests/snapshots/android/VerifyTimePickerIsNullOnInitialLoad.png
    • src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyClearedTimeDoesNotShowMidnight.png
    • src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyTimePickerIsNullOnInitialLoad.png
    • src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyClearedTimeDoesNotShowMidnight.png
    • src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyTimePickerIsNullOnInitialLoad.png
    • src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyClearedTimeDoesNotShowMidnight.png
    • src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyTimePickerIsNullOnInitialLoad.png

Test Type

  • UI test (TestCases.HostApp + TestCases.Shared.Tests)

Edge Cases from Issue and Review Discussion

  • Initial load with Time = null
  • Clearing the value back to null after first assigning a non-null time
  • Windows uses nullable SelectedTime; macOS still has a native-platform limitation for clearing date/time picker values

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #32314 Use WinUI nullable SelectedTime instead of coercing null to TimeSpan.Zero, and listen to SelectedTimeChanged; add UI coverage for initial-null and clear-to-null flows ⏳ PENDING (Gate) src/Core/src/Handlers/TimePicker/TimePickerHandler.Windows.cs, src/Core/src/Platform/Windows/TimePickerExtensions.cs, src/Controls/tests/TestCases.HostApp/Issues/Issue32266.cs, src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32266.cs, snapshot baselines Original PR

🚦 Gate — Test Verification

Gate Result: ✅ PASSED

Platform: windows
Mode: Full Verification

  • Tests FAIL without fix: ✅
  • Tests PASS with fix: ✅

Evidence

  • Verification ran through the required isolated skill flow for Issue32266.
  • The reverted baseline reproduced the bug: both VerifyTimePickerIsNullOnInitialLoad and VerifyClearedTimeDoesNotShowMidnight failed.
  • Restoring the PR changes made both UI tests pass on Windows.

Logs

  • CustomAgentLogsTmp/PRState/32314/PRAgent/gate/verify-tests-fail/verification-report.md
  • CustomAgentLogsTmp/PRState/32314/PRAgent/gate/verify-tests-fail/verification-log.txt

🔧 Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix Use RegisterPropertyChangedCallback on TimePicker.SelectedTimeProperty instead of the SelectedTimeChanged CLR event, while mapping null through WinUI SelectedTime ✅ PASS 2 files Works, but adds lower-level DP callback plumbing without improving the core fix
2 try-fix Keep TimeChanged, but read nullable sender.SelectedTime instead of non-nullable e.NewTime; still map MAUI Time to WinUI SelectedTime ✅ PASS 2 files Suggests the forward null-preserving mapping is the essential behavior
3 try-fix Keep existing handler wiring, but when MAUI Time is null, clear WinUI TimePicker.TimeProperty and set SelectedTime = null ✅ PASS 1 file Smallest passing variant, but it only addresses the forward mapping path and leaves reverse nullable sync semantics implicit
4 try-fix Hybrid mapping: set platformView.Time for non-null values, but explicitly set platformView.SelectedTime = null for null; keep TimeChanged and read nullable state from SelectedTime ✅ PASS 2 files Passed tests, but artifact output was incomplete (attempt-1.patch instead of a full attempt-4 directory)
5 try-fix Change TimePicker.TimeProperty default from new TimeSpan(0) to null at the Controls source-model layer ❌ FAIL 1 file Did not fix either Windows screenshot test; the bug is not solved at the default-value layer alone
6 try-fix Defer SelectedTime = null until after WinUI initialization/template application by using Loaded or DispatcherQueue ✅ PASS 1 file Works, but introduces lifecycle/timing complexity that simpler fixes avoid
7 try-fix Use ClearValue(TimePicker.SelectedTimeProperty) for null state and narrowly ignore native null-to-null feedback in the handler ✅ PASS 2 files Distinct DP-clear semantics path; passes but is more stateful and indirect than necessary
8 try-fix Sync MAUI Time from WinUI only on a user-commit surrogate and ignore programmatic updates during initialization ❌ FAIL 1 file Failed after iteration; commit-only sync did not fix the Windows placeholder behavior
9 try-fix Make the Controls ITimePicker.Time implementation Windows value-source-aware (!IsSet(TimeProperty) => null) and combine that with nullable SelectedTime mapping ✅ PASS 3 files Passes, but it broadens the change into the Controls layer and is more invasive than needed
PR PR #32314 Map ITimePicker.Time to WinUI nullable SelectedTime and switch handler synchronization from TimeChanged to SelectedTimeChanged ✅ PASSED (Gate) 4 source files + snapshot baselines Original PR; aligned with WinUI nullable API semantics and reviewer guidance

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 1 Yes DependencyProperty callback on SelectedTimeProperty
claude-sonnet-4.6 1 Yes Keep TimeChanged, but read sender.SelectedTime
gpt-5.3-codex 1 Yes Clear WinUI TimeProperty and set SelectedTime = null while leaving handler wiring in place
gemini-3-pro-preview 1 Yes Hybrid null handling: use Time for non-null, SelectedTime = null for null, keep TimeChanged
claude-opus-4.6 2 No NO NEW IDEAS
claude-sonnet-4.6 2 No NO NEW IDEAS
gpt-5.3-codex 2 Yes Change the Controls TimeProperty default to null
gemini-3-pro-preview 2 Yes Defer null assignment until after native initialization via Loaded or DispatcherQueue
claude-opus-4.6 3 No NO NEW IDEAS
claude-sonnet-4.6 3 No NO NEW IDEAS
gpt-5.3-codex 3 Yes Use ClearValue(TimePicker.SelectedTimeProperty) for the null state, then a commit-only sync idea
gemini-3-pro-preview 3 Yes Make the mapping value-source-aware so default MAUI time does not propagate as a native value

Exhausted: Yes

Best-Fix Comparison

Candidate Why it passes Trade-offs
PR #32314 Uses WinUI's nullable SelectedTime API in both mapping and event synchronization Slightly larger than the smallest passing alternative, but direct and idiomatic
Candidate #3 Minimal forward-path fix Does not explicitly modernize reverse sync semantics; narrower than the PR
Candidate #6 Handles a possible initialization race Adds lifecycle/timing complexity
Candidate #9 Distinguishes default MAUI value from an explicitly set midnight Broadens scope into Controls and adds Windows-specific value-source behavior

Selected Fix: PR #32314 — It is the best overall fix because it is robust, passes Gate, matches the WinUI nullable API model directly, and avoids the extra lifecycle, DP-state, or Controls-layer complexity introduced by the alternative passing attempts.


📋 Report — Final Recommendation

✅ Final Recommendation: APPROVE

Phase Status

Phase Status Notes
Pre-Flight ✅ COMPLETE Linked issue is #32266; PR scope is appropriately narrowed to Windows even though the original issue also mentions macOS
Gate ✅ PASSED Windows full verification proved the tests fail without the fix and pass with it
Try-Fix ✅ COMPLETE 9 attempts run, 7 passing; PR fix selected as best overall
Report ✅ COMPLETE

Summary

PR #32314 fixes the Windows TimePicker null-state bug by switching the native mapping to WinUI's nullable SelectedTime API and syncing native changes through SelectedTimeChanged. The added UI coverage correctly verifies both required scenarios: initial load with Time = null and clearing back to null after setting a value.

I also ran a full try-fix exploration across the required models. Several alternative implementations passed the same tests, but the PR's version is still the best choice because it uses the intended WinUI nullable API directly, stays within the Windows platform layer, and avoids the extra lifecycle hooks, dependency-property bookkeeping, or Controls-layer semantics changes introduced by the alternatives.

Root Cause

The Windows platform implementation treated a nullable MAUI TimePicker.Time as though it always had a value. Specifically, it pushed null through the non-nullable native Time API by coercing it to TimeSpan.Zero, which rendered as midnight. The PR corrects that by using WinUI's nullable SelectedTime property and associated nullable event path.

Fix Quality

The fix is good and review-ready.

  • It matches reviewer guidance from the PR discussion to use WinUI's nullable SelectedTime.
  • It passed Gate verification on Windows with the exact issue tests.
  • It is more robust than the smaller passing variants because it handles both native mapping and native-to-virtual synchronization using the same nullable API surface.
  • It avoids broader behavioral changes such as altering the Controls default value or adding Windows-specific IsSet(TimeProperty) semantics in the shared layer.

@MauiBot MauiBot added s/agent-approved AI agent recommends approval - PR fix is correct and optimal 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 Mar 21, 2026
@kubaflo kubaflo changed the base branch from main to inflight/current March 21, 2026 23:30
@kubaflo kubaflo merged commit 41c3a04 into dotnet:inflight/current Mar 21, 2026
16 of 29 checks passed
PureWeen pushed a commit that referenced this pull request Mar 24, 2026
…is null (#32314)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details
- On Windows, TimePicker renders a default time when its value is null,
both on first load and after runtime updates, instead of showing an
empty state.
- On macOS, DatePicker and TimePicker render the default date/time when
their values are null, again both initially and dynamically, rather than
remaining empty.

### Root Cause

Windows :
- The TimePicker handler uses the null-coalescing operator with
TimeSpan.Zero when the Time property is null. As a result, it defaults
to 12:00 AM in 12-hour format and 00:00 in 24-hour format.


### Description of Change
- Updated TimePickerExtensions.UpdateTime to clear the native control's
time value when the logical time is null, instead of defaulting to
midnight.
- Documentation : [Time
Picker](https://learn.microsoft.com/en-us/windows/apps/design/controls/time-picker#:~:text=When%20SelectedTime%20is%20null%2C%20the%20picker%20is%20%27unset%27%20and%20shows%20the%20field%20names%20instead%20of%20a%20time.)

**Regarding Mac Platform :**
- The same behavior is observed on the native platform as well. The
values are not cleared when the date or time picker is set to null. In
such cases, the default date or time is rendered.

### Issues Fixed
Fixes #32266 

### Validated the behaviour in the following platforms

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

### Output

| Before | After |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/70d2fda1-66e4-4083-8df5-75c064ada067">
| <img
src="https://github.com/user-attachments/assets/33f4fc5f-456f-4de8-b72c-99c07dc07eaa">
|
KarthikRajaKalaimani pushed a commit to KarthikRajaKalaimani/maui that referenced this pull request Mar 30, 2026
…is null (dotnet#32314)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details
- On Windows, TimePicker renders a default time when its value is null,
both on first load and after runtime updates, instead of showing an
empty state.
- On macOS, DatePicker and TimePicker render the default date/time when
their values are null, again both initially and dynamically, rather than
remaining empty.

### Root Cause

Windows :
- The TimePicker handler uses the null-coalescing operator with
TimeSpan.Zero when the Time property is null. As a result, it defaults
to 12:00 AM in 12-hour format and 00:00 in 24-hour format.


### Description of Change
- Updated TimePickerExtensions.UpdateTime to clear the native control's
time value when the logical time is null, instead of defaulting to
midnight.
- Documentation : [Time
Picker](https://learn.microsoft.com/en-us/windows/apps/design/controls/time-picker#:~:text=When%20SelectedTime%20is%20null%2C%20the%20picker%20is%20%27unset%27%20and%20shows%20the%20field%20names%20instead%20of%20a%20time.)

**Regarding Mac Platform :**
- The same behavior is observed on the native platform as well. The
values are not cleared when the date or time picker is set to null. In
such cases, the default date or time is rendered.

### Issues Fixed
Fixes dotnet#32266 

### Validated the behaviour in the following platforms

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

### Output

| Before | After |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/70d2fda1-66e4-4083-8df5-75c064ada067">
| <img
src="https://github.com/user-attachments/assets/33f4fc5f-456f-4de8-b72c-99c07dc07eaa">
|
sheiksyedm pushed a commit that referenced this pull request Apr 4, 2026
…is null (#32314)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Issue Details
- On Windows, TimePicker renders a default time when its value is null,
both on first load and after runtime updates, instead of showing an
empty state.
- On macOS, DatePicker and TimePicker render the default date/time when
their values are null, again both initially and dynamically, rather than
remaining empty.

### Root Cause

Windows :
- The TimePicker handler uses the null-coalescing operator with
TimeSpan.Zero when the Time property is null. As a result, it defaults
to 12:00 AM in 12-hour format and 00:00 in 24-hour format.


### Description of Change
- Updated TimePickerExtensions.UpdateTime to clear the native control's
time value when the logical time is null, instead of defaulting to
midnight.
- Documentation : [Time
Picker](https://learn.microsoft.com/en-us/windows/apps/design/controls/time-picker#:~:text=When%20SelectedTime%20is%20null%2C%20the%20picker%20is%20%27unset%27%20and%20shows%20the%20field%20names%20instead%20of%20a%20time.)

**Regarding Mac Platform :**
- The same behavior is observed on the native platform as well. The
values are not cleared when the date or time picker is set to null. In
such cases, the default date or time is rendered.

### Issues Fixed
Fixes #32266 

### Validated the behaviour in the following platforms

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

### Output

| Before | After |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/70d2fda1-66e4-4083-8df5-75c064ada067">
| <img
src="https://github.com/user-attachments/assets/33f4fc5f-456f-4de8-b72c-99c07dc07eaa">
|
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-datetimepicker DatePicker, TimePicker community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/windows s/agent-approved AI agent recommends approval - PR fix is correct and optimal 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)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Nullable support is not working properly on Windows TimePicker and macOS DatePicker and TImePicker

8 participants