Skip to content

[automated] Merge branch 'main' => 'net11.0'#34618

Merged
PureWeen merged 72 commits intonet11.0from
merge/main-to-net11.0
Mar 24, 2026
Merged

[automated] Merge branch 'main' => 'net11.0'#34618
PureWeen merged 72 commits intonet11.0from
merge/main-to-net11.0

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

I detected changes in the main branch which have not been merged yet to net11.0. I'm a robot and am configured to help you automatically keep net11.0 up to date, so I've opened this PR.

This PR merges commits made on main by the following committers:

  • PureWeen
  • kubaflo
  • sheiksyedm
  • lewing
  • jfversluis

Instructions for merging from UI

This PR will not be auto-merged. When pull request checks pass, complete this PR by creating a merge commit, not a squash or rebase commit.

merge button instructions

If this repo does not allow creating merge commits from the GitHub UI, use command line instructions.

Instructions for merging via command line

Run these commands to merge this pull request from the command line.

git fetch
git checkout main
git pull --ff-only
git checkout net11.0
git pull --ff-only
git merge --no-ff main

# If there are merge conflicts, resolve them and then run git merge --continue to complete the merge
# Pushing the changes to the PR branch will re-trigger PR validation.
git push https://github.com/dotnet/maui HEAD:merge/main-to-net11.0
or if you are using SSH
git push git@github.com:dotnet/maui HEAD:merge/main-to-net11.0

After PR checks are complete push the branch

git push

Instructions for resolving conflicts

⚠️ If there are merge conflicts, you will need to resolve them manually before merging. You can do this using GitHub or using the command line.

Instructions for updating this pull request

Contributors to this repo have permission update this pull request by pushing to the branch 'merge/main-to-net11.0'. This can be done to resolve conflicts or make other changes to this pull request before it is merged.
The provided examples assume that the remote is named 'origin'. If you have a different remote name, please replace 'origin' with the name of your remote.

git fetch
git checkout -b merge/main-to-net11.0 origin/net11.0
git pull https://github.com/dotnet/maui merge/main-to-net11.0
(make changes)
git commit -m "Updated PR with my changes"
git push https://github.com/dotnet/maui HEAD:merge/main-to-net11.0
or if you are using SSH
git fetch
git checkout -b merge/main-to-net11.0 origin/net11.0
git pull git@github.com:dotnet/maui merge/main-to-net11.0
(make changes)
git commit -m "Updated PR with my changes"
git push git@github.com:dotnet/maui HEAD:merge/main-to-net11.0

Contact .NET Core Engineering (dotnet/dnceng) if you have questions or issues.
Also, if this PR was generated incorrectly, help us fix it. See https://github.com/dotnet/arcade/blob/main/.github/workflows/scripts/inter-branch-merge.ps1.

jfversluis and others added 30 commits March 20, 2026 09:54
## Description

Remove the "Are you waiting for the changes in this PR to be merged?"
note from all Copilot instruction files.

This note was previously required at the top of every PR description so
users could find instructions on how to test PR artifacts. We now have a
**dogfooding comment bot** that automatically posts testing instructions
under each PR, making this manual note redundant.

Copilot agents were still prepending this note to every PR description
because it was hardcoded in:
- `.github/copilot-instructions.md` (main instructions)
- `.github/skills/pr-finalize/SKILL.md` (PR finalization skill)
- `.github/skills/pr-finalize/references/complete-example.md` (example
PR)

### Issues Fixed

N/A — instruction cleanup only.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Problem

The `maui-pr-uitests` pipeline has 98+ test jobs that all publish
artifacts using `PublishBuildArtifacts@1` with **no artifact name**,
defaulting to `drop`. When multiple jobs upload the same file to the
same container simultaneously, AzDO blob storage encounters write
conflicts:

```
Blob is incomplete (missing block). Blob: 29adda685a1ff1119a49000d3a9183a5, Expected Offset: 0, Actual Offset: 8388608
##[error]File upload failed even after retry.
```

