Skip to content

Picker: Refresh ItemDisplayBinding when bound item properties change#29922

Open
devanathan-vaithiyanathan wants to merge 16 commits into
dotnet:mainfrom
devanathan-vaithiyanathan:fix-25634
Open

Picker: Refresh ItemDisplayBinding when bound item properties change#29922
devanathan-vaithiyanathan wants to merge 16 commits into
dotnet:mainfrom
devanathan-vaithiyanathan:fix-25634

Conversation

@devanathan-vaithiyanathan

@devanathan-vaithiyanathan devanathan-vaithiyanathan commented Jun 11, 2025

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

Picker does not refresh displayed item when bound property changes through ItemDisplayBinding

Description of Change

Added support to automatically refresh the Picker display when a bound item's property changes. Subscribed to property change events in the items source, and updated the display when the property defined in ItemDisplayBinding changes. Also handled item additions and removals by updating the subscriptions accordingly.

Issues Fixed

Fixes #25634

Tested the behavior in the following platforms.

  • Android
  • Windows
  • iOS
  • Mac
Before After
iOS
iOS-BeforeFix.mov
iOS
iOS-AfterFix.mov

@dotnet-policy-service dotnet-policy-service Bot added community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration labels Jun 11, 2025
Comment thread src/Controls/src/Core/Picker/Picker.cs Outdated
Comment thread src/Controls/src/Core/Picker/Picker.cs Outdated
Comment thread src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue25634.cs Outdated
Comment thread src/Controls/tests/TestCases.HostApp/Issues/Issue25634.cs Outdated
Comment thread src/Controls/src/Core/Picker/Picker.cs Outdated
Comment thread src/Controls/tests/TestCases.HostApp/Issues/Issue25634.cs Outdated
@jsuarezruiz

Copy link
Copy Markdown
Contributor

/azp run MAUI-UITests-public

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

{
App.WaitForElement("PickerButton");
App.Tap("PickerButton");
VerifyScreenshot();

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 snapshot in all the platforms. Already available in the latest build.
image
Could you commit the images?

@jsuarezruiz

Copy link
Copy Markdown
Contributor

/azp run MAUI-UITests-public

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jsuarezruiz jsuarezruiz left a comment

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 test snapshots on Mac and Windows.
image

@devanathan-vaithiyanathan

Copy link
Copy Markdown
Contributor Author

Pending test snapshots on Mac and Windows. image

@jsuarezruiz , pending snapshots has been added.

@devanathan-vaithiyanathan devanathan-vaithiyanathan marked this pull request as ready for review June 13, 2025 10:11
@devanathan-vaithiyanathan devanathan-vaithiyanathan requested a review from a team as a code owner June 13, 2025 10:11
@jsuarezruiz

Copy link
Copy Markdown
Contributor

/azp run MAUI-UITests-public

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Comment thread src/Controls/src/Core/Picker/Picker.cs Outdated

void OnItemsSourceChanged(IList oldValue, IList newValue)
{
if (oldValue is not null)

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.

This logic is duplicated, can extract it to a method.

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.

Inside the methods, check items.Count == 0 before iterating to avoid unnecessary loops

Copilot AI review requested due to automatic review settings December 9, 2025 08:08
@github-actions

github-actions Bot commented Dec 9, 2025

Copy link
Copy Markdown
Contributor

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

Or

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

Copilot AI left a comment

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.

Pull request overview

This PR adds support for automatically refreshing the Picker display when a bound item's property changes through ItemDisplayBinding. The implementation subscribes to PropertyChanged events on items in the ItemsSource and updates the display when the bound property changes.

Key Changes:

  • Event subscription for INotifyPropertyChanged items in ItemsSource
  • Automatic refresh when bound property changes
  • Dynamic subscription/unsubscription when items are added/removed
  • Comprehensive UI tests with screenshot verification for all platforms

Reviewed changes

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

Show a summary per file
File Description
src/Controls/src/Core/Picker/Picker.cs Core implementation: adds PropertyChanged event handling for items, subscription/unsubscription logic in OnItemsSourceChanged and CollectionChanged methods
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue25634.cs NUnit UI test verifying the picker display updates after property change
src/Controls/tests/TestCases.HostApp/Issues/Issue25634.cs Test HostApp page with Picker, ObservableCollection, and INotifyPropertyChanged model
src/Controls/tests/TestCases.Android.Tests/snapshots/android/VerifyPickerItemDisplayBindingValue.png Android test screenshot baseline
src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/VerifyPickerItemDisplayBindingValue.png iOS test screenshot baseline
src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifyPickerItemDisplayBindingValue.png Windows test screenshot baseline
src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifyPickerItemDisplayBindingValue.png MacCatalyst test screenshot baseline

{
if (e.PropertyName == binding.Path)
{
ResetItems();

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

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

Potential performance issue: ResetItems() is called for every property change on any item, even if that item is not currently visible or selected. For large collections where many items change their properties simultaneously, this could cause excessive UI updates.

Consider optimizing to only refresh the display when the selected item's property changes:

void OnPickerItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (ItemDisplayBinding is Binding binding && !string.IsNullOrEmpty(binding.Path))
    {
        if (e.PropertyName == binding.Path)
        {
            // Only reset if the changed item is the currently selected item
            // or if we need to update all items in the dropdown
            if (sender == SelectedItem)
            {
                // Update just the display text for the selected item
                Handler?.UpdateValue(nameof(IPicker.SelectedItem));
            }
            else
            {
                // For items in the dropdown list, consider a more targeted update
                ResetItems();
            }
        }
    }
}
Suggested change
ResetItems();
// Only reset if the changed item is not the currently selected item
if (sender == SelectedItem)
{
// Update just the display text for the selected item
Handler?.UpdateValue(nameof(IPicker.SelectedItem));
}
else
{
// For items in the dropdown list, update the items
ResetItems();
}

Copilot uses AI. Check for mistakes.
Comment thread src/Controls/src/Core/Picker/Picker.cs Outdated
Comment on lines +374 to +378
if (e.PropertyName == binding.Path)
{
ResetItems();
}
}

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

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

The OnPickerItemPropertyChanged method only handles Binding type but not other BindingBase types like TypedBinding or custom binding implementations. This could cause the feature to silently fail for other binding types.

Consider handling all BindingBase types or documenting the limitation:

void OnPickerItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (ItemDisplayBinding is Binding binding && !string.IsNullOrEmpty(binding.Path))
    {
        if (e.PropertyName == binding.Path || string.IsNullOrEmpty(e.PropertyName))
        {
            ResetItems();
        }
    }
    else if (ItemDisplayBinding is not null && ItemDisplayBinding is not Binding)
    {
        // For other binding types, refresh on any property change
        // since we can't determine the specific path
        ResetItems();
    }
}

Note: Also consider checking for string.IsNullOrEmpty(e.PropertyName) which indicates all properties changed.

Suggested change
if (e.PropertyName == binding.Path)
{
ResetItems();
}
}
// For Binding, only reset if the relevant property changed, or all properties changed
if (e.PropertyName == binding.Path || string.IsNullOrEmpty(e.PropertyName))
{
ResetItems();
}
}
else if (ItemDisplayBinding is not null && ItemDisplayBinding is not Binding)
{
// For other BindingBase types (TypedBinding, custom), reset on any property change
ResetItems();
}

