Skip to content

[C] Fix binding to interface-inherited properties like IReadOnlyList<T>.Count#32912

Merged
rmarinho merged 2 commits intoinflight/currentfrom
fix/13872-binding-interface-inherited-properties
Dec 5, 2025
Merged

[C] Fix binding to interface-inherited properties like IReadOnlyList<T>.Count#32912
rmarinho merged 2 commits intoinflight/currentfrom
fix/13872-binding-interface-inherited-properties

Conversation

@StephaneDelcroix
Copy link
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!

Description

Fixes #13872

Runtime bindings were not resolving properties inherited from parent interfaces. For example, IReadOnlyList<T>.Count would return null because Count is defined on IReadOnlyCollection<T>, not directly on IReadOnlyList<T>.

Changes

  • Added GetProperty() method in BindingExpression.cs that searches both base classes and implemented interfaces recursively (similar to how GetIndexer() already handles this case)
  • Updated SetupPart() to use the new GetProperty() method
  • Added unit test Maui13872 that verifies bindings to IReadOnlyList<T>.Count work correctly with all XAML inflators (Runtime, XamlC, SourceGen)

Test Results

All 1790 XAML unit tests pass:

  • Passed: 1764
  • Skipped: 26
  • Failed: 0

…ount

Fixes #13872

The runtime binding expression was not resolving properties inherited from parent interfaces. For example, IReadOnlyList<T>.Count would return null because Count is defined on IReadOnlyCollection<T>, not directly on IReadOnlyList<T>.

Added GetProperty() method that searches both base classes and implemented interfaces recursively, similar to how GetIndexer() already handles this case.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a bug where runtime bindings failed to resolve properties inherited from parent interfaces. For example, IReadOnlyList<T>.Count would return null because the Count property is defined on IReadOnlyCollection<T>, not directly on IReadOnlyList<T>.

Key changes:

  • Added recursive interface search capability to property resolution in runtime bindings
  • Refactored property lookup logic into a dedicated GetProperty() method that mirrors the existing GetIndexer() pattern
  • Added comprehensive test coverage for the fix across all XAML inflators

Reviewed changes

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

File Description
src/Controls/src/Core/BindingExpression.cs Adds GetProperty() method with recursive interface search and refactors SetupPart() to use it instead of inline property lookup
src/Controls/tests/Xaml.UnitTests/Issues/Maui13872.xaml XAML test file demonstrating both compiled and uncompiled bindings to IReadOnlyList<T>.Count
src/Controls/tests/Xaml.UnitTests/Issues/Maui13872.xaml.cs Test code-behind with view model and test assertions validating the fix works with all inflators