### Recent failures
- [Build
1334980](https://dev.azure.com/dnceng-public/public/_build/results?buildId=1334980):
3 jobs failed (Controls CollectionView, Controls (vlatest), Controls
(vlatest) CollectionView)
- [Build
1334245](https://dev.azure.com/dnceng-public/public/_build/results?buildId=1334245):
1 job failed (Controls (vlatest))

The specific collision: both "Controls (vlatest)" and "Controls
(vlatest) CollectionView" upload
`drop/logs/appium_ios_Controls.TestCases.iOS.Tests-Release-ios-CollectionView.log`
— same blob ID, concurrent writes.

## Fix

Add a unique artifact name per job using
`$(System.StageName)-$(System.JobName)-$(System.JobAttempt)` in
`eng/pipelines/common/ui-tests-steps.yml`. This matches the pattern
already used by snapshot diff artifacts in
`ui-tests-collect-snapshot-diffs.yml`.

Fixes #34477
Ref: dotnet/dnceng#1916

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ertPageBefore (#29924)

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

### Issue Detail
When using the InsertPageBefore method to change the root page in a
NavigationPage, the back button is not visible, but the flyout icon
remains visible.
 

### Root Cause
The flyout icon was not updated when changing the root page using
InsertPageBefore.
 

### Description of Change
The updated logic checks whether the inserted page becomes the new root,
updates the flyout icon. Previously, the flyout icon was updated based
on NavPageController.Pages. However, this collection was not updated
with the actual native navigation stack. Since pages are inserted
directly into ViewControllers in InsertPageBefore, the fix updates the
flyout icon based on the ViewControllers stack instead.

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

### Issues Fixed
 
Fixes #29921

### Screenshots

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video width="300" height="600"
src="https://github.com/user-attachments/assets/20acfd44-79af-45c7-ad9d-c55f2e825b49">
| <video width="300" height="600"
src="https://github.com/user-attachments/assets/fc99cc8b-8ed2-424f-876c-bd703e10872f">)
|
…is set to null (#30420)

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


### Root Cause

CollectionView.SelectItem was being called inside the
`PerformBatchUpdates` completion handler, which is triggered after all
other actions are completed. As a result, when `SelectedItem` is set to
null in the `SelectionChanged` event handler, the deferred selection
inside `PerformBatchUpdates` would fire afterward and re-select the
item, making the null assignment ineffective.

The original implementation (from PR #25555) always wrapped `SelectItem`
calls in `PerformBatchUpdates` to ensure selection happened after
collection view items generation was completed. This worked for initial
load scenarios but caused a timing issue for runtime selection changes.

### Description of Change

The fix introduces conditional logic based on the view's loaded state
using `CollectionView.IsLoaded()` (which checks if `UIView.Window !=
null`):

**For initial load (!IsLoaded()):**
- Selection still uses `PerformBatchUpdates` to defer until items are
generated
- This preserves the original intent from PR #25555

**For runtime changes (IsLoaded()):**
- Selection executes immediately without `PerformBatchUpdates` wrapper
- Includes all existing safety checks: EmptySource verification,
reference equality, index recalculation, and item equality validation
- Allows user code (like `SelectedItem = null`) to take effect
immediately without being overridden by deferred selection

This resolves the issue where the selected item was not being cleared
when `SelectedItem` is set to null during runtime.

### Key Technical Details

**IsLoaded() Extension Method:**
- Definition: `UIView.Window != null`
- Indicates whether the view is attached to the window hierarchy
- Used to distinguish between initial load (preselection) vs. runtime
selection changes

**Lifecycle Distinction:**
- **Initial load**: View isn't attached, items still being laid out →
defer selection
- **Runtime**: View is active, items stable → select immediately to
avoid race conditions

**Why Immediate Selection Works:**
Direct `SelectItem` calls execute synchronously in the current call
stack, before any completion handlers fire. This prevents the race
condition where user code sets `SelectedItem = null`, but the deferred
`PerformBatchUpdates` completion handler re-selects the item afterward.

### Files Changed

1.
`src/Controls/src/Core/Handlers/Items/iOS/SelectableItemsViewController.cs`
- Added IsLoaded() check (deprecated handler)
2.
`src/Controls/src/Core/Handlers/Items2/iOS/SelectableItemsViewController2.cs`
- Added IsLoaded() check (current handler)
3. `src/Controls/tests/TestCases.HostApp/Issues/Issue30363.cs` - New UI
test demonstrating the fix
4. `src/Controls/tests/TestCases.HostApp/Issues/Issue26187.cs` - Updated
existing test
5.
`src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue30363.cs` -
Appium test with screenshot verification
6. Snapshots for iOS and Android

### What NOT to Do (for future agents)

- ❌ **Don't always use PerformBatchUpdates for selection** - This causes
deferred execution that can override user code
- ❌ **Don't remove PerformBatchUpdates entirely** - Initial load
scenarios still need it for proper item generation timing
- ❌ **Don't ignore the view's loaded state** - The lifecycle context
(initial vs. runtime) is critical for correct timing

### Edge Cases

| Scenario | Risk | Mitigation |
|----------|------|------------|
| EmptySource disposal | Medium | Runtime path checks `ItemsSource is
EmptySource` before selection |
| ItemsSource changes during selection | Medium | Runtime path verifies
`ReferenceEquals(ItemsView.ItemsSource, originalSource)` |
| Collection mutations (add/delete) | Medium | Runtime path recalculates
index and verifies item equality at updated position |
| Initial preselection timing | Low | Preserved PerformBatchUpdates for
!IsLoaded() case |

### Issues Fixed

Fixes #30363
Fixes #26187

### Regression PR

This fix addresses a regression introduced in PR #25555, which added
`PerformBatchUpdates` to ensure selection timing but didn't account for
runtime selection clearing scenarios.

### Platforms Tested

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

### Screenshots

**Issue #30363:**

| Before Fix | After Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/09891481-5e3a-476d-a058-b6f828335a63">
| <video
src="https://github.com/user-attachments/assets/6bad46a2-acbf-498a-a45c-e08c84f4a32a">
|

**Issue #26187:**

| Before Fix | After Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/95245bc1-5772-4cc1-9947-c371a4c35586">
| <video
src="https://github.com/user-attachments/assets/1474b60e-d552-4a05-9461-fb513e3ef5b0">
|
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

### Description of Change
This pull request introduces support for a Material Design 3 styled
`ActivityIndicator` on Android, allowing the app to use the new Material
component when the Material3 feature is enabled. The main changes
involve conditional registration of a new handler, the implementation of
a `MaterialActivityIndicatorHandler`, and the addition of a custom
`MaterialActivityIndicator` control for Android.

**Material3 ActivityIndicator support for Android:**

* Added a new `MaterialActivityIndicatorHandler` class that extends
`ActivityIndicatorHandler` and creates a `MaterialActivityIndicator`
(the new Material3 control) as its platform view. It also customizes
layout behavior to ensure proper sizing and centering.
* Implemented the `MaterialActivityIndicator` control in
`MaterialActivityIndicator.cs`, inheriting from
`CircularProgressIndicator` and overriding measurement logic to ensure
the indicator remains square and properly sized according to Material
guidelines.

**Handler registration logic:**

* Updated the `AddControlsHandlers` extension method to conditionally
register either `MaterialActivityIndicatorHandler` or the classic
`ActivityIndicatorHandler` for `ActivityIndicator`, based on whether
Material3 is enabled on Android.

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #33479 

**Material3 Spec**
[ActivityIndicator](https://m3.material.io/components/progress-indicators/specs)
### Output Screenshot
| Material 2  | Material 3 |
|---------|--------|
| <video height=600 width=300
src="https://github.com/user-attachments/assets/23d67157-b19f-4b5d-b21d-4e50c45f288f">
|  <video height=600 width=300
src="https://github.com/user-attachments/assets/6a5de984-6407-4a5c-b60b-09e9fc16342a"> 
|
…#33246)

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

## Background and Context

This PR addresses issue #33037 where iOS large titles in Shell don't
transition properly when scrolling. This is the third attempt to fix the
issue:

1. **PR #33039** (merged Dec 8, 2025): Changed the condition from
`PrefersLargeTitles = largeTitleDisplayMode == Always` to
`PrefersLargeTitles = largeTitleDisplayMode != Never`
2. **PR #33230** (merged Dec 19, 2025): Reverted #33039 because it
caused "a lot of failing tests" - large titles started appearing
unintentionally in many scenarios, breaking UI test snapshots
3. **PR #33246** (this PR): Re-attempts the fix with an important
addition: opt-in check

## Root Cause

Shell doesn't have a `PrefersLargeTitles` property at the Shell level.
The previous implementation would update large title preferences
whenever any page was displayed, regardless of whether the developer
explicitly requested large title behavior.

**Problem with PR #33039:** Changing the condition to
`largeTitleDisplayMode != Never` meant that:
- `LargeTitleDisplayMode.Always` → PrefersLargeTitles = true ✅
- `LargeTitleDisplayMode.Automatic` → PrefersLargeTitles = true ⚠️
(unintended for pages that didn't set the property)
- `LargeTitleDisplayMode.Never` → PrefersLargeTitles = false ✅

Since the default value is `Automatic`, pages that never set
`LargeTitleDisplay` would suddenly get large titles, breaking many UI
tests.

## Description of Change

This PR implements an **opt-in model** for large title display in Shell:

### 1. Added Opt-In Check
Before updating large title preferences, the code now checks if the
`LargeTitleDisplay` property is explicitly set on the Page:

```csharp
if (!page.IsSet(PlatformConfiguration.iOSSpecific.Page.LargeTitleDisplayProperty))
{
    return; // Don't update if property not explicitly set
}
…rItems (#34085)

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

### Issue Details

- On iOS 26, setting Shell.ForegroundColor (either at the Shell level or
Page level) no longer applies the specified color to ToolbarItems.
- The toolbar items remain in the default system tint color instead of
respecting the configured foreground color.

### Root Cause

- On iOS 26, Apple's LiquidGlass redesign changed how
UINavigationBar.TintColor propagates to bar button items — it is no
longer automatically inherited.

### Description of Change

- Added UpdateRightBarButtonItemTintColors() method in
ShellPageRendererTracker.cs to explicitly set the TintColor of right bar
button items to the Shell's foreground color for iOS 26+ and Mac
Catalyst 26+. This ensures toolbar items correctly reflect the intended
color.
- Updated property change handlers (HandleShellPropertyChanged,
OnPagePropertyChanged) to call UpdateRightBarButtonItemTintColors() when
relevant properties change, guaranteeing color updates are applied when
needed.


### Issues Fixed
Fixes #34083

### Validated the behaviour in the following platforms

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

### Output

| Before | After |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/dc70555a-7e03-4922-94d5-1f6723c059f1">
| <img
src="https://github.com/user-attachments/assets/30a18bca-103d-4d76-a4ef-956fbbef3fe9">
|
…gate (#32045)

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

### Description of Change

Fixes Entry MaxLength property not being enforced on iOS 26 and
MacCatalyst 26.

**Root cause:** iOS 26 introduced a new delegate method
`ShouldChangeCharactersInRanges(NSValue[], string)` that accepts
multiple text ranges instead of the old `ShouldChangeCharacters(NSRange,
string)` method. The old delegate is no longer called on iOS 26, so
MAUI's MaxLength enforcement (which only subscribed to the old delegate)
stopped working.

**Fix:** 
- Use runtime version check to subscribe to the correct delegate:
  - iOS 26+: Subscribe to `ShouldChangeCharactersInRanges` 
  - iOS <26: Subscribe to `ShouldChangeCharacters` (existing behavior)
- Process all ranges in reverse order and simulate replacements to
calculate final text length
- Include paste truncation feature to maintain pre-iOS 26 behavior
(truncates long pastes to MaxLength)
- Add defensive null checks and range validation

**Key insight:** Multiple ranges must be processed in **reverse order**
(highest location first) because simulating replacements changes string
indices. Processing forward would invalidate subsequent range locations.

**What to avoid:**
- ❌ Only checking the first range - breaks marked text/IME composition
- ❌ Processing ranges in forward order - index calculations become
incorrect after first replacement
- ❌ Removing paste truncation - breaks backward compatibility

**References:**
- [UITextFieldDelegate
documentation](https://developer.apple.com/documentation/uikit/uitextfielddelegate/textfield(_:shouldchangecharactersin:replacementstring:))
- [What's new in UIKit
26](https://sebvidal.com/blog/whats-new-in-uikit-26/)

### Issues Fixed

Fixes #32016  
Fixes #33316

<img width="1021" height="451" alt="Screenshot 2025-10-17 at 16 14 05"
src="https://github.com/user-attachments/assets/cbb3e8ea-b677-4787-8d6b-4b98935d8951"
/>

https://sebvidal.com/blog/whats-new-in-uikit-26/
<img width="760" height="517" alt="Screenshot 2025-10-17 at 16 14 21"
src="https://github.com/user-attachments/assets/e5b2eeff-1c6e-4a91-b34a-ff2de4ff6e23"
/>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…5 tabs) (#27932)

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

### Description of Change

Fixes navigation lifecycle events (`OnAppearing`, `OnNavigatedTo`) and
back button behavior for Shell pages accessed through the "More" tab
(when TabBar has >5 tabs on iOS).

**Root cause:** When `IsInMoreTab` is true, `PushViewController` and
`PopViewController` delegate to
`UITabBarController.MoreNavigationController` instead of the base
navigation controller. The `MoreNavigationController` doesn't use our
`NavDelegate`, so `DidShowViewController` never fires, leaving
navigation completion tasks incomplete. This causes lifecycle events to
not fire and back button bindings to fail.

**Fix:** 
1. **Completion tasks:** Added `HandleMoreNavigationCompletionTasks()`
helper method that manually completes navigation tasks after More
push/pop operations
2. **Back button:** Set `BackAction` on pushed view controllers to call
`SendPop()` with the correct top view controller
3. **API cleanup:** Modified `SendPop()` to accept optional
`topViewController` parameter (defaults to `TopViewController` for
backward compatibility)

**Key insight:** MoreNavigationController is a separate
UINavigationController that doesn't inherit our delegate setup. Tasks
were being added to `_completionTasks` dictionary but never completed
because the delegate callback that completes them
(`DidShowViewController`) only fires for the base navigation controller.

**What to avoid:** Don't try to set a delegate on
`MoreNavigationController` - it's managed by iOS and delegate changes
may be overridden. The manual completion approach after each operation
is more reliable.

### Issues Fixed

Fixes #27799
Fixes #27800
Fixes #30862
Fixes #31166

|Before|After|
|--|--|
|<video
src="https://github.com/user-attachments/assets/08d993d7-25ad-4e12-bb80-e7c8162cf79e"
width="300px"/>|<video
src="https://github.com/user-attachments/assets/e07b53c3-c403-4e2b-a59d-e779e7c8274e"
width="300px"/>|
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Description of Change

Updated the NavigationRenderer on iOS to account for IView margins when
calculating the layout rectangle. This ensures that child views are
positioned and sized correctly according to their margin properties.

```xaml
  <NavigationPage.TitleView>
        <HorizontalStackLayout BackgroundColor="Blue"
                HorizontalOptions="Fill"
                VerticalOptions="Fill"
                Margin="-20,0,0,0">
            <Label Text="1234567890abcdefghij"/>
        </HorizontalStackLayout>
    </NavigationPage.TitleView>
```

|Before|After|
|--|--|
|<img
src="https://github.com/user-attachments/assets/283897af-0392-49e6-8332-b1b912de493d"
width="300px"/>|<img
src="https://github.com/user-attachments/assets/80d0465c-5d25-47b1-bcf1-55c3840e3888"
width="300px"/>|

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #32200

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…extending to system navigation bar (#33428)

### Root Cause
In Android `Edge-to-Edge` mode, the `MauiWindowInsetListener` was
applying padding to the root view and consuming bottom insets. This
prevented `BottomNavigationView` from receiving the system navigation
bar insets, so it could not extend its background color into the
navigation bar area—resulting in a visible gap between the tab bar and
the screen edge.
 
### Description of Change
When a `TabbedPage` uses `ToolbarPlacement.Bottom`, the fix applies
bottom padding to `contentView` (the fragment container) instead of the
root view, and passes bottom insets through without consuming them. This
allows `BottomNavigationView` to receive the insets and extend its
background color into the system navigation bar area, eliminating the
gap.

### Issues Fixed
Fixes #33344 
 
Tested the behaviour in the following platforms
- [x] Android
- [ ] Windows
- [x] iOS
- [ ] Mac

**Note:**
This issue is Android-specific. Windows and macOS do not have a system
navigation bar area at the bottom of the screen.

### Screenshots
| Before Issue Fix | After Issue Fix |
|------------------|-----------------|
| <img width="350" alt="withoutfix"
src="https://github.com/user-attachments/assets/878a0361-c0cd-4621-a063-94bbc757d15c"
/> | <img width="350" alt="withfix"
src="https://github.com/user-attachments/assets/ed552f1e-d75f-4275-856a-b8bf993a0dcd"
/> |
…2432)

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

This PR includes a comprehensive set of test cases for the
CollectionView control. The tests validate the FlowDirection Changes
functionality in CollectionView, including properties such as: Header,
Footer, HeaderTemplate, FooterTemplate, Grouping, EmptyView,
EmptyViewTemplate, Scrolling, Selection.

### Issues Identified:

- #32404

### Additional cases :
#32256
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
### RootCause

`FilePicker.PickMultipleAsync()` has incorrect nullable reference type
annotations causing compiler warnings with `#nullable enable`. When
checking if the result is null, the compiler warns "Expression is always
true" because `IEnumerable<FileResult?>` is not marked nullable, even
though the method returns null.
 
### Reason for Regression: 

PR #[27961](#27961) attempted to fix
null return behavior but applied the annotation incorrectly, making
items nullable `(Task<IEnumerable<FileResult?>>)` instead of making the
collection nullable `(Task<IEnumerable<FileResult>?>)`.
 
### Description of Change:

The fix moves the nullable marker from collection items to the
collection itself, changing `Task<IEnumerable<FileResult?>>` to
`Task<IEnumerable<FileResult>?> ` in the IFilePicker interface,
FilePicker static class, and FilePickerImplementation class.

### Issues Fixed
Fixes #33114

### Tested the behaviour on the following platforms
- [x] Android
- [x] Windows
- [x] iOS
- [x] Mac

### Note:
**Test Case**: Not applicable. This fix corrects nullable annotations
only and does not change runtime behavior. The scenario cannot be
validated through automated tests.
On Mac Catalyst 26+, the Picker view was incorrectly positioned,
appearing visually shifted within the picker controller.
This PR centers UIPickerView using NSLayoutConstraint when added to the
pickerController’s view. This ensures correct alignment, predictable
sizing, and consistent layout behavior across Mac Catalyst versions.

Fixes #33229

|Before|After|
|--|--|
|<img
src="https://github.com/user-attachments/assets/d55949ec-3f78-4836-a18c-778e240f2a1f"
width="300px"/>|<img
src="https://github.com/user-attachments/assets/7fb709ba-b1cd-490e-b093-7dd79f48ea08"
width="300px"/>|
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Description of Change

This pull request introduces platform-specific logic for registering
image handlers on Android, enabling support for Material 3 by
conditionally using a new handler. It also adds a new internal
`ImageHandler2` class for Android, which utilizes Google's Material
`ShapeableImageView` for improved image rendering.

**Android-specific handler registration:**

* The registration of the `Image` handler in
`AppHostBuilderExtensions.cs` is now conditional: if Material 3 is
enabled on Android, `ImageHandler2` is used; otherwise, the original
`ImageHandler` is used. On other platforms, `ImageHandler` continues to
be used.

**New Image Handler for Material 3:**

* Introduced a new internal `ImageHandler2` class for Android, which
overrides the platform view creation to use `ShapeableImageView` from
Google's Material library.

### Issues Fixed

Fixes #33660 

### Screenshot
| Material 2  | Material 3 |
|---------|--------|
| <img height=600 width=300
src="https://github.com/user-attachments/assets/c30a18fd-bf44-4a93-a751-bfb296f0d5ea">
|  <img height=600 width=300
src="https://github.com/user-attachments/assets/77a6a06b-d656-4bb3-9e39-dd3442c2f131"> 
|

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
…ell content (#34254)

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!
 ## Root Cause
iOS 26 introduced the Liquid Glass rendering system for the tab bar. In
`ShellItemTransition`, setting `newView.Alpha = 0` before the cross-fade
animation causes iOS 26 to composite the Liquid Glass tab bar icons
while the parent view is at zero opacity. When the animation restores
`alpha = 1`, the glass pill appears with the selected tab icon missing
because the Liquid Glass layer already cached its content at zero
opacity.
## Description of Change
- Updated `ShellItemTransition.cs` to skip setting `newView.Alpha = 0`
on iOS 26+, preventing
Liquid Glass tab bar icons from being composited while the parent view
is transparent.
- The cross-fade animation still runs on iOS 26+ (animating from the
default `alpha = 1`),
     so the visual transition is preserved.
- Added missing `using System;` directive required for
`OperatingSystem.IsIOSVersionAtLeast(26)`.

**Test coverage for the regression:**

* Introduced a new test case in `TestCases.HostApp` (`Issue34143.cs`)
that reproduces the navigation scenario and ensures the tab bar renders
correctly after navigating from a modal.
* Added a UI test (`TestCases.Shared.Tests/Tests/Issues/Issue34143.cs`)
to automate validation that the tab bar is visible and interactable
after the specific navigation flow, preventing regressions.
<!-- Enter description of the fix in this section -->

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #34143 

### Tested the behaviour in the following platforms

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

### Screenshot

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <img width="1206" height="2622" alt="Simulator Screenshot - iPhone 17
Pro - 2026-02-25 at 16 06 31"
src="https://github.com/user-attachments/assets/26ffcaf1-a5cb-4898-944b-7d08ae5f8f9f"
/> | <img width="1206" height="2622" alt="Simulator Screenshot - iPhone
17 - 2026-02-27 at 11 19 31"
src="https://github.com/user-attachments/assets/ccd5799b-278c-42c6-bc20-92498fc09b06"
/> |
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

This pull request adds new VisualStateManager feature matrix pages for
Button, CheckBox CollectionView, Entry, Label, Slider and Switch
controls, providing comprehensive demos and test cases for visual state
management. These additions enhance the test suite by enabling users to
interactively explore and verify VisualStateManager behaviors such as
Normal, Selected, PointerOver, Disabled, Focused, and Pressed across
different controls

**New VisualStateManager Feature Matrix Functionality**
- Added a new entry for “VisualStateManager Feature Matrix” to the Core
Views gallery, allowing easy navigation to the new demo pages from the
main test app UI.
- Implemented dedicated feature matrix pages covering the following
controls:
- Entry – Demonstrates visual states such as Normal, Focused, and
Completed with interactive input validation and styling updates.
- Button – Showcases Normal, Pressed, PointerOver, Disabled, and Focused
states with dynamic transitions.
- CollectionView – Demonstrates item-level states such as Normal,
Selected, Disable and PointerOver with interactive selection behavior.
- CheckBox – Covers Normal, Checked, Unchecked, and Disabled states with
dynamic styling.
- Label – Validates visual state transitions including Normal and
Disabled scenarios.
- Slider – Demonstrates Normal, Dragging, and Disabled states with
value-based interactions.
- Switch – Showcases On, Off, and Disabled states with state-based
styling updates.
- Added a supporting VSMCollectionViewViewModel, providing sample data
and logic for testing VisualStateManager behavior within CollectionView
scenarios.

**UI and Feature Coverage Enhancements**
- Added interactive controls and state-triggered styling to validate
VisualStateManager behavior across Entry, Button, CollectionView,
CheckBox, Label, Slider, and Switch.
- Enabled users to dynamically interact with controls to verify state
transitions such as:
- Normal, Selected, PointerOver, Disabled, Focused, Pressed, Checked,
Unchecked, On, Off, Completed, and Dragging.
- Provided structured demonstrations to ensure consistent verification
of visual state behavior across different control types and platforms.

**Code-Behind and Logic**
Created dedicated XAML and code-behind implementations for each
VisualStateManager feature page, including interactive handlers and
state-driven style logic.
Implemented a view model for CollectionView scenarios to supply sample
items and support visual state testing under realistic data-binding
conditions.



https://github.com/user-attachments/assets/7845278f-5328-44f8-a1cd-f21b6c57c166

---------

Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

This pull request introduces a new feature matrix page for clip
controls, providing UI and navigation for testing various clip
geometries and control types. The main changes add new pages and logic
to support interaction and configuration of clip features across
multiple controls.

New Clip Feature Matrix page:

* Added `ClipControlPage` to the feature matrix navigation, enabling
access to clip-related test cases from the main gallery.

Clip control navigation and main UI:

* Created `ClipControlPage.xaml` and `ClipControlPage.xaml.cs` to
provide a main selection interface for different control types (Border,
BoxView, Button, Image, Label, ContentView, ImageButton), each leading
to its respective clip test page.
[[1]](diffhunk://#diff-b7d7c225a540ea441e453bf89908da66da21a6d4fcdf2b6e61472d52cc03b7f8R1-R33)
[[2]](diffhunk://#diff-507d302b2e9bb3f416a0dff56ae23dc1464bf7e1811ddd34c616d087cee8ca4eR1-R52)

Clip options and configuration UI:

* Added `ClipOptionsPage.xaml` with extensive UI for selecting clip
geometry, path segment types, and configuring properties for various
controls (stroke, color, corner radius, font size, transforms, shadow,
and clear clip functionality).

### Issues Identified:

- #34114



https://github.com/user-attachments/assets/c43dcf47-943b-4159-b8b8-6c76e4b3c557
… 26 (#34019)

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

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->


### Issue Details

- On iOS 26, when a custom `ThumbImageSource` is set on a Slider control
at **runtime**, the thumb image is not vertically centered on the slider
track. The image appears offset (positioned incorrectly).

### Root Cause of the issue

- On iOS 26, calling UISlider.SetThumbImage() at runtime no longer
results in the thumb position being recalculated. On prior iOS versions,
the position was recalculated automatically. The exact internal
mechanism that changed is undocumented by Apple, but behavioral evidence
confirms the regression: the thumb updates visually but remains at the
stale position until user interaction forces a layout pass. Adding an
explicit SetNeedsLayout() call restores correct behavior.

### Description of Change
* In `SliderExtensions.cs`, after calling `SetThumbImage`, the code now
explicitly calls `SetNeedsLayout()` on the `UISlider` for iOS 26 and
above to ensure the thumb position is recalculated, restoring previous
runtime behavior.
<!-- Enter description of the fix in this section -->

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #33967

### Tested the behaviour in the following platforms

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

### Output
| Before | After |
|----------|----------|
| <img
src="https://github.com/user-attachments/assets/c0c2d380-7361-4524-a198-2e1a59145ca9">
| <img
src="https://github.com/user-attachments/assets/ec7c05a9-29c5-4a14-aef0-a267df097a94">
|

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

**This PR reopens the work from the closed PR
#30954

This pull request adds a new feature to test map controls in the app. It
includes UI components to test user interaction, map behavior, and
customization. Key changes include a Map Feature Matrix page, a main Map
Control page, and a Map Options page for configuration.
**Note:** Tests are added only for iOS and macOS, as Maps aren't
supported on Windows and require an API key on Android.

### New Map Feature Matrix Page
* Added a new entry for the `MapControlPage` in the `CorePageView` to
include it in the feature matrix navigation.
* Created `MapControlPage.xaml` to define the UI for displaying a map
and its interactive elements, including labels for map and marker click
events, and bindings for various map properties.
* Implemented `MapControlPage.xaml.cs` to handle map interactions,
synchronize map state with the ViewModel, and manage events like map
clicks, pin additions, and property changes.
* Added `MapOptionsPage.xaml` to provide a UI for configuring map
behavior and properties, such as visibility, zoom, traffic, and user
location. It also includes options to manage pins and map elements.


https://github.com/user-attachments/assets/d4fa0f89-785d-4a24-8deb-540f8ccc0e50

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Jakub Florkowski <42434498+kubaflo@users.noreply.github.com>
…true (#28983)

### Description of Change

On iOS, the `ActivityIndicator` becomes visible even when `IsVisible =
false` and `IsRunning = true`, effectively ignoring the `IsVisible`
property.

**Root Cause**

Visibility is not being correctly mapped in iOS.

By default, `IsVisible` is `true` for all elements, so we must
explicitly manage visibility based on the `IsRunning` value — especially
since it's expected that the `ActivityIndicator` is hidden by default.

The current implementation seems to work because `IsRunning` defaults to
`false`, which calls `StopAnimating()` and hides the native control.
However, if `HidesWhenStopped` is set to `false`, the control remains
visible without animating — which is incorrect.

To fix this, we explicitly update the visibility inside the `IsRunning`
mapper, just as it's done on Android.


<table>
  <tr>
<th>Before Fix</th>
<th>After Fix</th>
</tr>
<tr>
<td>


https://github.com/user-attachments/assets/19482315-e5ba-4c4e-af2a-2e883d6eef35


</td>
<td>


https://github.com/user-attachments/assets/9c05750d-d7ef-445c-9c65-64e6e142cc45


</td>
</tr>
</table>

### Issues Fixed


Closes #28968

---------

Co-authored-by: Jakub Florkowski <kubaflo123@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…modal (#34212)

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

## Description

Fixes #22938 - Modal page keyboard focus not shifting on Windows

When a modal page is pushed via `Navigation.PushModalAsync` on Windows,
keyboard focus stays on the underlying page. This causes:
1. **Enter key activates buttons beneath the modal** — a serious UX and
accessibility bug
2. **Tab navigation cycles through ALL stacked pages** — not just the
topmost modal

### Root Cause

`WindowRootViewContainer` (the WinUI Panel that stacks pages) had **zero
focus management**. Pages were layered by z-order but keyboard focus was
completely unmanaged.

### Fix

Three coordinated changes in `WindowRootViewContainer`:

1. **IsHitTestVisible toggling** — When pushing a modal, sets
`IsHitTestVisible = false` on the underlying page to block pointer/touch
input. Restores on pop.

2. **GettingFocus event trap** — Registers a `GettingFocus` handler
(with `handledEventsToo=true`) on the container that intercepts any
focus attempt leaving the modal page and redirects it back. This mirrors
how WinUI3's `ContentDialog` implements modal focus trapping.

3. **Focus restoration** — `SetFocusToFirstElement` moves focus to the
first focusable element in the new top page, with a `DispatcherQueue`
fallback for cases where the visual tree isn't ready.

**Critical ordering fix**: State (`_topPage`, focus trap) is updated
BEFORE `CachedChildren.Remove()` because WinUI3 fires `GettingFocus`
synchronously when removing a focused element. Without this, the handler
would see stale state pointing to the removed modal.

### Testing

- **Device test**: `ModalPageDisablesHitTestOnUnderlyingPage` — verifies
IsHitTestVisible toggling
- **Device test**: `ModalPageFocusTrapsAndRestoresCorrectly` — verifies
full push/pop cycle
- **UI test**: `Issue22938` — End-to-end test with semi-transparent
modal
- **Unit tests**: 69/69 existing modal tests pass
- **Manual testing**: Verified with MauiApp1 reproduction app (3
push/pop cycles, buttons functional after each pop)

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…view (#31215)

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

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
### Issue Details
In CV2, when there are no items, the CollectionView becomes horizontally
scrollable. This issue is not seen in CV1.

### Description of Change

<!-- Enter description of the fix in this section -->
Overrode CollectionViewContentSize to return CGSize.Empty when no items
are present, preventing unwanted scrolling.

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #17799 
Fixes #33201

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

### Regarding Test case
For this case, it's not possible to write a test because the scrollbar
does not appear during initial loading. It only becomes visible when a
scroll action is performed, and even then, it remains visible only for a
few seconds.

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

**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/b40d9b89-c5d7-41f0-bd26-0510f2a0547f"
width="300" height="600"> | **iOS**<br> <video
src="https://github.com/user-attachments/assets/5aaba964-6999-43eb-88d8-43e95deca353"
width="300" height="600"> |
…and reopened (#31066)

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

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
### Issue Details
The TimePicker was not showing AM/PM correctly after restarting the app
when using the format "HH:mm tt".

### Description of Change

<!-- Enter description of the fix in this section -->
We now use the same culture for both the display text and the TimePicker
control to ensure consistency. When the format includes AM/PM, we use
the en-US culture. For 24-hour formats, we use the de-DE culture.

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #30837 
Fixes #33722 

<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->

**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/d09aca5b-978c-47ef-ba43-2e639a501ca7"
width="300" height="600"> | **iOS**<br> <video
src="https://github.com/user-attachments/assets/58edaf5f-cca2-4451-be98-2e333a8d8807"
width="300" height="600"> |

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…32799)

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

This pull request adds a new VisualTransform feature matrix to the test
application, allowing users to interactively explore and manipulate
visual transformation properties (such as rotation, scale, translation,
anchor points, and shadow) on a sample UI element. The implementation
includes a new view model, Control page, and options page for setting
transformation parameters.

**VisualTransform Feature Matrix Addition**

* Added a new entry for the VisualTransform feature matrix in the main
gallery page list, exposing it in the test app UI (`CorePageView.cs`).
* Introduced `VisualTransformControlPage` and
`VisualTransformControlMainPage`, which display a demo element whose
visual transformation properties can be interactively modified and
reset. Navigation to an options page is supported for property editing
(`VisualTransformControlPage.xaml`,
`VisualTransformControlPage.xaml.cs`).
[[1]](diffhunk://#diff-40b18186c25db9939b3dd1f864e20691ef45ddadcc49d56b72fc0419fd03b122R1-R146)
[[2]](diffhunk://#diff-9c0f311a29ee6ea16863b27929f2874f5a6b1fec6bc0b3ee8c837156a57a4db7R1-R30)
* Added `VisualTransformOptionsPage` for editing transformation
properties (rotation, scale, translation, anchor points, visibility, and
shadow) with two-way data binding to the view model
(`VisualTransformOptionsPage.xaml`,
`VisualTransformOptionsPage.xaml.cs`).
[[1]](diffhunk://#diff-36dde512976f7ba703ea01eb98da9a60d16046d37112bf3637bde29e9f450701R1-R247)
[[2]](diffhunk://#diff-b59d66bdd977d8aa37213fb4d545242dd3e848bf34e3e9f09006679cbecfa576R1-R21)

* Implemented `VisualTransformViewModel` to encapsulate all
transformation-related properties, support property change
notifications, and provide a reset command for restoring default values
(`VisualTransformViewModel.cs`).

Identified Issue:

- #32724
- #32731


https://github.com/user-attachments/assets/c3653dfc-e225-4d98-92ee-0d1836f66788

---------

Co-authored-by: Shane Neuville <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: NafeelaNazhir <nafeela.nazhirhussain@syncfusion.com>
Co-authored-by: LogishaSelvarajSF4525 <logisha.selvaraj@syncfusion.com>
>[!NOTE]
>Are you waiting for the changes in this PR to be merged?
>It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR->Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!
 
This pull request adds a new "Shell Feature Matrix" test page to the
test application, providing comprehensive UI and code coverage for
various .NET MAUI Shell features. The changes introduce a new navigation
entry, new XAML and code-behind files for the Shell feature, and
implement interactive controls to test Shell properties, navigation, and
presentation modes.

The most important changes are:

**Feature Matrix Integration**
- Added a new entry for "Shell Feature Matrix" to the list of feature
matrix pages in `CorePageView.cs`, enabling access to the new Shell test
page from the main test app navigation.

**Shell Feature Page Implementation**
- Created `ShellFeaturePage.xaml` and its code-behind to serve as the
entry point for Shell feature testing, with a button that navigates to
the new Shell control page.
[[1]](diffhunk://#diff-429088ce96d697ab4ebcb64f4f34eab95990318df0e699a206770e487cc5f99cR1-R16)
[[2]](diffhunk://#diff-d9fe6832827db8c2b917b1667eb42de532a901608d7f118f002848d9a7fc5018R1-R24)

**Shell Control Page and UI**
- Implemented `ShellControlPage.xaml` and its code-behind, providing a
fully interactive Shell UI with multiple tabs and controls to test Shell
properties such as navigation bar visibility, animation, presentation
modes, title view, and tab visibility/enabled state.
[[1]](diffhunk://#diff-ef09490b3d33ffd4f104801faf89112b700d3a5f25bbe6becaf9596c98846c8dR1-R220)
[[2]](diffhunk://#diff-e29dc0b826e2441118582a11e860792f731a0fb606a75879643459b47163c013R1-R198)

**Shell Navigation and Presentation Modes**
- Registered routes and implemented navigation handlers for different
Shell presentation modes (Animated, NotAnimated, Modal, etc.), including
custom ContentPages to demonstrate each mode.

These changes collectively enhance the test app by allowing developers
to manually and programmatically verify a wide range of Shell behaviors
in .NET MAUI.

#### Issues Identified ####

- #17550
- #6399
- #5161
- #32125
- #33909


https://github.com/user-attachments/assets/cebb9549-b440-48b0-99ef-f6788e4541d1
…tems when IsGrouped was true for an ObservableCollection (#29144)

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

## Issue 1: Group header and footer templates not updating correctly at
runtime on iOS.

### Root Cause

The mapper for `GroupFooterTemplateProperty` and
`GroupHeaderTemplateProperty` in `GroupableItemsViewHandler` was
conditionally compiled with `#if WINDOWS || __ANDROID__ || TIZEN`,
meaning it was excluded from iOS builds. As a result, changing the
template at runtime on iOS had no effect and templates were never
displayed.

### Description of Change

Removed the `#if WINDOWS || __ANDROID__ || TIZEN` preprocessor guard
from `GroupableItemsViewHandler.cs`, making the
`GroupFooterTemplateProperty` and `GroupHeaderTemplateProperty` mappers
active on all platforms including iOS. Both mappers call `MapIsGrouped`,
which triggers `UpdateItemsSource()` and refreshes the grouping state.

---

## Issue 2: Group header/footer templates incorrectly applied to all
items in a flat ObservableCollection when `IsGrouped = true`.

### Root Cause

In `ObservableGroupedSource.cs` (iOS), the `GroupsCount()` method
iterated over all items in `_groupSource` and counted every item,
regardless of whether it was an `IEnumerable` (i.e., an actual group).
When `IsGrouped = true` but the source was a flat
`ObservableCollection<T>` (non-grouped), each non-grouped item was
counted as a section, causing `NumberOfSections` to be inflated. This
led to header and footer templates being incorrectly applied to every
item.

### Description of Change

Modified `GroupsCount()` to only increment the count for items that
implement `IEnumerable`. Non-`IEnumerable` items are no longer counted
as sections. As a result, `NumberOfSections` now correctly reflects the
number of actual groups, preventing header/footer templates from
appearing for non-grouped items.

---

### Issues Fixed

Fixes #29141

### Test Case

Tests for this fix are included in this PR:
- `src/Controls/tests/TestCases.HostApp/Issues/Issue29141.cs` — HostApp
page with a `CollectionView` bound to a flat `ObservableCollection`,
with radio buttons to toggle `IsGrouped`, `GroupHeaderTemplate`, and
`GroupFooterTemplate` at runtime.
- `src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue29141.cs`
— NUnit UI test verifying that group header/footer template views are
NOT shown when the source collection is not grouped.

> **Note:** The test is currently excluded from Windows (unrelated
NullReferenceException — see #28824) and Android (separate fix in PR
#28886). It runs on iOS and MacCatalyst.

### Platforms Tested

- [x] iOS
- [x] Android
- [x] Mac
- [ ] Windows
</details>

---------

Co-authored-by: Shane Neuville <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com>
…scape - fix (#26762)

Description needs updates. See details below.
### ✨ Suggested PR Description

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

### Root Cause

In `PhoneFlyoutPageRenderer.LayoutChildren()`, when `IsRTL &&
!FlyoutOverlapsDetailsInPopoverMode`, the flyout panel's X position was
calculated as:

```csharp
flyoutFrame.X = (int)(flyoutFrame.Width * .25);
```

This formula positions the flyout at 25% of its own width from the left
edge — not at the right side of the screen. In landscape orientation
(where `frame.Width` is large), this places the flyout far off to the
left, making its content invisible or clipped rather than right-aligned
as expected for RTL layout.

### Description of Change

**`PhoneFlyoutPageRenderer.cs`** — 1-line fix:

```csharp
// Before
flyoutFrame.X = (int)(flyoutFrame.Width * .25);

// After
flyoutFrame.X = (int)(frame.Width - flyoutFrame.Width);
```

`frame.Width - flyoutFrame.Width` is the standard right-align formula:
it positions the flyout so its right edge aligns with the screen's right
edge, which is the correct position for an RTL flyout panel.

**`Issue2818.cs`** (test) — two changes:

1. Removed `TEST_FAILS_ON_IOS` compile guard. The test was previously
skipped on iOS because the RTL flyout was broken. The fix makes iOS
behavior correct, so the guard is no longer needed.

2. Added `RootViewSizeDoesntChangeAfterBackground` test (async) with a
polling loop (up to 5s / 50 × 100ms) to wait for window size to
stabilize after backgrounding/foregrounding the app. This prevents
flakiness caused by intermediate layout sizes during window restoration
on iOS.

### Issues Fixed

Fixes #26726

### Platforms Tested

- [x] iOS (primary — fix targets iOS RTL landscape flyout behavior)
- [ ] Android (not affected — `PhoneFlyoutPageRenderer` is iOS-only)
- [ ] Windows (not affected)
- [ ] Mac Catalyst (test still excluded via `TEST_FAILS_ON_CATALYST`
guard)
</details>

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

### Root Cause

On Android, when a custom `ThumbImageSource` is set on a `Slider`, the
image drawable is applied to the `SeekBar` at its native size. Because
images are typically larger than the expected thumb diameter (20dp per
Material Design spec), the thumb appears oversized.

### Description of Change

**Android only** — this PR adds image scaling before applying custom
thumb drawables to `SeekBar`.

Key changes in `src/Core/src/Platform/Android/SliderExtensions.cs`:

- **`UpdateThumbImageSourceAsync`**: Refactored to call two new helpers
(`SetThumbDrawable` / `SetDefaultThumb`) instead of inlining the logic.
- **`SetThumbDrawable`**: New method that scales the provided drawable
to 20dp × 20dp (Material Design thumb size) by rendering it to a
fixed-size `Bitmap` then wrapping in a `BitmapDrawable` before calling
`SeekBar.SetThumb()`.
- **`SetDefaultThumb`**: New method that restores the platform default
thumb drawable (`abc_seekbar_thumb_material`) and re-applies the theme
accent color or custom `ThumbColor`. Also adds a `ResolveAttribute`
return-value check (previously the result was ignored).
- **Null checks**: Updated `!= null` patterns to `is not null` for
consistency.

**Note:** iOS and MacCatalyst scaling is tracked separately in PR
#34184.

### Issues Fixed

Fixes #13258

### Platforms Tested

- [x] Android
- [ ] iOS (separate PR #34184)
- [ ] Windows
- [ ] Mac


Previously closed PR - #27472

---------

Co-authored-by: Shane Neuville <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kubaflo and others added 14 commits March 22, 2026 16:52
…roperty - fix (#28797)

### Description of Change

More generic condition for detecting the 24 hour date format

### Issues Fixed

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

<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Issues Fixed

Fixes #29573
Fixes #23623
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Description of Change

To resolve the UITest Build Sample failures , replaced the
PlatformAffected.MacCatalyst with PlatformAffected.macOS — there is no
MacCatalyst member in the enum. The correct value is macOS (lowercase
'm', uppercase 'OS'). -
…lor not updating (#31254)" (#34508)

Revert PR #31254 from the inflight/candidate branch due to multiple
failures. The failures need to be validated, and the fix will be
included later.

### Reverted changes
- **Handler logic**: `GraphicsViewHandler` on iOS, Android, and Windows
restored to pre-PR behavior; removes `UpdateBackground()` calls and
`NeedsContainer` override on Windows
- **iOS platform**: Removes `PixelAlign()` helper and `LayoutSubviews()`
override from `PlatformGraphicsView`
- **Tests**: Removes `Issue31239` host app page and shared UI test;
restores `Issue25502` host app page and shared UI test
- **Snapshots**: Restores `VerifyGraphicsViewWithoutGrayLine` snapshots;
removes `GraphicsViewBackgroundShouldBeApplied` and
`GraphicsViewBackgroundShouldBeChanged` snapshots
- **PublicAPI**: Removes `LayoutSubviews` and `NeedsContainer` entries
from unshipped API files for iOS, MacCatalyst, and Windows

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 Send tasks to Copilot coding agent from
[Slack](https://gh.io/cca-slack-docs) and
[Teams](https://gh.io/cca-teams-docs) to turn conversations into code.
Copilot posts an update in your thread when it's finished.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
…nal source generators (#34514)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!
###  Root Cause :
- [PR #31940 ](#31940) added
`ContentLabel` as a top-level internal class in Microsoft.Maui.Controls.
It inherits from `Label`, so it implements ITextStyle and IAnimatable.
- Source generators scan all namespace-level types in the assembly.
Because `ContentLabel` is namespace-level, it was picked up and code was
generated referencing it.
- Since the class is internal, the generated code cannot access it from
another assembly, causing a compile-time accessibility error.

### Description of Change : 

- `ContentLabel` was moved from a top-level internal class in
`Microsoft.Maui.Controls` to a nested class inside `ContentConverter`.
- Top-level internal classes are returned by namespace-level scans, but
nested classes without an explicit modifier are private by default.
- Source generators scanning top-level types no longer see
`ContentLabel`, so no code is generated referencing it.
- Functionally, nothing changed: `ContentLabel` is still used only
inside `ContentConverter`, and style mechanisms continue to work
correctly.

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #34512 

### Tested the behavior in the following platforms

- [x] Windows
- [x] Android
- [x] iOS
- [x] Mac
### ScreenShots
| Before Issue Fix | After Issue Fix |
|----------|----------|
| <img width="1158" height="276" alt="Screenshot 2026-03-17 at 19 42 54"
src="https://github.com/user-attachments/assets/3021227c-b516-4403-98f3-569ec4266ee0"
/>| <img width="1073" height="833" alt="Screenshot 2026-03-17 at 19 37
06"
src="https://github.com/user-attachments/assets/24dbc6ce-86b4-4748-9184-37a01f65005a"
/> |
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### RootCause of the issue

- In PR #33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for #33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state.
 
### Description of Change
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for #33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

### Test failures
- EntryScrollTest, HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape,
VerifyBindableLayoutWithGridItemTemplate - (EntryScrollTest)Test fails
due to #33428 this PR



### Issues Fixed

Fixes #34509
### Root Cause of the issue



- The failing test: `SetVisibility(Visibility.Collapsed)` device test on
iOS.

  Why it fails: PR #28983's fix maps Visibility → MapIsRunning in
  ActivityIndicatorHandler, which bypasses the standard
ViewExtensions.UpdateVisibility path. The standard path calls Collapse()
to
add a CollapseConstraint (an NSLayoutConstraint that zeros the view's
size).
The PR's UpdateIsRunning only sets Hidden = true — it never calls
Collapse()
- Crash in the FeatureMatrix Navigation Page Scenario in the iOS 26
PR #34326 added an else block in UpdateBarTextColor() that explicitly
sets BackButtonAppearance = null, BackIndicatorImage = null, and
BackIndicatorTransitionMaskImage = null on the navigation bar when no
custom color is applied. On iOS versions before 26, assigning null to
these properties was treated as "use system defaults." On iOS 26, the
Liquid Glass rendering pipeline reads these properties during push/pop
navigation transitions and throws an exception when it encounters an
explicit null — it expects either an unset property or a valid object.
Since useCustomColor is false by default (no IconColor set), this
crashes on every standard page navigation.
- Setting ThumbTintList = null in the else block removes the tint
entirely, causing the thumb to appear white instead of the default blue,
because SwitchCompat does not re-resolve its theme colors once the tint
list is cleared.
- SetAdjustViewBounds(false) was being applied to all images regardless
of their Aspect value. When this property is false, Android’s ImageView
does not resize itself based on the image’s intrinsic aspect ratio and
instead expands to fill the available space. As a result, an Image
control with the default AspectFit setting ignored its height constraint
and overflowed its container, causing the image to appear taller than
expected in the screenshot test.(LoadAndVerifyGif, ThemeRelated feature
tests)
- PR #29144 changed the group-detection guard in ObservableGroupedSource
(iOS and Android) from is IEnumerable to is ICollection to prevent
strings (which implement IEnumerable<char>) from being treated as
groups.
While the intent was correct, the change was too broad. Custom group
types that implement only IEnumerable<T> were also excluded. As a
result, _groupCount became zero on iOS and _groups remained empty on
Android, causing grouped CollectionView rendering failures and
IndexOutOfRangeException during Add/Remove operations.
- StepperHandler.iOS.cs compiles for both iOS and Mac Catalyst. On Mac
Catalyst / macOS 26, OperatingSystem.IsIOS() and IsIOSVersionAtLeast(26)
both return true, and the screen is always landscape. As a result, the
20pt glass pill compensation was incorrectly applied, inflating
GetDesiredSize(1,1) to width = 21. (Native View Bounding Box is not
empty - device Test failures)
- In PR #33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for #33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state. (EntryScrollTest,
HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape and so on failures)

### Description of Change



- Handles the three Visibility cases the same way as
ViewExtensions.UpdateVisibility:

`Visible`: Calls Inflate() (restores layout size) and sets Hidden =
false — identical to UpdateVisibility. Additionally starts/stops the
animation based on IsRunning.
`Hidden`: Calls Inflate() (preserves layout space) and sets Hidden =
true — identical to UpdateVisibility. The indicator keeps its layout
footprint but is invisible.
`Collapsed`: Sets Hidden = true and calls Collapse() (zeros out layout
size via constraints) — identical to UpdateVisibility. The indicator is
both invisible and takes up no space.
- Removed the else block entirely. When no custom color is applied,
these properties should remain untouched. The system defaults work
correctly on their own — there is no need to explicitly reset them to
null
- Removed the else block from UpdateThumbColor in SwitchExtensions.cs.
The default thumb color is managed by SwitchCompat internally from the
Material theme, so no explicit reset is needed.
- Restored the correct logic in ImageViewExtensions.UpdateAspect to call
SetAdjustViewBounds based on the image’s Aspect value:
- The guard has been updated from is ICollection to is IEnumerable &&
not string in the ObservableGroupedSource implementations for both iOS
and Android (GroupsCount(), UpdateGroupTracking(), Add(), Remove()).
This change specifically excludes string while allowing legitimate
custom group types that implement only IEnumerable<T>. The fix restores
the behavior for Issue22320 while keeping all Issue29141 scenarios
working correctly.
-Added !OperatingSystem.IsMacCatalyst() to the guard condition in
GetDesiredSize, restricting the 20pt compensation to real iOS 26+ only —
as intended in the original PR comment.
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for #33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

### Testing related description of change
EditorNoOverlapAfterRotateToLandscape,
EditorNoOverlapAfterRotateToPortrait,
EntryFocusedShouldNotCauseGapAfterRotation Added cropLeft to remove the
navbar on Android and re-saved the image due to entry text changes in
this commit –
8d17a6d,
91047fb.

DrawStringShouldDrawText – The automation ID set to GraphicsView was not
found by Appium on the Windows platform, so a test condition was added
for Windows to take the image directly instead of waiting for the
GraphicsView.

Added the base images for iOS 26 and Mac that were not added previously.

Re-saved the images that failed due to the wrong iOS version image being
added in the PR.

Re-saved the test images that failed due to this fix PR:
#31254 — e.g.,
GraphicsViewFeatureTests and others.
 
Resaved the slider-related test images due to this fix PR —
#34064.

### Issues Fixed




Fixes #34437 



### Tested the behaviour in the following platforms



- [x] iOS
- [x] Mac

---------

Co-authored-by: SyedAbdulAzeem <syedabdulazeem.a@syncfusion.com>
Co-authored-by: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com>
Co-authored-by: TamilarasanSF4853 <tamilarasan.velu@syncfusion.com>
Co-authored-by: LogishaSelvarajSF4525 <logisha.selvaraj@syncfusion.com>
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### Description of Change

- Resaved the images of `EditorNoOverlapAfterRotateToLandscape`,
`EditorNoOverlapAfterRotateToPortrait`,
`EntryFocusedShouldNotCauseGapAfterRotation` due to entry text changes
in this commit –
[8d17a6d](8d17a6d),
[91047fb](91047fb).

- Re-saved the correct image of`CollectionViewShouldChangeItemsLayout`
(Issue28656) due to a slight difference between CV1 and CV2. Since the
XAML code for Issue28656 explicitly uses CV2, it has now been re-saved
accordingly.


Fixes #34437
#34575)

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

## Description

Adds Windows platform support to the `maui-copilot` CI pipeline (AzDO
definition 27723), enabling Copilot PR reviews on Windows-targeted PRs.

### Changes

**`eng/pipelines/ci-copilot.yml`**
- Add `catalyst` and `windows` to Platform parameter values
- Add per-platform pool selection (`androidPool`, `iosPool`, `macPool`,
`windowsPool`)
- Skip Xcode, Android SDK, simulator setup for Windows/Catalyst
- Add Windows-specific "Set screen resolution" step (1920x1080)
- Add MacCatalyst-specific "Disable Notification Center" step
- Fix `sed` command for `Directory.Build.Override.props` on Windows (Git
Bash uses GNU sed)
- Handle Copilot CLI PATH detection on Windows vs Unix
- Change `script:` steps to `bash:` for cross-platform consistency

**`.github/scripts/Review-PR.ps1`**
- Add `catalyst` to ValidateSet for Platform parameter

**`.github/scripts/BuildAndRunHostApp.ps1`**
- Add Windows test assembly directory for artifact collection

**`.github/scripts/post-ai-summary-comment.ps1` /
`post-pr-finalize-comment.ps1`**
- Various improvements for cross-platform comment posting

### Validation

Successfully ran the pipeline with `Platform=windows` on multiple
Windows-specific PRs:
- PR #27713 — ✅ Succeeded
- PR #34337 — ✅ Succeeded
- PR #26217, #27609, #27880, #28617, #29927, #30068 — Triggered and
running

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## What's Coming

.NET MAUI inflight/candidate introduces significant improvements across
all platforms with focus on quality, performance, and developer
experience. This release includes 66 commits with various improvements,
bug fixes, and enhancements.


## Activityindicator
- [Android] Implemented material3 support for ActivityIndicator by
@Dhivya-SF4094 in #33481
  <details>
  <summary>🔧 Fixes</summary>

- [Implement material3 support for
ActivityIndicator](#33479)
  </details>

- [iOS] Fix: ActivityIndicator IsRunning ignores IsVisible when set to
true by @bhavanesh2001 in #28983
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] [ActivityIndicator] `IsRunning` ignores `IsVisible` when set to
`true`](#28968)
  </details>

## Button
- [iOS] Button RTL text and image overlap - fix by @kubaflo in
#29041

## Checkbox
- [iOS/MacCatalyst] Fix CheckBox foreground color not resetting when set
to null by @Ahamed-Ali in #34284
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Color of the checkBox control is not properly worked on dynamic
scenarios](#34278)
  </details>

## CollectionView
- [iOS] Fix: CollectionView does not clear selection when SelectedItem
is set to null by @Tamilarasan-Paranthaman in
#30420
  <details>
  <summary>🔧 Fixes</summary>

- [CollectionView not being able to remove selected item highlight on
iOS](#30363)
- [[MAUI] Select items traces are
preserved](#26187)
  </details>

- [iOS] CV2 ItemsLayout update by @kubaflo in
#28675
  <details>
  <summary>🔧 Fixes</summary>

- [CollectionView CollectionViewHandler2 doesnt change ItemsLayout on
DataTrigger](#28656)
- [iOS CollectionView doesn't respect a change to ItemsLayout when using
Items2.CollectionViewHandler2](#31259)
  </details>

- [iOS][CV2] Fix CollectionView renders large empty space at bottom of
view by @devanathan-vaithiyanathan in
#31215
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] [MacCatalyst] CollectionView renders large empty space at
bottom of view](#17799)
- [[iOS/Mac] CollectionView2 EmptyView takes up large horizontal space
even when the content is
small](#33201)
  </details>

- [iOS] Fixed issue where group Header/Footer template was set to all
items when IsGrouped was true for an ObservableCollection by
@Tamilarasan-Paranthaman in #29144
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Group Header/Footer Repeated for All Items When IsGrouped is
True for ObservableCollection in
CollectionView](#29141)
  </details>

- [Android] Fix CollectionView selection crash with HeaderTemplate by
@NirmalKumarYuvaraj in #34275
  <details>
  <summary>🔧 Fixes</summary>

- [[Bug] [Android] System.ArgumentOutOfRangeException: Index was out of
range. Must be non-negative and less than the size of the collection.
Parameter name: index](#34247)
  </details>

## DateTimePicker
- [iOS] Fix TimePicker AM/PM frequently changes when the app is closed
and reopened by @devanathan-vaithiyanathan in
#31066
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] TimePicker AM/PM frequently changes when the app is closed and
reopened](#30837)
- [Maui 10 iOS TimePicker Strange Characters in place of
AM/PM](#33722)
  </details>

- Android TimePicker ignores 24 hour system setting when using Format
Property - fix by @kubaflo in #28797
  <details>
  <summary>🔧 Fixes</summary>

- [Android TimePicker ignores 24 hour system setting when using Format
Property](#28784)
  </details>

## Drawing
- [iOS, Mac, Windows] GraphicsView: Fix Background/BackgroundColor not
updating by @NirmalKumarYuvaraj in
#31254
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS, Mac, Windows] GraphicsView does not change the
Background/BackgroundColor](#31239)
  </details>

- [iOS] GraphicsView DrawString - fix by @kubaflo in
#26304
  <details>
  <summary>🔧 Fixes</summary>

- [DrawString not rendering in
iOS.](#24450)
- [GraphicsView DrawString not rendering in
iOS](#8486)
- [DrawString doesn't work on
maccatalyst](#4993)
  </details>

- [Android] - Fix Shadow Rendering For Transparent Fill, Stroke (Lines),
and Text on Shapes by @prakashKannanSf3972 in
#29528
  <details>
  <summary>🔧 Fixes</summary>

- [Ellipse Transparency Not Rendered When Drawing Arc Inside the Ellipse
Using GraphicsView on
Android](#29394)
  </details>

- Revert "[iOS, Mac, Windows] GraphicsView: Fix
Background/BackgroundColor not updating (#31254)" by @Ahamed-Ali via
@Copilot in #34508

## Entry
- [iOS 26] Fix Entry MaxLength not enforced due to new multi-range
delegate by @kubaflo in #32045
  <details>
  <summary>🔧 Fixes</summary>

- [iOS 26 - The MaxLength property value is not respected on an Entry
control.](#32016)
- [.NET MAUI Entry Maximum Length not working on iOS and
macOS](#33316)
  </details>

- [iOS] Fixed Entry with IsPassword toggling loses previously entered
text by @SubhikshaSf4851 in #30572
  <details>
  <summary>🔧 Fixes</summary>

- [Entry with IsPassword toggling loses previously entered text on iOS
when IsPassword is
re-enabled](#30085)
  </details>

## Essentials
- Fix for FilePicker PickMultipleAsync nullable reference type by
@SuthiYuvaraj in #33163
  <details>
  <summary>🔧 Fixes</summary>

- [FilePicker PickMultipleAsync nullable reference
type](#33114)
  </details>

- Replace deprecated NetworkReachability with NWPathMonitor on iOS/macOS
by @jfversluis via @Copilot in #32354
  <details>
  <summary>🔧 Fixes</summary>

- [NetworkReachability is obsolete on iOS/maccatalyst
17.4+](#32312)
- [Use NWPathMonitor on iOS for Essentials
Connectivity](#2574)
  </details>

## Essentials Connectivity
- Update Android Connectivity implementation to use modern APIs by
@jfversluis via @Copilot in #30348
  <details>
  <summary>🔧 Fixes</summary>

- [Update the Android Connectivity implementation to user modern
APIs](#30347)
  </details>

## Flyout
- [iOS] Fixed Flyout icon not updating when root page changes using
InsertPageBefore by @Vignesh-SF3580 in
#29924
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Flyout icon not replaced by back button when root page is
changed using
InsertPageBefore](#29921)
  </details>

## Flyoutpage
- [iOS] Flyout Items Not Displayed in RightToLeft FlowDirection in
Landscape - fix by @kubaflo in #26762
  <details>
  <summary>🔧 Fixes</summary>

- [Flyout Items Not Displayed in RightToLeft FlowDirection on iOS in
Landscape Orientation and Hamburger Icon Positioned
Incorrectly](#26726)
  </details>

## Image
- [Android] Implemented Material3 support for Image by @Dhivya-SF4094 in
#33661
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 support for
Image](#33660)
  </details>

## Keyboard
- [iOS] Fix gap at top of view after rotating device while Entry
keyboard is visible by @praveenkumarkarunanithi in
#34328
  <details>
  <summary>🔧 Fixes</summary>

- [Focusing and entering texts on entry control causes a gap at the top
after rotating simulator.](#33407)
  </details>

## Label
- [Android] Support for images inside HTML label by @kubaflo in
#21679
  <details>
  <summary>🔧 Fixes</summary>

- [Label with HTML TextType does not display images on
Android](#21044)
  </details>

- [fix] ContentLabel Moved to a nested class to prevent CS0122 in
external source generators by @SubhikshaSf4851 in
#34514
  <details>
  <summary>🔧 Fixes</summary>

- [[MAUI] Building Maui App with sample content results CS0122
errors.](#34512)
  </details>

## Layout
- Optimize ordering of children in Flex layout by @symbiogenesis in
#21961

- [Android] Fix control size properties not available during Loaded
event by @Vignesh-SF3580 in #31590
  <details>
  <summary>🔧 Fixes</summary>

- [CollectionView on Android does not provide height, width, logical
children once loaded, works fine on
Windows](#14364)
- [Control's Loaded event invokes before calling its measure override
method.](#14160)
  </details>

## Mediapicker
- [iOS/Android] MediaPicker: Fix image orientation when RotateImage=true
by @michalpobuta in #33892
  <details>
  <summary>🔧 Fixes</summary>

- [MediaPicker.PickPhotosAsync does not preserve image
orientation](#32650)
  </details>

## Modal
- [Windows] Fix modal page keyboard focus not shifting to newly opened
modal by @jfversluis in #34212
  <details>
  <summary>🔧 Fixes</summary>

- [Keyboard focus does not shift to a newly opened modal page: Pressing
enter clicks the button on the page beneath the modal
page](#22938)
  </details>

## Navigation
- [iOS26] Apply view margins in title view by @kubaflo in
#32205
  <details>
  <summary>🔧 Fixes</summary>

- [NavigationPage TitleView iOS
26](#32200)
  </details>

- [iOS] System.NullReferenceException at
NavigationRenderer.SetStatusBarStyle() by @kubaflo in
#29564
  <details>
  <summary>🔧 Fixes</summary>

- [System.NullReferenceException at
NavigationRenderer.SetStatusBarStyle()](#29535)
  </details>

- [iOS 26] Fix back button color not applied for NavigationPage by
@Shalini-Ashokan in #34326
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Color not applied to the Back button text or image on iOS
26](#33966)
  </details>

## Picker
- Fix Picker layout on Mac Catalyst 26+ by @kubaflo in
#33146
  <details>
  <summary>🔧 Fixes</summary>

- [[MacOS 26] Text on picker options are not centered on macOS
26.1](#33229)
  </details>

## Progressbar
- [Android] Implemented Material3 support for ProgressBar by
@SyedAbdulAzeemSF4852 in #33926
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 support for
Progressbar](#33925)
  </details>

## RadioButton
- [iOS, Mac] Fix for RadioButton TextColor for plain Content not working
by @HarishwaranVijayakumar in #31940
  <details>
  <summary>🔧 Fixes</summary>

- [RadioButton: TextColor for plain Content not working on
iOS](#18011)
  </details>

- [All Platforms] Fix RadioButton warning when ControlTemplate is set
with View content by @kubaflo in
#33839
  <details>
  <summary>🔧 Fixes</summary>

- [Seeking clarification on RadioButton + ControlTemplate + Content
documentation](#33829)
  </details>

- Visual state change for disabled RadioButton by @kubaflo in
#23471
  <details>
  <summary>🔧 Fixes</summary>

- [RadioButton disabled UI issue -
iOS](#18668)
  </details>

## SafeArea
- [Android] Fix for TabbedPage BottomNavigation BarBackgroundColor not
extending to system navigation bar by @praveenkumarkarunanithi in
#33428
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] TabbedPage BottomNavigation BarBackgroundColor does not
extend to system navigation bar area in Edge-to-Edge
mode](#33344)
  </details>

## ScrollView
- [Android] ScrollView: Fix HorizontalScrollBarVisibility not updating
immediately at runtime by @SubhikshaSf4851 in
#33528
  <details>
  <summary>🔧 Fixes</summary>

- [Runtime Scrollbar visibility not updating correctly on Android and
macOS platforms.](#33400)
  </details>

- Fixed crash when calling ItemsView.ScrollTo on unloaded CollectionView
by @kubaflo in #25444
  <details>
  <summary>🔧 Fixes</summary>

- [App crashes when calling ItemsView.ScrollTo on unloaded
CollectionView](#23014)
  </details>

## Shell
- [Shell] Update logic for iOS large title display in ShellItemRenderer
by @kubaflo in #33246

- [iOS][Shell] Fix navigation lifecycle and back button for More tab (>5
tabs) by @kubaflo in #27932
  <details>
  <summary>🔧 Fixes</summary>

- [OnAppearing and OnNavigatedTo does not work when using extended
Tabbar (tabbar with more than 5 tabs) on
IOS.](#27799)
- [Shell.BackButtonBehavior does not work when using extended Tabbar
(tabbar with more than 5 tabs)on
IOS.](#27800)
- [Shell TabBar More button causes ViewModel command binding
disconnection on back
navigation](#30862)
- [Content page onappearing not firing if tabs are on the more tab on
IOS](#31166)
  </details>

- [iOS 26] Fix tab bar ghosting when navigating from modal to tabbed
Shell content by @SubhikshaSf4851 in
#34254
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Tab bar ghosting issue on iOS 26 (liquid
glass)](#34143)
  </details>

- Fix for Shell tab visibility not updating when navigating back
multiple pages by @BagavathiPerumal in
#34403
  <details>
  <summary>🔧 Fixes</summary>

- [Changing Shell Tab Visibility when navigating back multiple pages
ignores Shell Tab
Visibility](#33351)
  </details>

- [iOS/Mac] Fixed OnBackButtonPressed not firing for Shell Navigation
Bar Button by @Dhivya-SF4094 in
#34401
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] OnBackButtonPressed not firing for Shell Navigation Bar
button](#34190)
  </details>

## Slider
- [iOS] Fix for Slider ThumbImageSource is not centered properly on iOS
26 by @HarishwaranVijayakumar in
#34019
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS 26] Slider ThumbImageSource is not centered
properly](#33967)
  </details>

- [Android] Fix improper rendering of ThumbimageSource in Slider by
@NirmalKumarYuvaraj in #34064
  <details>
  <summary>🔧 Fixes</summary>

- [[Slider] MAUI Slider thumb image is big on
android](#13258)
  </details>

## Stepper
- [iOS] Fix Stepper layout overlap in landscape on iOS 26 by
@Vignesh-SF3580 in #34325
  <details>
  <summary>🔧 Fixes</summary>

- [[.NET10] D10 - Customize cursor position - Rotating simulator makes
the button and label
overlap](#34273)
  </details>

## SwipeView
- [iOS] SwipeView: Honor FontImageSource.Color in SwipeItem icon by
@kubaflo in #27389
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] SwipeView: SwipeItem.IconImageSource.FontImageSource color
value not honored](#27377)
  </details>

## Switch
- [Android] Fix Switch thumb shadow missing when ThumbColor is set by
@Shalini-Ashokan in #33960
  <details>
  <summary>🔧 Fixes</summary>

- [Android Switch Control Thumb
Shadow](#19676)
  </details>

## Toolbar
- [iOS/Mac Catalyst 26] Fix Shell.ForegroundColor not applied to
ToolbarItems by @SyedAbdulAzeemSF4852 in
#34085
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS26] Shell.ForegroundColor is not applied to
ToolbarItems](#34083)
  </details>

- [Android] VoiceOver on Toolbar Item by @kubaflo in
#29596
  <details>
  <summary>🔧 Fixes</summary>

- [VoiceOver on Toolbar
Item](#29573)
- [SemanticProperties do not work on
ToolbarItems](#23623)
  </details>


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

- [Testing] Additional Feature Matrix Test Cases for CollectionView by
@TamilarasanSF4853 in #32432
- [Testing] Feature Matrix UITest Cases for VisualStateManager by
@LogishaSelvarajSF4525 in #34146
- [Testing] Feature Matrix UITest Cases for Clip by @TamilarasanSF4853
in #34121
- [Testing] Feature matrix UITest Cases for Map Control by
@HarishKumarSF4517 in #31656
- [Testing] Feature matrix UITest Cases for Visual Transform Control by
@HarishKumarSF4517 in #32799
- [Testing] Feature Matrix UITest Cases for Shell Pages by
@NafeelaNazhir in #33945
- [Testing] Feature Matrix UITest Cases for Triggers by
@HarishKumarSF4517 in #34152
- [Testing] Refactoring Feature Matrix UITest Cases for CheckBox Control
by @LogishaSelvarajSF4525 in #34283
- Resolve UI test Build Sample failures - Candidate March 16 by
@Ahamed-Ali in #34442
- Fix the failures in the Candidate branch- March 16 by @Ahamed-Ali in
#34453
  <details>
  <summary>🔧 Fixes</summary>

  - [March 16th, Candidate](#34437)
  </details>
- Fixed the iOS 18.5 Candidate failures (March 16,2026) by @Ahamed-Ali
in #34593
  <details>
  <summary>🔧 Fixes</summary>

  - [March 16th, Candidate](#34437)
  </details>

</details>

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

- Fixed candidate test failures caused by PR #33428. by @Ahamed-Ali in
#34515
  <details>
  <summary>🔧 Fixes</summary>

- [[.NET10] On Android, there's a big space at the top for I, M and N2 &
N3](#34509)
  </details>
- Revert "[iOS] Button RTL text and image overlap - fix (#29041)" in
b0497af

</details>

<details>
<summary>📝 Issue References</summary>

Fixes #2574, Fixes #4993, Fixes #8486, Fixes #13258, Fixes #14160, Fixes
#14364, Fixes #17799, Fixes #18011, Fixes #18668, Fixes #19676, Fixes
#21044, Fixes #22938, Fixes #23014, Fixes #23623, Fixes #24450, Fixes
#26187, Fixes #26726, Fixes #27377, Fixes #27799, Fixes #27800, Fixes
#28656, Fixes #28784, Fixes #28968, Fixes #29141, Fixes #29394, Fixes
#29535, Fixes #29573, Fixes #29921, Fixes #30085, Fixes #30347, Fixes
#30363, Fixes #30837, Fixes #30862, Fixes #31166, Fixes #31239, Fixes
#31259, Fixes #32016, Fixes #32200, Fixes #32312, Fixes #32650, Fixes
#33114, Fixes #33201, Fixes #33229, Fixes #33316, Fixes #33344, Fixes
#33351, Fixes #33400, Fixes #33407, Fixes #33479, Fixes #33660, Fixes
#33722, Fixes #33829, Fixes #33925, Fixes #33966, Fixes #33967, Fixes
#34083, Fixes #34143, Fixes #34190, Fixes #34247, Fixes #34273, Fixes
#34278, Fixes #34437, Fixes #34509, Fixes #34512

</details>

**Full Changelog**:
main...inflight/candidate
Reset patterns:
- global.json
- NuGet.config
- eng/Version.Details.xml
- eng/Versions.props
- eng/common/*
Resolved 7 Essentials PublicAPI.Unshipped.txt merge conflicts by combining
entries from both branches.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor Author

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

Or

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

@PureWeen
Copy link
Copy Markdown
Member

/azp run maui-pr-uitests

@PureWeen
Copy link
Copy Markdown
Member

/azp run maui-pr-devicetests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@PureWeen
Copy link
Copy Markdown
Member

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

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@PureWeen
Copy link
Copy Markdown
Member

  • all failures are pre-existing

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.