Copilot uses AI. Check for mistakes.
Comment thread src/Controls/src/Core/Picker/Picker.cs Outdated
Comment on lines +290 to +309
if (oldValue is not null)
{
foreach (var item in oldValue)
{
if (item is INotifyPropertyChanged npc)
{
npc.PropertyChanged -= OnPickerItemPropertyChanged;
}
}
}
if (newValue is not null && ItemDisplayBinding is not null)
{
foreach (var item in newValue)
{
if (item is INotifyPropertyChanged npc)
{
npc.PropertyChanged += OnPickerItemPropertyChanged;
}
}
}

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

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

Missing cleanup when Picker is disposed or removed from the visual tree. The PropertyChanged event handlers attached to items will prevent garbage collection of both the Picker and the items, causing a memory leak.

Consider overriding cleanup methods to unsubscribe from events:

protected override void OnHandlerChanging(HandlerChangingEventArgs args)
{
    base.OnHandlerChanging(args);
    
    if (args.NewHandler == null && ItemsSource is not null)
    {
        // Unsubscribe when being removed from the visual tree
        foreach (var item in ItemsSource)
        {
            if (item is INotifyPropertyChanged npc)
            {
                npc.PropertyChanged -= OnPickerItemPropertyChanged;
            }
        }
    }
}

Alternatively, use weak event patterns to avoid memory leaks.

Copilot uses AI. Check for mistakes.
@rmarinho rmarinho added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-win AI found a better alternative fix than the PR labels Feb 15, 2026
@dotnet dotnet deleted a comment from MauiBot May 6, 2026
@kubaflo kubaflo dismissed MauiBot’s stale review May 6, 2026 10:12

Resetting for re-review

@MauiBot

This comment has been minimized.

MauiBot

This comment was marked as outdated.

@MauiBot MauiBot added s/agent-fix-win AI found a better alternative fix than the PR and removed s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates labels May 6, 2026
@kubaflo

kubaflo commented May 24, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/refactor-copilot-yml

MauiBot

This comment was marked as outdated.

@MauiBot MauiBot added s/agent-review-incomplete and removed s/agent-changes-requested AI agent recommends changes - found a better alternative or issues labels May 24, 2026

@kubaflo kubaflo left a comment

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.

Could you please check the ai's suggestions?

@kubaflo

kubaflo commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/enhanced-reviewer -p ios

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Expert Review — 3 findings

See inline comments for details.


// Unsubscribe when being removed from visual tree to prevent memory leaks
if (args.NewHandler == null)
UnsubscribeFromItemPropertyChanges(ItemsSource);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[major] Handler lifecycle - This unsubscribes item PropertyChanged handlers when the picker loses its handler, but there is no matching re-subscribe path when the same picker later gets a new handler. Scenario: a Picker in a Shell tab or virtualized page is detached and reattached; subsequent ItemDisplayBinding property changes no longer refresh the displayed text.


void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
UnsubscribeFromItemPropertyChanges(e.OldItems);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[major] Memory Leak Prevention - NotifyCollectionChangedAction.Reset commonly has OldItems == null, so this leaves all previously subscribed items hooked to OnPickerItemPropertyChanged. After ObservableCollection.Clear() or a reset-style source refresh, removed item view models can still retain the Picker and trigger resets, causing stale callbacks and leaks.

