Skip to content

Picker: Refresh ItemDisplayBinding when bound item properties change#29922

Open
devanathan-vaithiyanathan wants to merge 17 commits into
dotnet:inflight/currentfrom
devanathan-vaithiyanathan:fix-25634
Open

Picker: Refresh ItemDisplayBinding when bound item properties change#29922
devanathan-vaithiyanathan wants to merge 17 commits into
dotnet:inflight/currentfrom
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

@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 Mapper and Property Patterns — This unsubscribes item PropertyChanged handlers when the Picker's handler is removed, but there is no matching re-subscribe path when a handler is attached again. Concrete scenario: a Picker with ItemDisplayBinding is disconnected/reconnected during navigation or Shell tab switching; after reconnect, changing the selected item's display property no longer calls ResetItems(), so the displayed text goes stale. Either avoid tying these item subscriptions to handler lifetime, or re-subscribe in the attach path.


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] Logic and Correctness VerificationNotifyCollectionChangedAction.Reset commonly arrives with OldItems == null and NewItems == null, so this code leaves the old items subscribed and never subscribes the new contents after ResetItems(). Concrete scenario: an ObservableCollection is cleared/reloaded via Reset; removed items keep a reference to the Picker and new items no longer refresh the display when their bound property changes. Reset needs special handling, such as tracking subscribed items or rebuilding subscriptions around the reset.

}
void OnPickerItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (ItemDisplayBinding is Binding binding && !string.IsNullOrEmpty(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] XAML & Bindings — The refresh logic only recognizes runtime Binding and MultiBinding; compiled XAML ItemDisplayBinding is a TypedBindingBase, so item property changes are ignored for compiled bindings. Existing XAML tests show ItemDisplayBinding can compile to TypedBinding<,>, and that common path will still reproduce issue #25634. The fallback should refresh for other BindingBase implementations, or explicitly support typed bindings.

@MauiBot MauiBot added s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates and removed s/agent-fix-win AI found a better alternative fix than the PR labels Jun 21, 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 Confidence Low Platform iOS


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

Gate Result: ✅ PASSED

Platform: IOS · Base: main · Merge base: 4567a055

Test Without Fix (expect FAIL) With Fix (expect PASS)
🖥️ Issue25634 Issue25634 ✅ FAIL — 330s ✅ PASS — 115s
🔴 Without fix — 🖥️ Issue25634: FAIL ✅ · 330s
  Determining projects to restore...
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 729 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 730 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 5.01 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/Foldable/src/Controls.Foldable.csproj (in 5.17 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/Maps/src/Controls.Maps.csproj (in 5.97 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj (in 5.97 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/maps/src/Maps.csproj (in 5.98 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Xaml/Controls.Xaml.csproj (in 5.98 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 6 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 5.99 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/BlazorWebView/src/Maui/Microsoft.AspNetCore.Components.WebView.Maui.csproj (in 5.98 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.14443093
  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.14443093
  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.14443093
  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.14443093
  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.14443093
  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.14443093
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14443093
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14443093
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14443093
  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.Foldable -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Foldable.dll
  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
  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:00.34
  Determining projects to restore...
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 588 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 589 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/CustomAttributes/Controls.CustomAttributes.csproj (in 588 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 588 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Core/UITest.Core.csproj (in 1 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/VisualTestUtils/VisualTestUtils.csproj (in 1 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 634 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 654 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.NUnit/UITest.NUnit.csproj (in 1.06 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Appium/UITest.Appium.csproj (in 2.29 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/UITest.Analyzers/UITest.Analyzers.csproj (in 4.31 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/TestUtils/src/VisualTestUtils.MagickNet/VisualTestUtils.MagickNet.csproj (in 5.47 sec).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/tests/TestCases.iOS.Tests/Controls.TestCases.iOS.Tests.csproj (in 5.49 sec).
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14443093
  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.14443093
  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.14443093
  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.14443093
  Controls.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Core/Debug/net10.0/Microsoft.Maui.Controls.dll
  UITest.Core -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Core/Debug/net10.0/UITest.Core.dll
  VisualTestUtils -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils/Debug/netstandard2.0/VisualTestUtils.dll
  UITest.NUnit -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
  VisualTestUtils.MagickNet -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.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.18]   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/21/2026 1:45:09 PM FixtureSetup for Issue25634(iOS)
>>>>> 6/21/2026 1:45:14 PM VerifyPickerItemDisplayBindingValue Start
>>>>> 6/21/2026 1:45:17 PM VerifyPickerItemDisplayBindingValue Stop
>>>>> 6/21/2026 1:45:17 PM 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

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

🟢 With fix — 🖥️ Issue25634: PASS ✅ · 115s
  Determining projects to restore...
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 405 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 418 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 375 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 466 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 436 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.14443093
  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.14443093
  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.14443093
  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.14443093
  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.14443093
  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.14443093
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14443093
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14443093
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14443093
  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.Foldable -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/Controls.Foldable/Debug/net10.0-ios26.0/Microsoft.Maui.Controls.Foldable.dll
  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
  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:00:57.66
  Determining projects to restore...
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/BindingSourceGen/Controls.BindingSourceGen.csproj (in 354 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Graphics/src/Graphics/Graphics.csproj (in 423 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Essentials/src/Essentials.csproj (in 424 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Controls/src/Core/Controls.Core.csproj (in 435 ms).
  Restored /Users/cloudtest/vss/_work/1/s/src/Core/src/Core.csproj (in 405 ms).
  8 of 13 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.90-ci+azdo.14443093
  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.14443093
  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.14443093
  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.14443093
  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
  UITest.Appium -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Appium/Debug/net10.0/UITest.Appium.dll
  VisualTestUtils.MagickNet -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/VisualTestUtils.MagickNet/Debug/netstandard2.0/VisualTestUtils.MagickNet.dll
  UITest.NUnit -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.NUnit/Debug/net10.0/UITest.NUnit.dll
  UITest.Analyzers -> /Users/cloudtest/vss/_work/1/s/artifacts/bin/UITest.Analyzers/Debug/netstandard2.0/UITest.Analyzers.dll
  Controls.TestCases.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/21/2026 1:47:08 PM FixtureSetup for Issue25634(iOS)
>>>>> 6/21/2026 1:47:12 PM VerifyPickerItemDisplayBindingValue Start
>>>>> 6/21/2026 1:47:13 PM 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: 23.3328 Seconds
>>> TRX_RESULT_FILE: /Users/cloudtest/vss/_work/1/s/CustomAgentLogsTmp/UITests/TestResults/Issue25634.trx

📁 Fix files reverted (8 files)
  • 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

📋 Pre-Flight — Context & Validation

Issue: #25634 - Picker ItemDisplayBinding doesn't support MVVM properly
PR: #29922 - Fix Picker ItemDisplayBinding MVVM updates
Platforms Affected: All; test platform requested: iOS
Files Changed: 8 implementation/API, 7 test/snapshot

Key Findings

  • gh authentication is unavailable, so PR/issue/comments/CI context could not be queried; pre-flight used the local PR branch diff against origin/main.
  • The PR adds a UI regression for Issue25634 and changes Picker to refresh display text when ItemDisplayBinding source item properties change.
  • Gate result was supplied as already passed; gate artifacts were not modified.

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:427 Reset collection changes can leave stale item subscriptions when OldItems is null.
  • src/Controls/src/Core/Picker/Picker.cs:397 Handler disconnect unsubscribes item changes with no reconnect re-subscribe.
  • src/Controls/src/Core/Picker/Picker.cs:413 Compiled ItemDisplayBinding/TypedBindingBase changes are ignored by the PR's Binding/MultiBinding filter.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #29922 Strong per-item INotifyPropertyChanged subscriptions plus handler cleanup ✅ PASSED (Gate supplied) Picker.cs, PublicAPI, UI test/snapshots Original PR; expert review found lifecycle/reset/compiled-binding issues

🔬 Code Review — Deep Analysis

Code Review — PR #29922

Independent Assessment

What this changes: Picker now listens to INotifyPropertyChanged on ItemsSource items so ItemDisplayBinding display text refreshes when item properties change. It also adds UI screenshot coverage and PublicAPI entries for a new Picker.OnHandlerChanging override.
Inferred motivation: Fix stale Picker display text when MVVM item properties mutate after the items are loaded.

Reconciliation with PR Narrative

Author claims: Unavailable — gh authentication is unavailable.
Agreement/disagreement: Could only verify against local origin/main...HEAD diff.

Prior Review Reconciliation

Prior ❌ Error Finding Source Status Evidence
Could not query prior reviews/comments gh reviews / inline comments / issue comments ❓ Unknown gh requires authentication in this environment.

Blast Radius Assessment

  • Runs for all instances: No — only Pickers with ItemDisplayBinding and ItemsSource items implementing INotifyPropertyChanged.
  • Startup impact: No.
  • Static/shared state: No.

CI Status

  • Required-check result: undetermined / tool-unavailable
  • Classification: undetermined
  • Action taken: confidence capped low; no comments posted.

Findings

❌ Error — Reset collection changes leave stale item subscriptions

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

CollectionChanged only unsubscribes e.OldItems, but NotifyCollectionChangedAction.Reset commonly has OldItems == null (for example ObservableCollection<T>.Clear()). Existing items can remain subscribed to the Picker, retaining the page and causing stale ResetItems() calls after removal. Reset handling needs tracked subscribed items or another way to unsubscribe previous items.

❌ Error — Handler disconnect permanently disables item refresh after reconnect

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

When args.NewHandler == null, item subscriptions are removed, but no matching re-subscribe occurs when a handler is attached again. A Picker that survives navigation/handler recreation keeps the same ItemsSource and ItemDisplayBinding, but later item property changes no longer refresh display text.

❌ Error — Compiled ItemDisplayBinding is ignored on property changes

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

OnPickerItemPropertyChanged refreshes only for Binding and MultiBinding. XAML compiled bindings use TypedBinding<TSource,TProperty> (TypedBindingBase : BindingBase), so property changes for compiled ItemDisplayBinding do nothing. Existing tests show Picker can receive typed ItemDisplayBinding, so this fix misses a common XAML path.

Failure-Mode Probing

  • Collection reset/clear: old item subscriptions can remain because OldItems may be null.
  • Handler reconnect: subscriptions are removed on disconnect and not restored.
  • Compiled XAML binding: notification arrives, but no branch calls ResetItems().
  • Null/default values: null ItemsSource is guarded.

Verdict: NEEDS_CHANGES

Confidence: low
Summary: The main approach is directionally useful, but lifecycle, reset, and compiled-binding gaps leave concrete correctness and leak issues. CI and PR narrative/comments could not be verified due unavailable gh auth.


🛠️ Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix-1 Binding display proxies using cloned bindings ❌ Failed expert review; UI test passed Picker.cs, PublicAPI Changed binding target semantics and clone behavior
2 try-fix-2 Selected-item weak observer ❌ Failed expert review; UI test passed Picker.cs, PublicAPI Missed no-selection and non-selected item changes
3 try-fix-3 Weak all-items display invalidation through existing GetDisplayMember() ✅ Passed Picker.cs, PublicAPI Expert accepted; handles reset, reconnect, compiled bindings, and all current items
PR PR #29922 Strong per-item INotifyPropertyChanged subscriptions with handler cleanup ✅ PASSED (Gate supplied) Picker.cs, PublicAPI, UI test/snapshots Original PR; expert review found reset/lifecycle/compiled-binding concerns

Cross-Pollination

Model Round New Ideas? Details
maui-expert-reviewer 1 Yes Binding display proxies; failed expert review due target semantics and clone metadata
maui-expert-reviewer 2 Yes Selected-item weak observer; failed expert review due no-selection/non-selected gaps
maui-expert-reviewer 3 Yes Weak all-items display invalidation; passed test and expert review

Exhausted: No — stopped because candidate #3 passed all tests and was demonstrably better than the PR fix.
Selected Fix: Candidate #3 — weak all-items display invalidation preserves existing binding semantics while avoiding the PR's strong subscription, reset, handler reconnect, and compiled-binding issues.


📝 Recommended PR Title & Description

Assessment: ✏️ Recommend updating — the current metadata accurately describes the submitted PR, but the winning fix changes the implementation from strong per-item subscriptions/handler cleanup to weak all-item display invalidation and removes the new public override.

Recommended title

Picker: Refresh ItemDisplayBinding when item display properties change

Recommended description

### Issue Details
Picker does not refresh the displayed item text when an item property used by ItemDisplayBinding changes.

### Description of Change

Added support to automatically refresh Picker display text when a bound item's display property changes. The fix observes current ItemsSource items through weak property-change observers and refreshes through the existing ItemDisplayBinding display pipeline, so runtime bindings, compiled bindings, converters, fallback values, and existing Picker binding target semantics continue to work.

Observer subscriptions are rebuilt when ItemDisplayBinding, ItemsSource, or collection contents change, including collection reset/reload scenarios. The implementation avoids tying item observation to handler disconnect/reconnect and does not add a new Picker public API override.

### Issues Fixed

Fixes #25634

**Tested the behavior in the following platforms.**
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

| Before  | After  |
|---------|--------|
| **iOS**<br> <video src="https://github.com/user-attachments/assets/289d7a41-163b-4987-a99e-9ebd392abd3b" width="300" height="600"> |**iOS**<br> <video src="https://github.com/user-attachments/assets/c200ee33-c4f6-4374-afea-6ce4e067389a" width="300" height="600"> |

🏁 Report — Final Recommendation

Comparative Fix Report — PR #29922

Ranking

Rank Candidate Regression result Expert result Assessment
1 pr-plus-reviewer ✅ Pass (inherits try-fix-3 behavior) ✅ No remaining findings Best candidate. Applies the expert feedback to the PR by using weak all-items display invalidation while preserving existing GetDisplayMember() binding semantics.
2 try-fix-3 ✅ Pass ✅ No remaining findings Equivalent technical approach to pr-plus-reviewer; ranked lower only because the requested PR-forward candidate captures the same fix as reviewer feedback applied to the PR.
3 pr ✅ Pass ❌ 3 major findings Handles the narrow runtime binding regression, but has handler reconnect, collection reset, and compiled-binding correctness gaps.
4 try-fix-2 ✅ Pass ❌ Failed expert review Preserves binding semantics but observes only the selected item, missing no-selection and non-selected item display updates.
5 try-fix-1 ❌ Fail ❌ Failed expert review Failed candidate ranking rules and also changed binding target/clone semantics in ways that can regress RelativeSource, TemplateBinding, and compiled-binding metadata.

Candidate Analysis

pr

The submitted PR adds strong INotifyPropertyChanged subscriptions for ItemsSource items and refreshes Picker display text when the runtime Binding.Path changes. The supplied gate passed, so it covers the reported simple iOS scenario. However, expert review found major issues: subscriptions are removed on handler disconnect without reconnect recovery, Reset collection changes can leave stale subscriptions and miss new items, and compiled XAML TypedBindingBase item-display bindings are ignored.

pr-plus-reviewer

This sandbox candidate applies the expert feedback by replacing the PR's strong subscriptions with weak all-item observers rebuilt from the current ItemsSource. It avoids handler-lifetime coupling, handles reset/reload by rebuilding observers, deduplicates repeated item references, and refreshes via ResetItems()/GetDisplayMember() so all existing BindingBase implementations continue to flow through the established Picker display pipeline. This is the best PR-forward solution.

try-fix-1

The proxy-binding approach passed the narrow UI test but failed expert review and is marked Fail. It changes binding target semantics by applying ItemDisplayBinding to a plain BindableObject proxy instead of the Picker element, and cloning BindingBase risks losing compiled-binding fallback/target-null metadata. Because failed candidates must rank below passing candidates, this cannot win.

try-fix-2

The selected-item weak observer passed the targeted UI regression but failed expert review. It refreshes only when the selected item changes, so picker popup rows and no-selection scenarios can remain stale. It is safer than try-fix-1 but incomplete compared with the all-items observer.

try-fix-3

The weak all-items display invalidation candidate passed the targeted iOS UI regression and expert review. It resolves the PR's lifecycle, reset, and compiled-binding issues while preserving the existing display binding application path. It is technically equivalent to the pr-plus-reviewer sandbox candidate.

Winner

Winner: pr-plus-reviewer

pr-plus-reviewer wins because it keeps the PR's intended behavior and test coverage while applying the expert-reviewed all-items weak observer fix. It ranks above the raw PR due to the three unresolved major findings in the submitted implementation, and above the standalone try-fix-3 because the requested PR-forward candidate incorporates the same accepted approach as reviewer feedback applied to the PR.


🧭 Next Steps — review latest findings

No alternative fix was selected for this run. Review the session findings and CI results before merging.

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

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

Tests Failure Analysis

@devanathan-vaithiyanathan — test-failure review results are available based on commit 41bf371.
To request a fresh review after new comments, commits, or CI runs, comment /review tests.

Overall Likely unrelated Failures 22 Platform Android Platform macOS Platform Windows

Test Failure Review: Likely unrelated - click to expand

Overall verdict: Likely unrelated

All 5 recent base-branch (main) builds for both maui-pr-uitests and maui-pr-devicetests are failing, and the 22 distinct failures span WebView, Shell, SafeArea, CollectionView, and visual-baseline areas that are entirely outside this PR's scope (area-controls-picker / Picker ItemDisplayBinding). The sole Picker-area failure (PickerDialogDoesNotCrashWhenPagePoppedWhileDialogOpen) tests a different scenario (dialog-crash-on-pop) and presents as a consistent Appium timeout across both retries, matching the base-branch instability pattern.

Failure Verdict Evidence
macOS UITests WebView (14 tests: WebViewNoCrashPopup, WebViewDoesntCrashWhenLoadingAHeavyPageAndUsingExecutionModeSeparateProcess, WebView_SetHtmlSource_VerifyNavigatingEvent, and 11 more) Likely unrelated WebView completely outside PR scope (area-controls-picker); all tests timed out or app became force-terminated (unresponsive); maui-pr-uitests failing on 5 consecutive main builds (1465238, 1459939)
ShellColorsResetOnNavigation / ShellPages_FlowDirectionRTL (WinUI UITests Controls Shell) Likely unrelated Shell tests unrelated to Picker; ShellPages_FlowDirectionRTL is a visual-baseline failure (VisualTestFailedException); base branch also failing
SafeAreaBorderBasicFunctionality / SafeAreaContentViewBasicFunctionality / ToolbarExtendsAllTheWayLeftAndRight_FlyoutPage (Android CoreClr SafeAreaEdges,Shadow) Likely unrelated SafeArea and Shadow tests unrelated to Picker; all failing on fixture-setup timeouts (OneTimeSetUp exception); base branch also failing
PickerDialogDoesNotCrashWhenPagePoppedWhileDialogOpen (macOS UITests Controls Page,Performance,Picker,ProgressBar) Likely unrelated Same area as PR (Picker) but tests dialog-crash-on-pop behavior, not ItemDisplayBinding refresh; Appium element-not-found timeout on both retries; consistent with pre-existing CI instability
LayoutShouldBeCorrectOnFirstNavigation (macOS UITests Controls ListView) Likely unrelated Visual-baseline failure (VisualTestFailedException); unrelated to Picker
MemoryLeakB42329 (macOS UITests Controls ListView) Likely unrelated CollectionView/ListView memory-leak test; unrelated to Picker ItemDisplayBinding
maui-pr-devicetests Windows Helix (net10.0 Windows Helix Tests Run DeviceTests Windows) Insufficient data Helix work-item data returned 404 (expired or inaccessible); device-test hidden failures cannot be verified; 5 consecutive base-branch builds also failed on main (1465240)

Recommended action

Rerun the failing UI test jobs. The pattern is consistent with pre-existing CI instability on main (5 consecutive base-branch failures on both maui-pr-uitests and maui-pr-devicetests), and no failure directly references the Picker ItemDisplayBinding code changed by this PR.

Evidence details

Checked pipelines:

  • maui-pr-devicetests build 1474419: 4 failed timeline records; Helix job 79e7c60f-370e-4e67-b565-d90a4a7a6c48 returned 404.
  • maui-pr-uitests build 1474418: 30 failed timeline records, 37 raw log failures, deduplicated to 22 distinct test failures.

Base-branch failures confirming pre-existing instability:

PR scope: 15 changed files, 7 test files, all in Picker / ItemDisplayBinding. No WebView, Shell, SafeArea, or CollectionView files changed.

Limitations: AzDO authenticated test-run APIs (_apis/test/...) were skipped (no AZDO_TOKEN available); Helix aggregate data is unavailable (404). Conclusions are based on public build timelines and extracted log text only.

@kubaflo kubaflo changed the base branch from main to inflight/current June 22, 2026 13:54

@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 resolve conflicts?

@devanathan-vaithiyanathan

Copy link
Copy Markdown
Contributor Author

Could you please resolve conflicts?

@kubaflo , I have resolved the conflicts

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-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Picker ItemDisplayBinding doesn't support MVVM properly

9 participants