@StephaneDelcroix StephaneDelcroix added this to the .NET 10.0 SR3 milestone Nov 29, 2025
@StephaneDelcroix StephaneDelcroix changed the title Fix binding to interface-inherited properties like IReadOnlyList<T>.Count [C] Fix binding to interface-inherited properties like IReadOnlyList<T>.Count Nov 29, 2025
@rmarinho rmarinho changed the base branch from main to inflight/current December 5, 2025 14:10
@rmarinho rmarinho merged commit 793fc12 into inflight/current Dec 5, 2025
62 checks passed
@rmarinho rmarinho deleted the fix/13872-binding-interface-inherited-properties branch December 5, 2025 14:10
github-actions bot pushed a commit that referenced this pull request Dec 5, 2025
…T>.Count (#32912)

* Fix binding to interface-inherited properties like IReadOnlyList<T>.Count

Fixes #13872

The runtime binding expression was not resolving properties inherited from parent interfaces. For example, IReadOnlyList<T>.Count would return null because Count is defined on IReadOnlyCollection<T>, not directly on IReadOnlyList<T>.

Added GetProperty() method that searches both base classes and implemented interfaces recursively, similar to how GetIndexer() already handles this case.

* Fix Maui32879Tests expected output after pragma warning merge
PureWeen pushed a commit that referenced this pull request Dec 8, 2025
…T>.Count (#32912)

* Fix binding to interface-inherited properties like IReadOnlyList<T>.Count

Fixes #13872

The runtime binding expression was not resolving properties inherited from parent interfaces. For example, IReadOnlyList<T>.Count would return null because Count is defined on IReadOnlyCollection<T>, not directly on IReadOnlyList<T>.

Added GetProperty() method that searches both base classes and implemented interfaces recursively, similar to how GetIndexer() already handles this case.

* Fix Maui32879Tests expected output after pragma warning merge
PureWeen pushed a commit that referenced this pull request Dec 10, 2025
…T>.Count (#32912)

* Fix binding to interface-inherited properties like IReadOnlyList<T>.Count

Fixes #13872

The runtime binding expression was not resolving properties inherited from parent interfaces. For example, IReadOnlyList<T>.Count would return null because Count is defined on IReadOnlyCollection<T>, not directly on IReadOnlyList<T>.

Added GetProperty() method that searches both base classes and implemented interfaces recursively, similar to how GetIndexer() already handles this case.

* Fix Maui32879Tests expected output after pragma warning merge
PureWeen pushed a commit that referenced this pull request Dec 16, 2025
…T>.Count (#32912)

* Fix binding to interface-inherited properties like IReadOnlyList<T>.Count

Fixes #13872

The runtime binding expression was not resolving properties inherited from parent interfaces. For example, IReadOnlyList<T>.Count would return null because Count is defined on IReadOnlyCollection<T>, not directly on IReadOnlyList<T>.

Added GetProperty() method that searches both base classes and implemented interfaces recursively, similar to how GetIndexer() already handles this case.

* Fix Maui32879Tests expected output after pragma warning merge
github-actions bot pushed a commit that referenced this pull request Dec 22, 2025
…T>.Count (#32912)

* Fix binding to interface-inherited properties like IReadOnlyList<T>.Count

Fixes #13872

The runtime binding expression was not resolving properties inherited from parent interfaces. For example, IReadOnlyList<T>.Count would return null because Count is defined on IReadOnlyCollection<T>, not directly on IReadOnlyList<T>.

Added GetProperty() method that searches both base classes and implemented interfaces recursively, similar to how GetIndexer() already handles this case.

* Fix Maui32879Tests expected output after pragma warning merge
PureWeen pushed a commit that referenced this pull request Dec 22, 2025
…T>.Count (#32912)

* Fix binding to interface-inherited properties like IReadOnlyList<T>.Count

Fixes #13872

The runtime binding expression was not resolving properties inherited from parent interfaces. For example, IReadOnlyList<T>.Count would return null because Count is defined on IReadOnlyCollection<T>, not directly on IReadOnlyList<T>.

Added GetProperty() method that searches both base classes and implemented interfaces recursively, similar to how GetIndexer() already handles this case.

* Fix Maui32879Tests expected output after pragma warning merge
github-actions bot pushed a commit that referenced this pull request Dec 24, 2025
…T>.Count (#32912)

* Fix binding to interface-inherited properties like IReadOnlyList<T>.Count

Fixes #13872

The runtime binding expression was not resolving properties inherited from parent interfaces. For example, IReadOnlyList<T>.Count would return null because Count is defined on IReadOnlyCollection<T>, not directly on IReadOnlyList<T>.

Added GetProperty() method that searches both base classes and implemented interfaces recursively, similar to how GetIndexer() already handles this case.

* Fix Maui32879Tests expected output after pragma warning merge
PureWeen pushed a commit that referenced this pull request Dec 26, 2025
…T>.Count (#32912)

* Fix binding to interface-inherited properties like IReadOnlyList<T>.Count

Fixes #13872

The runtime binding expression was not resolving properties inherited from parent interfaces. For example, IReadOnlyList<T>.Count would return null because Count is defined on IReadOnlyCollection<T>, not directly on IReadOnlyList<T>.

Added GetProperty() method that searches both base classes and implemented interfaces recursively, similar to how GetIndexer() already handles this case.

* Fix Maui32879Tests expected output after pragma warning merge
github-actions bot pushed a commit that referenced this pull request Dec 27, 2025
…T>.Count (#32912)

* Fix binding to interface-inherited properties like IReadOnlyList<T>.Count

Fixes #13872

The runtime binding expression was not resolving properties inherited from parent interfaces. For example, IReadOnlyList<T>.Count would return null because Count is defined on IReadOnlyCollection<T>, not directly on IReadOnlyList<T>.

Added GetProperty() method that searches both base classes and implemented interfaces recursively, similar to how GetIndexer() already handles this case.

* Fix Maui32879Tests expected output after pragma warning merge
PureWeen added a commit that referenced this pull request Dec 29, 2025
## CollectionView
- Fixed the NRE in CarouselViewController on iOS 15.5 & 16.4 by
@Ahamed-Ali in #30838
  <details>
  <summary>🔧 Fixes</summary>

- [NRE in CarouselViewController on iOS 15.5 &
16.4](#28557)
  </details>

- [iOS, macOS] Fixed CollectionView group header size changes with
ItemSizingStrategy by @NanthiniMahalingam in
#33161
  <details>
  <summary>🔧 Fixes</summary>

- [[NET 10] I6_Grouping - Grouping_with_variable_sized_items changing
the 'ItemSizingStrategy' also changes the header
size.](#33130)
  </details>

## Flyout
- Add unit tests for TabBar and FlyoutItem navigation
ApplyQueryAttributes (#25663) by @StephaneDelcroix in
#33006

## Flyoutpage
- Fixed the FlyoutPage.Flyout Disappearing When Maximizing the Window on
Mac Platform by @NanthiniMahalingam in
#26701
  <details>
  <summary>🔧 Fixes</summary>

- [FlyoutPage.Flyout - navigation corrupted when running om mac , on
window ok](#22719)
  </details>

## Mediapicker
- [Windows] Fix for PickPhotosAsync throws exception if image is
modified by @HarishwaranVijayakumar in
#32952
  <details>
  <summary>🔧 Fixes</summary>

- [PickPhotosAsync throws exception if image is
modified.](#32408)
  </details>

## Navigation
- Fix for TabBar Navigation does not invoke its
IQueryAttributable.ApplyQueryAttributes(query) by @SuthiYuvaraj in
#25663
  <details>
  <summary>🔧 Fixes</summary>

- [Tabs defined in AppShell.xaml does not invoke its view model's
IQueryAttributable.ApplyQueryAttributes(query)
implementaion](#13537)
- [`ShellContent` routes do not call
`ApplyQueryAttributes`](#28453)
  </details>

## ScrollView
- Fix ScrollToPosition.Center behavior in ScrollView on iOS and
MacCatalyst by @devanathan-vaithiyanathan in
#26825
  <details>
  <summary>🔧 Fixes</summary>

- [ScrollToPosition.Center Centers the First Item too in iOS and
Catalyst](#26760)
- [On iOS - ScrollView.ScrollToAsync Element,
ScrollToPosition.MakeVisible shifts view to the right, instead of just
scrolling vertically](#28965)
  </details>

## Searchbar
- [iOS, Mac, Windows] Fixed CharacterSpacing for SearchBar text and
placeholder text by @Dhivya-SF4094 in
#30407
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS, Mac, Windows] SearchBar CharacterSpacing property is not
working as expected](#30366)
  </details>

## Shell
- Update logic for large title display mode on iOS - shell by @kubaflo
in #33039

## TitleView
- [iOS] Fixed memory leak with PopToRootAsync when using TitleView by
@Vignesh-SF3580 in #28547
  <details>
  <summary>🔧 Fixes</summary>

- [NavigationPage.TitleView causes memory leak with
PopToRootAsync](#28201)
  </details>

## Xaml
- [C] Fix binding to interface-inherited properties like
IReadOnlyList<T>.Count by @StephaneDelcroix in
#32912
  <details>
  <summary>🔧 Fixes</summary>

- [Compiled Binding to Array.Count provides no
result](#13872)
  </details>

- Fix #31939: CommandParameter TemplateBinding lost during reparenting
by @StephaneDelcroix in #32961
  <details>
  <summary>🔧 Fixes</summary>

- [CommandParameter TemplateBinding Lost During ControlTemplate
Reparenting](#31939)
  </details>


<details>
<summary>🧪 Testing (4)</summary>

- [Testing] Fixed Test case failure in PR 33185 - [12/22/2025] Candidate
by @TamilarasanSF4853 in #33257
- [Testing] Re-saved ShouldFlyoutBeVisibleAfterMaximizingWindow test
case images in PR 33185 - [12/22/2025] Candidate by @TamilarasanSF4853
in #33271
- [Testing] Fixed Test case failure in PR 33185 - [12/22/2025] Candidate
- 2 by @TamilarasanSF4853 in #33299
- [Testing] Fixed Test case failure in PR 33185 - [12/22/2025] Candidate
- 3 by @TamilarasanSF4853 in #33311

</details>

<details>
<summary>📦 Other (2)</summary>

- [XSG][BindingSourceGen] Add support for RelayCommand to compiled
bindings by @simonrozsival via @Copilot in
#32954
  <details>
  <summary>🔧 Fixes</summary>

  - [Issue #25818](#25818)
  </details>
- Revert "Update logic for large title display mode on iOS - shell
(#33039)" in cff7f35

</details>
**Full Changelog**:
main...inflight/candidate
@github-actions github-actions bot locked and limited conversation to collaborators Jan 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compiled Binding to Array.Count provides no result

4 participants