{
if (ItemDisplayBinding is Binding binding && !string.IsNullOrEmpty(binding.Path))
{
if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == binding.Path)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[major] Logic and Correctness - Comparing PropertyChangedEventArgs.PropertyName to the full binding path misses nested-path invalidation. For ItemDisplayBinding = new Binding("Address.Name"), replacing the root Address property raises PropertyChanged("Address"), but this condition ignores it, leaving the picker text stale.

MauiBot

This comment was marked as outdated.

@kubaflo kubaflo left a comment

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.

Could you please check the ai's suggestions?

@devanathan-vaithiyanathan

Copy link
Copy Markdown
Contributor Author

Could you please check the ai's suggestions?

@kubaflo , I have addressed the AI suggestion

@kubaflo

kubaflo commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

/review -b feature/enhanced-reviewer -p ios

@github-actions github-actions Bot added the s/agent-review-in-progress AI review is currently running for this PR label Jun 15, 2026

@MauiBot MauiBot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

AI Review Summary

@devanathan-vaithiyanathan — new AI review results are available based on this last commit: 41bf371. To request a fresh review after new comments or commits, comment /review rerun.

Gate Passed Code Review Needs Changes Confidence Low Platform iOS

Review Sessions — click to expand
Gate — Test Before & After Fix

Gate Result: ✅ PASSED

Platform: IOS · Base: main · Merge base: bb4e7040

Test Without Fix (expect FAIL) With Fix (expect PASS)
🖥️ Issue25634 Issue25634 ✅ FAIL — 334s ✅ PASS — 125s
🔴 Without fix — 🖥️ Issue25634: FAIL ✅ · 334s
  Determining projects to restore...
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 662 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 650 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 5.07 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/Foldable/src/Controls.Foldable.csproj (in 6.86 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 6.86 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Xaml/Controls.Xaml.csproj (in 6.86 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj (in 6.86 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/Maps/src/Controls.Maps.csproj (in 6.86 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj (in 6.87 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 6.89 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/maps/src/Maps.csproj (in 6.2 sec).
/Users/cloudtest/vss/_work/1/s/.dotnet/packs/Microsoft.iOS.Sdk.net10.0_26.0/26.0.11017/targets/Xamarin.Shared.Sdk.targets(309,3): warning : RuntimeIdentifier was set on the command line, and will override the value for RuntimeIdentifiers set in the project file. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-ios]
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0-ios26.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0-ios26.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0-ios26.0/Microsoft.Maui.dll
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0-ios26.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.90-ci+azdo.14376859
  Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Maps.dll
  Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Xaml.dll
  Controls.Foldable -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Foldable.dll
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  Microsoft.AspNetCore.Components.WebView.Maui -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-ios26.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
  Controls.TestCases.HostApp -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-ios/iossimulator-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.

/Users/cloudtest/vss/_work/1/s/.dotnet/packs/Microsoft.iOS.Sdk.net10.0_26.0/26.0.11017/targets/Xamarin.Shared.Sdk.targets(309,3): warning : RuntimeIdentifier was set on the command line, and will override the value for RuntimeIdentifiers set in the project file. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-ios]
    1 Warning(s)
    0 Error(s)

Time Elapsed 00:03:04.17
  Determining projects to restore...
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 932 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 932 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/VisualTestUtils/VisualTestUtils.csproj (in 39 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Core/UITest.Core.csproj (in 7 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/CustomAttributes/Controls.CustomAttributes.csproj (in 3 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 81 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 1.11 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 1.13 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.NUnit/UITest.NUnit.csproj (in 1.81 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Appium/UITest.Appium.csproj (in 3.17 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Analyzers/UITest.Analyzers.csproj (in 4.17 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/VisualTestUtils.MagickNet/VisualTestUtils.MagickNet.csproj (in 6.97 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.iOS.Tests/Controls.TestCases.iOS.Tests.csproj (in 7 sec).
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  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.90-ci+azdo.14376859
  Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  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.90-ci+azdo.14376859
  Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  VisualTestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
  UITest.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.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.iOS.Tests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.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.
[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.08]   Discovering: Controls.TestCases.iOS.Tests
[xUnit.net 00:00:00.21]   Discovered:  Controls.TestCases.iOS.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
   NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 6/15/2026 4:42:36 AM FixtureSetup for Issue25634(iOS)
>>>>> 6/15/2026 4:42:40 AM VerifyPickerItemDisplayBindingValue Start
>>>>> 6/15/2026 4:42:44 AM VerifyPickerItemDisplayBindingValue Stop
>>>>> 6/15/2026 4:42:44 AM Log types: syslog, crashlog, performance, safariConsole, safariNetwork, server
  Failed VerifyPickerItemDisplayBindingValue [3 s]
  Error Message:
   VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyPickerItemDisplayBindingValue.png (1.15% difference)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow

  Stack Trace:
     at VisualTestUtils.VisualRegressionTester.Fail(String message) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 162
   at VisualTestUtils.VisualRegressionTester.VerifyMatchesSnapshot(String name, ImageSnapshot actualImage, String environmentName, ITestContext testContext) in /_/src/TestUtils/src/VisualTestUtils/VisualRegressionTester.cs:line 123
   at Microsoft.Maui.TestCases.Tests.UITest.<VerifyScreenshot>g__Verify|13_0(String name, <>c__DisplayClass13_0&) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 477
   at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 309
   at Microsoft.Maui.TestCases.Tests.Issues.Issue25634.VerifyPickerItemDisplayBindingValue() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue25634.cs:line 20
   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
Results File: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue25634.trx

Total tests: 1
     Failed: 1
Test Run Failed.
 Total time: 1.5301 Minutes
>>> TRX_RESULT_FILE: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue25634.trx

🟢 With fix — 🖥️ Issue25634: PASS ✅ · 125s
  Determining projects to restore...
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 427 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 449 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 403 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 500 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 517 ms).
  6 of 11 projects are up-to-date for restore.
/Users/cloudtest/vss/_work/1/s/.dotnet/packs/Microsoft.iOS.Sdk.net10.0_26.0/26.0.11017/targets/Xamarin.Shared.Sdk.targets(309,3): warning : RuntimeIdentifier was set on the command line, and will override the value for RuntimeIdentifiers set in the project file. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-ios]
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  Graphics -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Graphics/Debug/net10.0-ios26.0/Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0-ios26.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Core/Debug/net10.0-ios26.0/Microsoft.Maui.dll
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Maps/Debug/net10.0-ios26.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.90-ci+azdo.14376859
  Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  Controls.Maps -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Maps/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Maps.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Microsoft.AspNetCore.Components.WebView.Maui/Debug/net10.0-ios26.0/Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Xaml -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Xaml/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Xaml.dll
  Controls.Foldable -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Foldable.dll
  Detected signing identity:
    Code Signing Key: "" (-)
    Provisioning Profile: "" () - no entitlements
    Bundle Id: com.microsoft.maui.uitests
    App Id: com.microsoft.maui.uitests
  Controls.TestCases.HostApp -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.HostApp/Debug/net10.0-ios/iossimulator-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.

/Users/cloudtest/vss/_work/1/s/.dotnet/packs/Microsoft.iOS.Sdk.net10.0_26.0/26.0.11017/targets/Xamarin.Shared.Sdk.targets(309,3): warning : RuntimeIdentifier was set on the command line, and will override the value for RuntimeIdentifiers set in the project file. [/Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj::TargetFramework=net10.0-ios]
    1 Warning(s)
    0 Error(s)

Time Elapsed 00:01:03.44
  Determining projects to restore...
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 411 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 355 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 421 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 445 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 465 ms).
  8 of 13 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  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.90-ci+azdo.14376859
  Essentials -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Essentials/Debug/net10.0/Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14376859
  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.90-ci+azdo.14376859
  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.iOS.Tests -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
Test run for /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.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.
[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.06]   Discovering: Controls.TestCases.iOS.Tests
[xUnit.net 00:00:00.20]   Discovered:  Controls.TestCases.iOS.Tests
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.TestCases.iOS.Tests/Debug/net10.0/Controls.TestCases.iOS.Tests.dll
   NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 6/15/2026 4:44:44 AM FixtureSetup for Issue25634(iOS)
>>>>> 6/15/2026 4:44:49 AM VerifyPickerItemDisplayBindingValue Start
>>>>> 6/15/2026 4:44:50 AM VerifyPickerItemDisplayBindingValue Stop
  Passed VerifyPickerItemDisplayBindingValue [1 s]
NUnit Adapter 4.5.0.0: Test execution complete
Results File: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue25634.trx

Test Run Successful.
Total tests: 1
     Passed: 1
 Total time: 25.6668 Seconds
>>> TRX_RESULT_FILE: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue25634.trx

📁 Fix files reverted (9 files)
  • eng/pipelines/ci-copilot.yml
  • src/Controls/src/Core/Picker/Picker.cs
  • src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt
  • src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt

UI Tests — Picker

Detected UI test categories: Picker

Deep UI tests — 12 passed, 29 failed across 1 category on platform-pool agent (replaces in-process counts above).

🧪 UI Test Execution Results (deep, platform pool)

Category Tests Snapshot diffs
Picker 12/41 (29 ❌) 23 diff PNGs
Picker — 29 failed tests
CheckNavigationBreaksVisualStatesForPicker
System.InvalidOperationException : 
Snapshot different than baseline: CheckNavigationBreaksVisualStatesForPicker.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: CheckNavigationBreaksVisualStatesForPicker.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseli
...
PickerShouldDismissWhenClickOnOutside
System.InvalidOperationException : 
Snapshot different than baseline: PickerShouldDismissWhenClickOnOutside.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: PickerShouldDismissWhenClickOnOutside.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.

...
InvisibleTimepickerShowsDialogOnFocus
System.TimeoutException : Timed out waiting for element...
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.Issues.Issue5159.InvisibleTimepickerShowsDialogOnFocus() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/XFIssue/Issue5159.cs:line 34
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHa
...
PickerShouldRegainTitle
System.InvalidOperationException : 
Snapshot different than baseline: PickerShouldRegainTitle.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: PickerShouldRegainTitle.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or downl
...
Picker_TapPicker_TakeScreenshot
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_TapPicker_TakeScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 42
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectH
...
PickerShouldShowSelectedItemHighlight
System.InvalidOperationException : 
Snapshot different than baseline: PickerShouldShowSelectedItemHighlight.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: PickerShouldShowSelectedItemHighlight.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.

...
Picker_SetShadow_VerifyShadow
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_SetShadow_VerifyShadow() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 365
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHa
...
Picker_SetTextColorRed_VerifyTextColor
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_SetTextColorRed_VerifyTextColor() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 384
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments,
...
Issue1614Test
System.TimeoutException : Timed out waiting for element...
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.Issues.Issue1614.TapPicker(String picker) in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/XFIssue/Issue1614.cs:line 36
   at Microsoft.Maui.TestCases.Tests.Issues.Issue1614.Issue1614Test() in /_/src/Controls/tests/TestCases.Shared.Tes
...
InvisiblePickerShowsDialogOnFocus
System.TimeoutException : Timed out waiting for element...
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.Issues.Issue5159.InvisiblePickerShowsDialogOnFocus() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/XFIssue/Issue5159.cs:line 43
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandle
...
Picker_SetHorizontalTextAlignmentAndSelectedItem_VerifySelectedItem
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_SetHorizontalTextAlignmentAndSelectedItem_VerifySelectedItem() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 291
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnSt
...
PickerCanBeOpenedProgrammatically
System.NullReferenceException : Object reference not set to an instance of an object.
at UITest.Appium.HelperExtensions.Click(IUIElement element) in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 412
   at UITest.Appium.HelperExtensions.<>c__DisplayClass2_0.<Tap>b__0() in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 36
   at UITest.Appium.HelperExtensions.<>c__DisplayClass186_0.<RunWithTimeout>b__0() in /_/src/TestUtils/src/UITest.Appium/HelperExtensions.cs:line 3075
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Tas
...
Picker_Validate_VerifyLabels
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_Validate_VerifyLabels() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 31
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHand
...
Picker_SetCharacterSpacing_VerifyCharacterSpacingLabel
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_SetCharacterSpacing_VerifyCharacterSpacingLabel() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 120
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, V
...
ShouldAppearItemsWhenTappingOnPickerUsingPushModalAsync
System.InvalidOperationException : 
Snapshot different than baseline: ShouldAppearItemsWhenTappingOnPickerUsingPushModalAsync.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: ShouldAppearItemsWhenTappingOnPickerUsingPushModalAsync.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bu
...
PickerTitleShouldBeRed
System.InvalidOperationException : 
Snapshot different than baseline: PickerTitleShouldBeRed.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: PickerTitleShouldBeRed.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or downloa
...
Picker_SetSelectedItem_VerifySelectedItemLabel
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_SetSelectedItem_VerifySelectedItemLabel() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 102
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** ar
...
Picker_SetIsEnabledFalse_VerifyPickerDisabled
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_SetIsEnabledFalse_VerifyPickerDisabled() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 260
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arg
...
Picker_SetSelectedIndex_VerifySelectedIndexAndItem
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_SetSelectedIndex_VerifySelectedIndexAndItem() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 85
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void**
...
Issue32984PickerShouldResize
System.TimeoutException : Timed out waiting for element...
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.Issues.Issue32984.Issue32984PickerShouldResize() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32984.cs:line 26
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig
...
InvisibleDatepickerShowsDialogOnFocus
System.TimeoutException : Timed out waiting for element...
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.Issues.Issue5159.InvisibleDatepickerShowsDialogOnFocus() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/XFIssue/Issue5159.cs:line 25
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHa
...
Picker_SetFontSizeAndFontAttributesBold_VerifyFontSizeAndAttributes
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_SetFontSizeAndFontAttributesBold_VerifyFontSizeAndAttributes() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 165
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnSt
...
Picker_SetFontAttributesItalicAndFontFamilyDokdo_VerifyFontAttributesAndFontFamily
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_SetFontAttributesItalicAndFontFamilyDokdo_VerifyFontAttributesAndFontFamily() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 245
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(O
...
VerifyPickerItemDisplayBindingValue
System.InvalidOperationException : 
Snapshot different than baseline: VerifyPickerItemDisplayBindingValue.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: VerifyPickerItemDisplayBindingValue.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See 
...
Picker_SetFlowDirectionRTL_VerifyFlowDirection
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_SetFlowDirectionRTL_VerifyFlowDirection() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 205
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** ar
...
Issue16737Test
System.InvalidOperationException : 
Snapshot different than baseline: Issue16737Test.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: Issue16737Test.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build arti
...
Picker_SetFontSizeAndFontFamilyDokdo_VerifyFontSizeAndFontFamily
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_SetFontSizeAndFontFamilyDokdo_VerifyFontSizeAndFontFamily() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 187
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack
...
Picker_SetVerticalTextAlignmentAndSelectedItem_VerifySelectedItem
System.InvalidOperationException : Unable to extract difference percentage from exception message.
at Microsoft.Maui.TestCases.Tests.UITest.VerifyScreenshot(String name, Nullable`1 retryDelay, Nullable`1 retryTimeout, Int32 cropLeft, Int32 cropRight, Int32 cropTop, Int32 cropBottom, Double tolerance) in /_/src/Controls/tests/TestCases.Shared.Tests/UITest.cs:line 296
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.VerifyPickerScreenshot() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 22
   at Microsoft.Maui.TestCases.Tests.PickerFeatureTests.Picker_SetVerticalTextAlignmentAndSelectedItem_VerifySelectedItem() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/FeatureMatrix/PickerFeatureTests.cs:line 329
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
   at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStac
...
BlankScreenOnNavigationBack
System.InvalidOperationException : 
Snapshot different than baseline: BlankScreenOnNavigationBack.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment or download the build artifacts to get the new snapshot file.

More info: https://aka.ms/visual-test-workflow


iOS 26 visual tests require an iPhone 11 Pro simulator for correct screen resolution.
To create the simulator, run:
  xcrun simctl create "iPhone 11 Pro" com.apple.CoreSimulator.SimDeviceType.iPhone-11-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-0

Then run the tests targeting the new simulator.
  ----> VisualTestUtils.VisualTestFailedException : 
Snapshot different than baseline: BlankScreenOnNavigationBack.png (size differs - baseline is 1124x2286 pixels, actual is 1206x2472 pixels)
If the correct baseline has changed (this isn't a a bug), then update the baseline image.
See test attachment 
...

📎 Download drop-deep-uitests artifact (TRX + snapshot diffs)


Pre-Flight — Context & Validation

Issue: #25634 - Picker does not refresh displayed item when bound property changes through ItemDisplayBinding
PR: #29922 - Picker: Refresh ItemDisplayBinding when bound item properties change
Platforms Affected: Android, iOS, MacCatalyst, Windows (testing platform requested: iOS)
Files Changed: 8 implementation/API, 7 test/snapshot

Key Findings

  • PR changes Picker to subscribe to INotifyPropertyChanged items when ItemDisplayBinding is set and calls ResetItems() when the bound item property changes.
  • PR adds UI test coverage for issue #25634 with platform snapshots.
  • gh is unauthenticated; public PR metadata was fetched via GitHub REST and required checks could not be verified locally.
  • Gate result was provided by caller: Gate ✅ PASSED — tests fail without fix and pass with PR fix. Gate was not re-run.

Code Review Summary

Verdict: NEEDS_CHANGES
Confidence: low
Errors: 3 | Warnings: 0 | Suggestions: 0

Key code review findings:

  • src/Controls/src/Core/Picker/Picker.cs:398 Handler detach removes item subscriptions with no reconnect re-subscribe path.
  • src/Controls/src/Core/Picker/Picker.cs:427 NotifyCollectionChangedAction.Reset with null OldItems/NewItems can leak old item subscriptions and miss new current items.
  • src/Controls/src/Core/Picker/Picker.cs:415 Nested paths such as Address.Name do not refresh when the root property Address changes.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #29922 Subscribe each INotifyPropertyChanged item and call ResetItems() when PropertyName equals the ItemDisplayBinding path. ✅ PASSED (Gate) src/Controls/src/Core/Picker/Picker.cs, PublicAPI files, UI tests/snapshots Original PR; code review found lifecycle/reset/nested-path gaps.

Code Review — Deep Analysis

Code Review — PR #29922

Independent Assessment

What this changes: Picker now subscribes to INotifyPropertyChanged items in ItemsSource when ItemDisplayBinding is set, and refreshes displayed picker items via ResetItems() when item properties change. It also adds UI screenshot coverage.
Inferred motivation: Fix stale Picker display text when bound item view-model properties change after initial item rendering.

Reconciliation with PR Narrative

Author claims: Fixes #25634 by refreshing Picker.ItemDisplayBinding when bound item properties change, including item additions/removals.
Agreement/disagreement: The basic top-level property scenario (Binding("LastName")) is addressed, but lifecycle, reset collection changes, and nested binding paths remain incorrect.

Prior Review Reconciliation

Prior ❌ Error Finding Source Status Evidence
Handler detach/reconnect loses item property subscriptions MauiBot inline [major] ❌ Unresolved Current Picker.cs:392-398 unsubscribes when NewHandler == null; OnHandlerChanged does not re-subscribe.
Collection reset leaks old subscriptions / misses reset items MauiBot inline [major] ❌ Unresolved Current Picker.cs:425-430 only uses e.OldItems/e.NewItems, which are commonly null for Reset.
Nested binding paths are missed MauiBot inline [major] ❌ Unresolved Current Picker.cs:413-416 compares PropertyName to the full binding path.
Earlier gate failure on commit 920a2cc MauiBot review body 🔄 Obsolete/undetermined Current public check-runs for head 41bf371 appear completed success/skipped, but required checks could not be verified due unauthenticated gh.

Blast Radius Assessment

  • Runs for all instances: No — only Pickers with non-null ItemDisplayBinding, but this is core control behavior.
  • Startup impact: No.
  • Static/shared state: No.
  • Handler lifecycle impact: Yes — subscribes item events across handler attach/detach.

CI Status

  • Required-check result: undetermined
  • Classification: tool-unavailable for required-check query
  • Action taken: gh pr checks 29922 --repo dotnet/maui --required returned authentication guidance. Public GitHub check-runs for head were queried and appeared successful/skipped, but required-check status is not verifiable; confidence capped low.

Findings

❌ Error — Handler reconnect permanently disables item refresh

src/Controls/src/Core/Picker/Picker.cs:398

When the Picker loses its handler, OnHandlerChanging unsubscribes from all item PropertyChanged events. There is no matching re-subscribe when the same Picker receives a handler again. Shell tab switches, navigation detach/reattach, or handler recreation can leave the Picker unable to refresh ItemDisplayBinding changes after reconnect.

❌ Error — Reset collection changes leak subscriptions and miss current items

src/Controls/src/Core/Picker/Picker.cs:427

NotifyCollectionChangedAction.Reset often has OldItems == null and NewItems == null. The current code therefore cannot unsubscribe removed items or subscribe the collection’s current items after a reset-style refresh. Removed view models may retain the Picker and continue firing stale callbacks, while newly reset items may not refresh on property changes.

❌ Error — Nested binding paths do not refresh on root property changes

src/Controls/src/Core/Picker/Picker.cs:415

For ItemDisplayBinding = new Binding("Address.Name"), replacing Address usually raises PropertyChanged("Address"), not "Address.Name". The exact string comparison skips that valid invalidation, leaving Picker display text stale for nested bindings.

Failure-Mode Probing

  • Handler disconnect/reconnect: subscriptions are removed on disconnect and never restored, so refresh stops.
  • ObservableCollection.Clear() / reset: OldItems is commonly null, so old items remain subscribed.
  • Nested object replacement: PropertyChanged("Address") does not match "Address.Name", so display does not update.

Verdict: NEEDS_CHANGES

Confidence: low
Summary: The core scenario is improved, but three concrete correctness issues remain in lifecycle, collection reset handling, and nested binding invalidation. Required CI status could not be verified with unauthenticated gh, and prior major findings remain unresolved.


Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix-1 / claude-opus-4.6 HashSet-tracked item subscriptions, re-evaluate full binding on any item property change, then update the changed display string directly. ✅ PASS 11 files Passed iOS Issue25634, but added LockableObservableListWrapper.InternalSetItem public API and PublicAPI entries; not selected because the API surface increase is unnecessary for this Picker-only bug.
2 try-fix-2 / claude-opus-4.7 Picker-private HashSet<INotifyPropertyChanged> rebuilt from current ItemsSource on source/binding/collection/handler changes; smart path matching supports full path, root segment for nested/indexed paths, null/empty, and non-Binding refresh. ✅ PASS 1 file Selected: fixes handler reconnect, reset subscription leaks/misses, and nested path invalidation without public API churn. Self-review clean.
PR PR #29922 Subscribe INotifyPropertyChanged items from ItemsSource and call ResetItems() when PropertyName exactly matches Binding.Path. ✅ PASSED (Gate) 15 files Original PR; gate passed, but code review found unresolved lifecycle/reset/nested-path gaps.

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 1 Yes Candidate 1 proved that binding re-evaluation on item change passes the iOS regression and handles nested paths, but its targeted item update required new public API.
claude-opus-4.7 1 Yes Candidate 2 incorporated candidate 1's lessons while avoiding public API by using existing ResetItems() and Picker-private subscription tracking.

Exhausted: No — stopped because Candidate #2 passed all requested tests and is demonstrably better than the PR's current fix and Candidate #1.
Selected Fix: Candidate #2 — it passes the iOS regression, keeps the change isolated to Picker.cs, avoids public API additions, and directly addresses all three expert-review defects: handler reconnect, collection reset, and nested binding paths.

Candidate Details

try-fix-1

  • Output: CustomAgentLogsTmp/PRState/29922/PRAgent/try-fix-1/content.md
  • Attempt artifacts: CustomAgentLogsTmp/PRState/29922/PRAgent/try-fix/attempt-1/
  • Result: Pass
  • Failure analysis: Not failed; rejected as best fix because it introduces unnecessary public API surface and PublicAPI churn.

try-fix-2

  • Output: CustomAgentLogsTmp/PRState/29922/PRAgent/try-fix-2/content.md
  • Attempt artifacts: CustomAgentLogsTmp/PRState/29922/PRAgent/try-fix/attempt-2/
  • Result: Pass
  • Failure analysis: Not failed; first iteration hit CA1307 analyzer errors for IndexOf(char), fixed with StringComparison.Ordinal, then iOS UI test passed.

Report — Final Recommendation

Comparative Fix Report — PR #29922

Candidates compared

Rank Candidate Regression result Assessment
1 try-fix-2 PASS Best candidate. It fixes the PR's verified scenario and all expert-review defects: handler reconnect, collection reset subscription correctness, and nested/indexed binding path invalidation. It is localized to Picker.cs and adds no public API.
2 pr-plus-reviewer Not independently re-run; equivalent feedback is covered by try-fix-2 The expert-feedback application is the right direction and maps to the same Picker-private rebuild strategy as try-fix-2, but the separately recorded passing test evidence belongs to try-fix-2.
3 try-fix-1 PASS Correctly handles lifecycle, reset, and nested path cases, but does so by adding LockableObservableListWrapper.InternalSetItem public API and corresponding PublicAPI entries for a Picker-only bug. That API churn is unnecessary.
4 pr PASS for provided gate only The raw PR passes the provided top-level iOS gate, but expert review found unresolved correctness defects for handler reconnect, collection reset, and nested binding paths.

Winning candidate

Winner: try-fix-2

try-fix-2 is the single strongest candidate because it passed the requested iOS regression and addresses every actionable expert-review issue without expanding public API surface. The raw PR must rank below it despite passing the gate because its implementation still has lifecycle and correctness gaps; try-fix-1 must rank below it because its public API addition is unnecessary for this localized Picker fix.

Notes

  • No candidate with a failed regression test outranks a passing candidate.
  • gh required-check queries were blocked by missing authentication, so CI state was not used to promote any untested candidate above a tested one.

Future Action — alternative fix proposed (try-fix-2)

Automated review — alternative fix proposed

The expert-reviewer evaluation compared the PR fix against automatically generated candidates and selected try-fix-2 as the strongest fix.

Why: try-fix-2 passed the requested iOS regression and fixes all expert-review defects: handler reconnect, collection Reset subscription correctness, and nested/indexed binding path invalidation. It keeps the change localized to Picker.cs and avoids the unnecessary public API expansion in try-fix-1.

Please consider applying the candidate diff below (or use it as guidance). Once you push an update, this workflow will re-trigger and re-evaluate.

Candidate diff (try-fix-2)
diff --git a/src/Controls/src/Core/Picker/Picker.cs b/src/Controls/src/Core/Picker/Picker.cs
index 2b8f363bbf..6320af9f9f 100644
--- a/src/Controls/src/Core/Picker/Picker.cs
+++ b/src/Controls/src/Core/Picker/Picker.cs
@@ -237,7 +237,7 @@ namespace Microsoft.Maui.Controls
 					return;
 
 				OnPropertyChanging();
-				var oldValue = value;
+				var oldValue = _itemDisplayBinding;
 				_itemDisplayBinding = value;
 				OnItemDisplayBindingChanged(oldValue, _itemDisplayBinding);
 				OnPropertyChanged();
@@ -274,6 +274,31 @@ namespace Microsoft.Maui.Controls
 			return (string)GetValue(s_displayProperty);
 		}
 
+		// Tracks INotifyPropertyChanged items in ItemsSource that we have subscribed to.
+		// Kept independent of NotifyCollectionChangedEventArgs (which can have null OldItems/NewItems on Reset)
+		// and of handler attach/detach state, so we can always unsubscribe what we actually subscribed to.
+		// Reference equality ensures distinct item instances are tracked separately even if they override Equals.
+		readonly HashSet<INotifyPropertyChanged> _subscribedItems = new HashSet<INotifyPropertyChanged>(ReferenceEqualityComparer.Instance);
+
+		void RebuildItemSubscriptions()
+		{
+			// Unsubscribe what we currently track.
+			foreach (var npc in _subscribedItems)
+				npc.PropertyChanged -= OnPickerItemPropertyChanged;
+			_subscribedItems.Clear();
+
+			// Only subscribe when we have a display binding AND a live handler — without a handler
+			// there is nothing to update visually, and we re-subscribe in OnHandlerChanged.
+			if (ItemDisplayBinding is null || ItemsSource is null || Handler is null)
+				return;
+
+			foreach (var item in ItemsSource)
+			{
+				if (item is INotifyPropertyChanged npc && _subscribedItems.Add(npc))
+					npc.PropertyChanged += OnPickerItemPropertyChanged;
+			}
+		}
+
 		static object CoerceSelectedIndex(BindableObject bindable, object value)
 		{
 			var picker = (Picker)bindable;
@@ -282,6 +307,7 @@ namespace Microsoft.Maui.Controls
 
 		void OnItemDisplayBindingChanged(BindingBase oldValue, BindingBase newValue)
 		{
+			RebuildItemSubscriptions();
 			ResetItems();
 		}
 
@@ -325,6 +351,10 @@ namespace Microsoft.Maui.Controls
 				((LockableObservableListWrapper)Items).IsLocked = false;
 				((LockableObservableListWrapper)Items).InternalClear();
 			}
+
+			// Rebuild item subscriptions from the new source — handles oldValue items being unsubscribed
+			// and newValue items being subscribed (when ItemDisplayBinding is set and a handler exists).
+			RebuildItemSubscriptions();
 		}
 
 		readonly Queue<Action> _pendingIsOpenActions = new Queue<Action>();
@@ -345,6 +375,10 @@ namespace Microsoft.Maui.Controls
 		{
 			base.OnHandlerChanged();
 
+			// Re-establish item subscriptions whenever the handler attaches/detaches,
+			// so a Picker that gets disconnected and later reattached still tracks item changes.
+			RebuildItemSubscriptions();
+
 			// Process any pending actions when handler becomes available
 			while (_pendingIsOpenActions.Count > 0 && Handler != null)
 			{
@@ -364,8 +398,64 @@ namespace Microsoft.Maui.Controls
 				picker.Closed?.Invoke(picker, PickerClosedEventArgs.Empty);
 		}
 
+		void OnPickerItemPropertyChanged(object sender, PropertyChangedEventArgs e)
+		{
+			if (ItemDisplayBinding is null)
+				return;
+
+			if (ItemDisplayBinding is Binding binding)
+			{
+				var path = binding.Path;
+
+				// A null/empty PropertyName means "all properties may have changed" (INPC convention).
+				// A null/empty binding path also means the whole item is the display value.
+				if (string.IsNullOrEmpty(e.PropertyName) || string.IsNullOrEmpty(path))
+				{
+					ResetItems();
+					return;
+				}
+
+				// Full-path match (e.g. "Name" matches "Name").
+				if (path == e.PropertyName)
+				{
+					ResetItems();
+					return;
+				}
+
+				// Nested-path root match (e.g. binding path "Address.Name" should refresh
+				// when the root property "Address" itself changes — the sub-tree was swapped out).
+				var dotIndex = path.IndexOf('.', StringComparison.Ordinal);
+				if (dotIndex > 0 && string.CompareOrdinal(path, 0, e.PropertyName, 0, dotIndex) == 0
+					&& e.PropertyName.Length == dotIndex)
+				{
+					ResetItems();
+					return;
+				}
+
+				// Indexed-path root match (e.g. "Items[0].Name" — refresh if "Items" itself swaps).
+				var bracketIndex = path.IndexOf('[', StringComparison.Ordinal);
+				if (bracketIndex > 0 && string.CompareOrdinal(path, 0, e.PropertyName, 0, bracketIndex) == 0
+					&& e.PropertyName.Length == bracketIndex)
+				{
+					ResetItems();
+					return;
+				}
+			}
+			else
+			{
+				// MultiBinding or any other BindingBase: we cannot reliably introspect which
+				// property feeds the converter, so refresh on any item-level property change.
+				ResetItems();
+			}
+		}
+
 		void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
 		{
+			// Always rebuild from the current ItemsSource — this correctly handles Reset (where
+			// OldItems/NewItems are typically null) and avoids leaking subscriptions to items
+			// that have been removed.
+			RebuildItemSubscriptions();
+
 			switch (e.Action)
 			{
 				case NotifyCollectionChangedAction.Add:

@MauiBot MauiBot removed the s/agent-review-in-progress AI review is currently running for this PR label Jun 15, 2026

@kubaflo kubaflo left a comment

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.

Could you please check the ai's suggestions?

@kubaflo

kubaflo commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

/review rerun

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-controls-picker Picker community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration s/agent-fix-win AI found a better alternative fix than the PR 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)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Picker ItemDisplayBinding doesn't support MVVM properly

9 participants