[Windows] Implement WinUI 3 MapControl handler using Azure Maps#34138
[Windows] Implement WinUI 3 MapControl handler using Azure Maps#34138kubaflo merged 10 commits intoinflight/currentfrom
Conversation
This adds a working Windows Maps handler implementation using the new WinUI 3
MapControl backed by Azure Maps (Windows App SDK 1.8+).
Features:
- MapHandler.Windows.cs: Full implementation with pin management and map interaction
- MapPinHandler.Windows.cs: MapIcon-based pin implementation with location support
- MapElementHandler.Windows.cs: Basic implementation (shapes have limited WinUI 3 support)
Authentication:
- Uses existing MapServiceToken infrastructure from Essentials
- Configure via: builder.ConfigureEssentials(e => e.UseMapServiceToken("YOUR_KEY"))
Platform Limitations (documented in XML docs):
- MapType: No programmatic switching; users can use built-in style picker
- IsTrafficEnabled: Not supported by basic MapControl (needs Azure Maps REST API)
- IsShowingUser: Not built-in (requires manual Geolocation API + custom MapIcon)
- IsZoomEnabled/IsScrollEnabled: Map to InteractiveControlsVisible (all-or-nothing)
- Polylines/Polygons/Circles: Limited support in MapElementsLayer
- Pin Labels/InfoWindows: Not supported on MapIcon directly
TODO (.NET 11):
- Add ConnectHandler/DisconnectHandler overrides to PublicAPI.Unshipped.txt
Testing:
- Core unit tests: 804 passed
- Controls unit tests: 5497 passed
- Windows TFM builds successfully
No public API changes.
Improvements to MapHandler.Windows.cs: - Add proper zoom level calculation using Spherical Mercator formula: zoom = log2(360 / degrees), using min of lat/lon for full span visibility - Add INotifyCollectionChanged support for dynamic pin add/remove - Add null guard in GetPinForMapIcon when VirtualView is null - Restructure XML docs into Supported/Unsupported sections for clarity - Remove verbose TODO comments (implementation is stable) - Clean up inline comments to be concise Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The WinUI 3 MapControl wraps Azure Maps in a WebView2 internally. Setting the Center dependency property does not visually navigate the map (microsoft-ui-xaml#9490). This commit works around the issue by accessing the internal WebView2 child and calling map.setCamera() via ExecuteScriptAsync with InvariantCulture number formatting. Changes: - MapHandler.Windows.cs: Rewrite MoveToRegion to use JS camera API with pending span queue for pre-WebView-ready calls - Sandbox MainPage: Add Maps demo with city navigation, pin management - Sandbox MauiProgram: Enable UseMauiMaps() with Azure Maps auth setup Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Implement three new features for the WinUI 3 Maps handler by accessing the Azure Maps JavaScript API through the MapControl's internal WebView2: - MapType: Street/Satellite/Hybrid via map.setStyle() - IsTrafficEnabled: Traffic flow and incidents via map.setTraffic() - IsScrollEnabled/IsZoomEnabled: Independent control via map.setUserInteraction() Refactor JS execution into reusable ExecuteJsAsync helper method. Apply initial property state on WebView2 NavigationCompleted. Update AppHostBuilderExtensions XML docs to reflect new capabilities. Update Sandbox demo with feature control buttons. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix Clear Pins: use individual MapElements.Remove() instead of Clear() which doesn't reliably refresh visuals in WinUI 3 MapControl - Remove dead INotifyCollectionChanged subscription code (IMap.Pins returns new List<> every call, so collection change events never fire) - Track VisibleRegion in MapMoveToRegion so pin placement uses current center - Add pin counter offset in Sandbox demo for visually distinguishable pins Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Moved layer setup/event wiring to ConnectHandler, cleanup to DisconnectHandler (matches iOS/Android handler pattern) - Added WebView2 discovery retry via LayoutUpdated event - Pin click no longer also fires map click (early return on pin match) - Improved exception handling with Trace.WriteLine for unexpected errors - Animated camera transitions (ease, 300ms) replacing jump - Updated PublicAPI.Unshipped.txt with new overrides Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…move dead code - Clear _pendingSpan in DisconnectHandler to prevent MapSpan retention - Remove unused RemovePinFromLayer method (pins are rebuilt via UpdatePins) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… API Move setup to CreatePlatformView and cleanup to Unloaded event handler. This avoids adding new PublicAPI entries, keeping the change backportable. Added TODO to refactor into ConnectHandler/DisconnectHandler for .NET 11. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR implements the Windows MapHandler using the WinUI 3 MapControl backed by Azure Maps, replacing all previous NotImplementedException stubs with functional implementations. This is a significant enhancement that brings Windows platform support for the Maps control without introducing new public API surface, making it suitable for a servicing release.
Changes:
- Full Windows MapHandler implementation with support for map navigation, styling, traffic, and user interaction controls via Azure Maps JavaScript API
- Pin management via MapIcon on MapElementsLayer with click event handling
- Documented no-op implementations for unsupported shape features (polylines, polygons, circles)
- Updated documentation reflecting Windows platform support and Azure Maps authentication requirements
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| MapHandler.Windows.cs | Complete implementation with WebView2 discovery, JavaScript API bridge, property mappers, and pin management |
| MapPinHandler.Windows.cs | Pin handler creating MapIcon platform elements with location mapping |
| MapElementHandler.Windows.cs | Documented no-op stubs for shape elements (unsupported by WinUI 3 MapElementsLayer) |
| AppHostBuilderExtensions.cs | Removed Windows exception, added comprehensive Azure Maps documentation, removed conditional compilation |
- Unsubscribe WebView2.NavigationCompleted in Unloaded cleanup to prevent memory leak when navigation never completes - Fix MapPins doc comment to accurately describe handler update mechanism Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jfversluis
left a comment
There was a problem hiding this comment.
Review Comments Addressed
Comment 1 (NavigationCompleted cleanup): ✅ Fixed in 05a6b18 — added _webView.NavigationCompleted -= OnWebViewNavigationCompleted\ in \OnMapControlUnloaded\ before nulling the reference. Good catch on the leak when navigation never completes.
Comment 2 (Clicked event behavior): This is intentional best-effort behavior. The \OnPinLayerElementClick\ handler is only wired to _pinsLayer, so it only fires for pin clicks. The fallthrough to \VirtualView.Clicked\ handles the edge case where a MapIcon exists but has no matching IMapPin (shouldn't happen in normal use). We can't get true background clicks from the WinUI 3 MapControl — this is the best approximation. The doc comment on the class already documents this limitation.
Comment 3 (MapPins doc): ✅ Fixed in 05a6b18 — updated to accurately describe the handler update mechanism.
🤖 AI Summary📊 Expand Full Review —
|
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #34138 | Full Windows Maps handler via WinUI 3 MapControl + Azure Maps JS API | ⏳ PENDING (Gate) | MapHandler.Windows.cs, MapPinHandler.Windows.cs, MapElementHandler.Windows.cs, AppHostBuilderExtensions.cs |
Feature implementation, no tests |
Issue: No linked issue — this is a new feature implementation
PR: #34138 - [Windows] Implement WinUI 3 MapControl handler using Azure Maps
Platforms Affected: Windows only
Files Changed: 4 implementation files, 0 test files
Prior Agent Review Found
A previous agent review was detected in the PR comments (MauiBot comment, 2026-03-25). That review:
- Pre-Flight: ✅ COMPLETE
- Gate:
⚠️ SKIPPED (no tests) - Try-Fix: ⏭️ SKIPPED (per user instruction - violates MANDATORY rule)
- Report: ✅ COMPLETE (Recommend APPROVE with suggestions)
Resuming from Phase 3 (Try-Fix) since it was improperly skipped.
Key Findings
-
Feature implementation: Replaces all
NotImplementedExceptionstubs in the Windows Maps handler with functional implementations backed by the WinUI 3MapControl(Azure Maps). PreviouslyCreatePlatformView()and all mappers threw. -
No new public API: All changes are behind existing interfaces (
IMap,IMapPin,IMapElement).PublicAPI.Unshipped.txtis empty — suitable for servicing release (.NET 10 SR6). -
Workaround for WinUI 3 bug:
MapControldependency properties (likeCenter) don't reliably propagate to the Azure Maps JS layer (microsoft-ui-xaml#9490). The handler works around this by:- Discovering the internal
WebView2child viaVisualTreeHelper.GetChild(_mapControl, 0) - Waiting for
NavigationCompletedbefore issuing any JS calls - Calling Azure Maps JS APIs directly (
map.setCamera(),map.setStyle(), etc.)
- Discovering the internal
-
Partial feature parity: IsShowingUser, polylines/polygons/circles, pin labels/InfoWindows, and background map clicks are documented no-ops — WinUI 3 MapControl limitations.
-
Copilot review addressed 3 issues:
- ✅
NavigationCompletedevent not unsubscribed during cleanup → Fixed in latest commit - ✅
VirtualView.Clickedfired incorrectly for all map element clicks → Acknowledged as intentional best-effort (documented limitation) - ✅
MapPinsdoc comment inaccurate about subscription mechanism → Fixed
- ✅
-
CI passes: All check runs completed with success (maui-pr, build, integration tests).
-
No tests included: PR does not add any UI tests, device tests, or unit tests. The changes are Windows-only platform handler code. No Map issue pages exist in TestCases.HostApp.
Architecture Details
CreatePlatformView()→ createsMapControl, subscribes toLoaded/Unloaded, creates_pinsLayerand_mapElementsLayerOnMapControlLoaded→ callsTryDiscoverWebView()which walksVisualTreeHelperto find the internalWebView2LayoutUpdatedretry loop ifWebView2not immediately availableOnWebViewNavigationCompleted→ marks_webViewReady = true, applies pending span, applies initial map state- Property mappers guard on
_webViewReadybefore executing JS; queue_pendingSpanif not yet ready UpdatePins()uses per-element removal (notClear()) to trigger proper WinUI 3 visual refreshOnMapControlUnloadedunsubscribes all events and nulls references
Changed Files
| File | Purpose |
|---|---|
src/Core/maps/src/Handlers/Map/MapHandler.Windows.cs |
Main handler implementation (430+ lines added) |
src/Core/maps/src/Handlers/MapPin/MapPinHandler.Windows.cs |
Pin handler via MapIcon |
src/Core/maps/src/Handlers/MapElement/MapElementHandler.Windows.cs |
No-op stubs for shapes |
src/Controls/Maps/src/AppHostBuilderExtensions.cs |
Updated docs, removed #if WINDOWS throw |
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #34138 | Full Windows Maps handler via WinUI 3 MapControl + Azure Maps JS API | ⏳ PENDING (Gate) | MapHandler.Windows.cs, MapPinHandler.Windows.cs, MapElementHandler.Windows.cs, AppHostBuilderExtensions.cs |
Feature implementation, no tests |
🚦 Gate — Test Verification
Gate Result: ⚠️ SKIPPED
Platform: Windows
Reason: No tests were detected in the PR's changed files. The Detect-TestsInDiff.ps1 script returned "No tests detected in changed files." The PR adds only platform implementation files with zero test files.
pwsh .github/scripts/shared/Detect-TestsInDiff.ps1 -PRNumber 34138
Output: No tests detected in changed files.
Tests Detected
| # | Type | Test Name | Filter |
|---|---|---|---|
| — | — | No tests in PR | — |
Verification
| Step | Expected | Actual | Result |
|---|---|---|---|
| Tests WITHOUT fix | FAIL | N/A (no tests) | |
| Tests WITH fix | PASS | N/A (no tests) |
Notes
The PR is a new feature implementation (Windows Maps handler). No automated tests were added to verify the behavior. Testing would require a physical Windows device or simulator with Azure Maps credentials. Recommend write-tests-agent to add coverage (UI tests or device tests for Windows Maps).
Fix Files (for reference)
src/Core/maps/src/Handlers/Map/MapHandler.Windows.cssrc/Core/maps/src/Handlers/MapPin/MapPinHandler.Windows.cssrc/Core/maps/src/Handlers/MapElement/MapElementHandler.Windows.cssrc/Controls/Maps/src/AppHostBuilderExtensions.cs
Gate Result: ⚠️ SKIPPED
Platform: Windows
Mode: Full Verification skipped — no tests detected
Reason: No tests were detected in the PR's changed files. The PR adds only platform implementation files with zero test files.
gh pr view 34138 --json files --jq '.files[].path' | grep -E "TestCases\.(HostApp|Shared\.Tests)"
Output: (no output — no test files in PR)
Additional check: No map-related test pages exist in src/Controls/tests/TestCases.HostApp/Issues/.
Tests Detected
| # | Type | Test Name | Filter |
|---|---|---|---|
| — | — | No tests in PR | — |
Verification
| Step | Expected | Actual | Result |
|---|---|---|---|
| Tests WITHOUT fix | FAIL | N/A (no tests) | |
| Tests WITH fix | PASS | N/A (no tests) |
Fix Files
src/Core/maps/src/Handlers/Map/MapHandler.Windows.cssrc/Core/maps/src/Handlers/MapPin/MapPinHandler.Windows.cssrc/Core/maps/src/Handlers/MapElement/MapElementHandler.Windows.cssrc/Controls/Maps/src/AppHostBuilderExtensions.cs
Notes
This is a new feature implementation PR. No automated tests were added. Testing would require:
- A Windows device with Windows App SDK 1.8+
- Azure Maps subscription key
- Map test infrastructure in TestCases.HostApp (does not exist)
Recommend write-tests-agent to add coverage after merge.
🔧 Fix — Analysis & Comparison
Gate Result: ⚠️ SKIPPED
Platform: Windows
Reason: No tests were detected in the PR's changed files. The Detect-TestsInDiff.ps1 script returned "No tests detected in changed files." The PR adds only platform implementation files with zero test files.
pwsh .github/scripts/shared/Detect-TestsInDiff.ps1 -PRNumber 34138
Output: No tests detected in changed files.
Tests Detected
| # | Type | Test Name | Filter |
|---|---|---|---|
| — | — | No tests in PR | — |
Verification
| Step | Expected | Actual | Result |
|---|---|---|---|
| Tests WITHOUT fix | FAIL | N/A (no tests) | |
| Tests WITH fix | PASS | N/A (no tests) |
Notes
The PR is a new feature implementation (Windows Maps handler). No automated tests were added to verify the behavior. Testing would require a physical Windows device or simulator with Azure Maps credentials. Recommend write-tests-agent to add coverage (UI tests or device tests for Windows Maps).
Fix Files (for reference)
src/Core/maps/src/Handlers/Map/MapHandler.Windows.cssrc/Core/maps/src/Handlers/MapPin/MapPinHandler.Windows.cssrc/Core/maps/src/Handlers/MapElement/MapElementHandler.Windows.cssrc/Controls/Maps/src/AppHostBuilderExtensions.cs
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix (claude-opus-4.6) | Direct MapControl.Center/ZoomLevel XAML properties no JS/WebView2 introspection | BLOCKED | 4 files | Compiled. Sacrifices MapType/Traffic support. Simpler but less feature-complete. |
| 2 | try-fix (claude-sonnet-4.6) | CoreWebView2.WebMessageReceived + polling JS injection for map-ready message |
BLOCKED | 4 files | Compiled. Better readiness detection (JS-level, not page-load level). |
| 3 | try-fix (gpt-5.3-codex) | General Queue<string> for ALL pending JS commands (vs PR's single _pendingSpan) |
⚠ BLOCKED | 1 file | Compiled. More general buffers all operations, not just MoveToRegion. |
| 4 | try-fix (gemini-3-pro-preview) | TaskCompletionSource<bool> readiness pattern instead of boolean _webViewReady flag |
BLOCKED | 4 files | Compiled. MapControl.StyleSheet unavailable in WinUI 3 JS still needed. |
| 5 | try-fix (claude-opus-4.6, cross-poll) | Standalone WebView2 with Azure Maps JS SDK skip MapControl entirely | BLOCKED | 4 files | Compiled. No VisualTreeHelper fragility. Supports polylines/polygons/circles via JS. |
| PR | PR #34138 | WinUI 3 MapControl + VisualTreeHelper WebView2 discovery + NavigationCompleted + Azure Maps JS API | GATE SKIPPED | 4 files | Feature implementation, no tests |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| claude-opus-4.6 | 2 | Yes | Standalone WebView2 with Azure Maps JS SDK (ran as Attempt 5) |
| claude-sonnet-4.6 | 2 | Yes | atlas.Map.events.add('ready') via AddScriptToExecuteOnDocumentCreatedAsync |
| gpt-5.3-codex | 2 | Yes | MapControl.TrySetSceneAsync for MoveToRegion + LoadingStatusChanged readiness |
| gemini-3-pro-preview | 2 | Yes | Promise-based JS synchronization shifting readiness to WebView2 engine |
| claude-sonnet-4.6 | 3 | No | NO NEW IDEAS solution space exhausted at architectural level |
Exhausted: Yes all 5 attempts compiled successfully but blocked by missing Windows Map test infrastructure.
Selected Fix: PR #34138 Most feature-complete approach. All alternatives either sacrificed features (Attempt 1) or are architecturally equivalent alternatives. The PR handles edge cases (pending span, LayoutUpdated retry, per-element pin removal) and Copilot review issues were addressed. The standalone WebView2 approach (Attempt 5) is worth considering for .NET 11 for better feature parity (polylines, labels, background clicks).
📋 Report — Final Recommendation
✅ Final Recommendation: APPROVE (with suggestions)
Phase Status
| Phase | Status | Notes |
|---|---|---|
| Pre-Flight | ✅ COMPLETE | Feature PR, 4 implementation files, 0 tests, all CI green |
| Gate | No tests detected in PR diff | |
| Try-Fix | ⏭️ SKIPPED (per user instruction) | N/A |
| Report | ✅ COMPLETE |
Summary
PR #34138 implements the Windows Maps handler using the WinUI 3 MapControl backed by Azure Maps, replacing all previous NotImplementedException stubs. This is a high-quality, well-documented feature implementation with no new public API surface — suitable for a servicing release (.NET 10 SR6). All 27 CI checks pass. The main gap is the lack of automated tests.
Root Cause / Feature Context
The Windows Maps handler has historically thrown NotImplementedException for all operations. WinUI 3's MapControl now wraps Azure Maps, but has a known bug (microsoft-ui-xaml#9490) where Center and other dependency properties don't reliably propagate to the Azure Maps JS layer. The PR works around this by:
- Discovering the internal
WebView2child viaVisualTreeHelper.GetChild() - Waiting for
NavigationCompletedbefore issuing any JS calls - Calling Azure Maps JS APIs directly (
map.setCamera(),map.setStyle(), etc.)
Fix Quality
Strengths:
- ✅ Thorough XML documentation with platform limitations clearly stated
- ✅ Proper event cleanup in
OnMapControlUnloaded(including theNavigationCompletedfix from Copilot review) - ✅ Correct WebView2 initialization sequencing with
_pendingSpanqueue forMoveToRegionbefore ready - ✅ Individual
MapIconremoval (notClear()) to work around WinUI 3 rendering bug — well-commented - ✅
CalculateZoomcorrectly uses Spherical Mercator log2 formula withMath.Clamp(0, 24) - ✅
InvariantCultureused when formatting JS coordinates — avoids locale comma-vs-dot issues - ✅ No new public API surface (clean for servicing)
- ✅ All CI checks pass (maui-pr, debug/release builds, integration tests)
Issues and Suggestions:
🟡 Issue 1: MapIcon.Title not mapped from IMapPin.Label
MapPinHandler.MapLabel is a documented no-op. However, WinUI 3's MapIcon does have a Title property that renders as a visible label on the map. This is a missed opportunity — the PR could at minimum map pin.Label to mapIcon.Title.
The class docs claim "MapIcon has no label or info window support" but that's inaccurate for Title. The Title shows a tooltip-style label next to the pin icon.
Suggested fix in MapPinHandler.MapLabel:
public static void MapLabel(IMapPinHandler handler, IMapPin mapPin)
{
if (handler.PlatformView is MapIcon mapIcon)
mapIcon.Title = mapPin.Label ?? string.Empty;
}And in AddPinToLayer():
var mapIcon = new MapIcon
{
Location = ...,
Title = pin.Label ?? string.Empty
};🟡 Issue 2: _mapElementsLayer is dead code
_mapElementsLayer is created, added to the map, and cleaned up — but never populated. MapElements mapper is a no-op (MapElementsLayer shapes unsupported). The empty layer has no functional impact but adds confusion. Consider removing it entirely, or adding a comment explaining it's a placeholder for future shape support.
🟡 Issue 3: OnPinLayerElementClick fires VirtualView.Clicked for unmatched MapIcons
When a MapIcon is clicked but has no matching IMapPin (e.g., if the VirtualView was updated without the icon being removed), it falls through to VirtualView.Clicked. This is technically incorrect (Clicked is for background map taps) but is noted in the class docs as a platform limitation. The comment ("shouldn't happen in normal use") is accurate, but a defensive return statement would be cleaner:
// Current: falls through to VirtualView.Clicked for unmatched icons
// Consider: just return silently if a MapIcon exists but has no matching pinℹ️ Observation: No tests
This is a new feature with zero test coverage (confirmed by Detect-TestsInDiff.ps1). For a feature affecting the Windows Maps control, some form of test coverage would be valuable:
- Device tests (
Controls.DeviceTestsWindows): Test that handlers initialize without throwing, properties map correctly - UI tests: Validate the map renders and responds to property changes
The PR description notes Azure Maps credentials are needed, which complicates automated testing. However, a CreatePlatformView() smoke test and property mapper unit tests are feasible without credentials.
Recommendation: Accept the PR now (given it's a feature that previously threw on all calls), but open a follow-up to add test coverage.
Architecture Notes
- The WebView2 discovery approach (
VisualTreeHelper.GetChild(_mapControl, 0)) is fragile — depends on internal WinUI 3 tree structure. TheLayoutUpdatedretry loop mitigates timing issues, but a future WinUI 3 version changing the internal structure would silently break all JS-based operations. Should be monitored. - The TODO comment for .NET 11 (refactor to
ConnectHandler/DisconnectHandler) is appropriately deferred to avoid public API churn in a servicing release. _webViewReadyis a plainboolfield. All MAUI handlers execute on the UI thread, so no volatile/locking needed — correct.
Selected Fix: PR #34138
The PR's fix is the only fix candidate. No alternatives explored (Phase 3 skipped per user instruction).
✅ Final Recommendation: APPROVE (with suggestions)
Phase Status
| Phase | Status | Notes |
|---|---|---|
| Pre-Flight | ✅ COMPLETE | Feature PR, 4 implementation files, 0 tests, CI green, prior review imported |
| Gate | No tests in PR diff — no Windows Map test infrastructure exists | |
| Try-Fix | ✅ COMPLETE | 5 attempts (4 models + 1 cross-poll), all BLOCKED by same constraint (no tests) |
| Report | ✅ COMPLETE |
Summary
PR #34138 implements the Windows Maps handler using the WinUI 3 MapControl backed by Azure Maps, replacing all previous NotImplementedException stubs. This is a well-documented feature implementation with no new public API surface — suitable for the .NET 10 SR6 servicing release. All CI checks pass. The main gap is the lack of automated tests, which is a known constraint (Azure Maps credentials required).
Try-Fix exhausted all architectural approaches: 5 independent implementations were explored (direct XAML properties, JS WebMessageReceived polling, general command queue, TaskCompletionSource readiness, and standalone WebView2). All compiled successfully but were Blocked by the absence of Windows Map test infrastructure. The PR's JS/WebView2 approach is the most feature-complete option available.
Root Cause / Feature Context
The Windows Maps handler has historically thrown NotImplementedException for all operations. WinUI 3's MapControl wraps Azure Maps but has a known bug (microsoft-ui-xaml#9490) where Center and other dependency properties don't reliably propagate to the Azure Maps JS layer. The PR works around this by:
- Discovering the internal
WebView2child viaVisualTreeHelper.GetChild(_mapControl, 0) - Waiting for
NavigationCompletedbefore issuing any JS calls - Calling Azure Maps JS APIs directly (
map.setCamera(),map.setStyle(), etc.)
Fix Quality
Strengths:
- ✅ All
NotImplementedExceptionstubs replaced with functional implementations - ✅ Thorough XML documentation with platform limitations clearly stated
- ✅ Proper event cleanup in
OnMapControlUnloaded(includingNavigationCompletedfix from Copilot review) - ✅
_pendingSpanqueue forMoveToRegioncalls before WebView is ready - ✅ Individual
MapIconremoval (notClear()) to work around WinUI 3 rendering bug — well-commented - ✅
CalculateZoomcorrectly uses Spherical Mercator log2 formula withMath.Clamp(0, 24) - ✅
InvariantCultureused when formatting JS coordinates — avoids locale comma-vs-dot issues - ✅ No new public API surface (clean for servicing)
- ✅ All CI checks pass
- ✅ Three Copilot review comments addressed in subsequent commit
Issues and Suggestions:
🟡 Issue 1: MapIcon.Title not mapped from IMapPin.Label
MapPinHandler.MapLabel is documented as a no-op. However, WinUI 3's MapIcon does have a Title property that renders as a visible label. The doc comment claims "MapIcon does not have a built-in label property" — this is inaccurate. Title shows a tooltip-style label next to the pin.
Suggested fix:
public static void MapLabel(IMapPinHandler handler, IMapPin mapPin)
{
if (handler.PlatformView is MapIcon mapIcon)
mapIcon.Title = mapPin.Label ?? string.Empty;
}And in CreatePlatformElement(), initialize Title = VirtualView.Label ?? string.Empty.
🟡 Issue 2: _pendingSpan only queues MoveToRegion — other state is silently lost
If MapType, IsTrafficEnabled, or IsScrollEnabled/IsZoomEnabled are set before the WebView is ready, they are silently discarded (guards return early). Only MoveToRegion is queued via _pendingSpan. Try-Fix Attempt 3 explored a general Queue<string> approach that would queue ALL pending JS commands — this is worth noting as an improvement.
The current behavior is acceptable for a servicing release (initial state is applied in OnWebViewNavigationCompleted), but worth documenting.
🟡 Issue 3: _mapElementsLayer is dead code
Created, added to the map, cleaned up — but never populated. MapElements mapper is a no-op. Adds confusion. Consider removing entirely, or adding a comment: // Placeholder for future shape support via Azure Maps Web SDK.
ℹ️ Architectural Note: Standalone WebView2 for .NET 11
Try-Fix Attempt 5 explored using a standalone WebView2 (skipping MapControl entirely) loaded with the Azure Maps Web SDK. This would:
- Eliminate the fragile
VisualTreeHelper.GetChild()dependency on WinUI 3 internals - Enable full Azure Maps JS support: polylines, polygons, circles, pin labels, info windows, background clicks
- Better feature parity with iOS/Android implementations
This is worth considering as the .NET 11 refactor target already mentioned in the PR's TODO comment.
Try-Fix Summary
| # | Approach | Result | Key Insight |
|---|---|---|---|
| 1 | Direct MapControl XAML properties | Simpler but sacrifices MapType/Traffic | |
| 2 | WebMessageReceived + JS polling | Better readiness detection than NavigationCompleted | |
| 3 | General Queue<string> for all JS |
More robust than _pendingSpan for pre-ready state |
|
| 4 | TaskCompletionSource<bool> readiness |
MapStyleSheet not available in WinUI 3 | |
| 5 | Standalone WebView2 + Azure Maps JS | Best long-term architecture; enables full feature parity |
All attempts blocked by the same constraint: no Windows Map tests exist in TestCases.HostApp/Issues/. The solution space is architecturally exhausted.
Selected Fix: PR #34138 — Original PR is the most feature-complete approach that avoids API changes. Compile-verified by 5 independent alternative approaches.
Selected Fix: PR #34138
Code Review SummaryMaps support for Windows — WinUI 3 MapControl handler using Azure Maps JS API via internal WebView2 discovery. No new public API confirmed. Well-documented extension points. Findings
Overall Assessment✅ Looks good — well-implemented, well-documented. Non-blocking suggestions above. The Review performed by Copilot CLI |
> [!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 Implements the Windows Maps handler using the new WinUI 3 `MapControl` (Windows App SDK 1.8+), which is backed by Azure Maps. Previously, all Windows `MapHandler` methods threw `NotImplementedException`. **No new public API surface** — this change only provides platform implementations behind already-shipped APIs. `PublicAPI.Unshipped.txt` is empty. This makes it suitable for a servicing release. ## What's implemented | Feature | Status | Implementation | |---------|--------|----------------| | MoveToRegion | ✅ | `map.setCamera()` via WebView2 JS (workaround for [microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)) | | MapType (Street/Satellite/Hybrid) | ✅ | `map.setStyle()` via WebView2 JS | | IsTrafficEnabled | ✅ | `map.setTraffic()` via WebView2 JS | | IsScrollEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | IsZoomEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | Pins (add/clear/click) | ✅ | `MapIcon` on `MapElementsLayer` | | Animated navigation | ✅ | Ease animation (300ms) | ## What's NOT implemented (no feature parity) These features are **no-op** on Windows due to WinUI 3 `MapControl` limitations. They don't throw — they silently do nothing, matching the pattern other platforms use for unsupported features. | Feature | Reason | |---------|--------| | IsShowingUser | No built-in user location display | | Polylines/Polygons/Circles | `MapElementsLayer` only supports `MapIcon` | | Pin Labels/InfoWindows | `MapIcon` has no label or info window support | | Map background click | `MapElementClick` only fires for `MapElement` clicks | ## Architecture The WinUI 3 `MapControl` internally wraps Azure Maps in a `WebView2`. Several dependency properties (like `Center`) don't reliably propagate to the JS layer ([microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)). This handler works around that by: 1. Discovering the internal `WebView2` child via `VisualTreeHelper.GetChild()` 2. Waiting for `NavigationCompleted` to know Azure Maps JS is ready 3. Calling Azure Maps JS APIs directly (`map.setCamera()`, `map.setStyle()`, etc.) ## Authentication Uses the existing Essentials pattern — no new API needed: ```csharp builder.ConfigureEssentials(e => e.UseMapServiceToken("YOUR_AZURE_MAPS_KEY")); ``` Get a key from the [Azure Portal](https://portal.azure.com) → Azure Maps account → Authentication. ## Files changed - `MapHandler.Windows.cs` — Full handler implementation (was all `NotImplementedException`) - `MapPinHandler.Windows.cs` — Pin handling via `MapIcon` - `MapElementHandler.Windows.cs` — Documented no-op stubs for shapes - `AppHostBuilderExtensions.cs` — Updated XML docs to reflect Windows support ## TODO for .NET 11 Refactor setup/cleanup into `ConnectHandler`/`DisconnectHandler` overrides to match iOS/Android pattern (avoided here to prevent new PublicAPI entries). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…et#34138) > [!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 Implements the Windows Maps handler using the new WinUI 3 `MapControl` (Windows App SDK 1.8+), which is backed by Azure Maps. Previously, all Windows `MapHandler` methods threw `NotImplementedException`. **No new public API surface** — this change only provides platform implementations behind already-shipped APIs. `PublicAPI.Unshipped.txt` is empty. This makes it suitable for a servicing release. ## What's implemented | Feature | Status | Implementation | |---------|--------|----------------| | MoveToRegion | ✅ | `map.setCamera()` via WebView2 JS (workaround for [microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)) | | MapType (Street/Satellite/Hybrid) | ✅ | `map.setStyle()` via WebView2 JS | | IsTrafficEnabled | ✅ | `map.setTraffic()` via WebView2 JS | | IsScrollEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | IsZoomEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | Pins (add/clear/click) | ✅ | `MapIcon` on `MapElementsLayer` | | Animated navigation | ✅ | Ease animation (300ms) | ## What's NOT implemented (no feature parity) These features are **no-op** on Windows due to WinUI 3 `MapControl` limitations. They don't throw — they silently do nothing, matching the pattern other platforms use for unsupported features. | Feature | Reason | |---------|--------| | IsShowingUser | No built-in user location display | | Polylines/Polygons/Circles | `MapElementsLayer` only supports `MapIcon` | | Pin Labels/InfoWindows | `MapIcon` has no label or info window support | | Map background click | `MapElementClick` only fires for `MapElement` clicks | ## Architecture The WinUI 3 `MapControl` internally wraps Azure Maps in a `WebView2`. Several dependency properties (like `Center`) don't reliably propagate to the JS layer ([microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)). This handler works around that by: 1. Discovering the internal `WebView2` child via `VisualTreeHelper.GetChild()` 2. Waiting for `NavigationCompleted` to know Azure Maps JS is ready 3. Calling Azure Maps JS APIs directly (`map.setCamera()`, `map.setStyle()`, etc.) ## Authentication Uses the existing Essentials pattern — no new API needed: ```csharp builder.ConfigureEssentials(e => e.UseMapServiceToken("YOUR_AZURE_MAPS_KEY")); ``` Get a key from the [Azure Portal](https://portal.azure.com) → Azure Maps account → Authentication. ## Files changed - `MapHandler.Windows.cs` — Full handler implementation (was all `NotImplementedException`) - `MapPinHandler.Windows.cs` — Pin handling via `MapIcon` - `MapElementHandler.Windows.cs` — Documented no-op stubs for shapes - `AppHostBuilderExtensions.cs` — Updated XML docs to reflect Windows support ## TODO for .NET 11 Refactor setup/cleanup into `ConnectHandler`/`DisconnectHandler` overrides to match iOS/Android pattern (avoided here to prevent new PublicAPI entries). --------- Co-authored-by: Copilot <223556219+Copilot@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 <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 Implements the Windows Maps handler using the new WinUI 3 `MapControl` (Windows App SDK 1.8+), which is backed by Azure Maps. Previously, all Windows `MapHandler` methods threw `NotImplementedException`. **No new public API surface** — this change only provides platform implementations behind already-shipped APIs. `PublicAPI.Unshipped.txt` is empty. This makes it suitable for a servicing release. ## What's implemented | Feature | Status | Implementation | |---------|--------|----------------| | MoveToRegion | ✅ | `map.setCamera()` via WebView2 JS (workaround for [microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)) | | MapType (Street/Satellite/Hybrid) | ✅ | `map.setStyle()` via WebView2 JS | | IsTrafficEnabled | ✅ | `map.setTraffic()` via WebView2 JS | | IsScrollEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | IsZoomEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | Pins (add/clear/click) | ✅ | `MapIcon` on `MapElementsLayer` | | Animated navigation | ✅ | Ease animation (300ms) | ## What's NOT implemented (no feature parity) These features are **no-op** on Windows due to WinUI 3 `MapControl` limitations. They don't throw — they silently do nothing, matching the pattern other platforms use for unsupported features. | Feature | Reason | |---------|--------| | IsShowingUser | No built-in user location display | | Polylines/Polygons/Circles | `MapElementsLayer` only supports `MapIcon` | | Pin Labels/InfoWindows | `MapIcon` has no label or info window support | | Map background click | `MapElementClick` only fires for `MapElement` clicks | ## Architecture The WinUI 3 `MapControl` internally wraps Azure Maps in a `WebView2`. Several dependency properties (like `Center`) don't reliably propagate to the JS layer ([microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)). This handler works around that by: 1. Discovering the internal `WebView2` child via `VisualTreeHelper.GetChild()` 2. Waiting for `NavigationCompleted` to know Azure Maps JS is ready 3. Calling Azure Maps JS APIs directly (`map.setCamera()`, `map.setStyle()`, etc.) ## Authentication Uses the existing Essentials pattern — no new API needed: ```csharp builder.ConfigureEssentials(e => e.UseMapServiceToken("YOUR_AZURE_MAPS_KEY")); ``` Get a key from the [Azure Portal](https://portal.azure.com) → Azure Maps account → Authentication. ## Files changed - `MapHandler.Windows.cs` — Full handler implementation (was all `NotImplementedException`) - `MapPinHandler.Windows.cs` — Pin handling via `MapIcon` - `MapElementHandler.Windows.cs` — Documented no-op stubs for shapes - `AppHostBuilderExtensions.cs` — Updated XML docs to reflect Windows support ## TODO for .NET 11 Refactor setup/cleanup into `ConnectHandler`/`DisconnectHandler` overrides to match iOS/Android pattern (avoided here to prevent new PublicAPI entries). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…et#34138) > [!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 Implements the Windows Maps handler using the new WinUI 3 `MapControl` (Windows App SDK 1.8+), which is backed by Azure Maps. Previously, all Windows `MapHandler` methods threw `NotImplementedException`. **No new public API surface** — this change only provides platform implementations behind already-shipped APIs. `PublicAPI.Unshipped.txt` is empty. This makes it suitable for a servicing release. ## What's implemented | Feature | Status | Implementation | |---------|--------|----------------| | MoveToRegion | ✅ | `map.setCamera()` via WebView2 JS (workaround for [microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)) | | MapType (Street/Satellite/Hybrid) | ✅ | `map.setStyle()` via WebView2 JS | | IsTrafficEnabled | ✅ | `map.setTraffic()` via WebView2 JS | | IsScrollEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | IsZoomEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | Pins (add/clear/click) | ✅ | `MapIcon` on `MapElementsLayer` | | Animated navigation | ✅ | Ease animation (300ms) | ## What's NOT implemented (no feature parity) These features are **no-op** on Windows due to WinUI 3 `MapControl` limitations. They don't throw — they silently do nothing, matching the pattern other platforms use for unsupported features. | Feature | Reason | |---------|--------| | IsShowingUser | No built-in user location display | | Polylines/Polygons/Circles | `MapElementsLayer` only supports `MapIcon` | | Pin Labels/InfoWindows | `MapIcon` has no label or info window support | | Map background click | `MapElementClick` only fires for `MapElement` clicks | ## Architecture The WinUI 3 `MapControl` internally wraps Azure Maps in a `WebView2`. Several dependency properties (like `Center`) don't reliably propagate to the JS layer ([microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)). This handler works around that by: 1. Discovering the internal `WebView2` child via `VisualTreeHelper.GetChild()` 2. Waiting for `NavigationCompleted` to know Azure Maps JS is ready 3. Calling Azure Maps JS APIs directly (`map.setCamera()`, `map.setStyle()`, etc.) ## Authentication Uses the existing Essentials pattern — no new API needed: ```csharp builder.ConfigureEssentials(e => e.UseMapServiceToken("YOUR_AZURE_MAPS_KEY")); ``` Get a key from the [Azure Portal](https://portal.azure.com) → Azure Maps account → Authentication. ## Files changed - `MapHandler.Windows.cs` — Full handler implementation (was all `NotImplementedException`) - `MapPinHandler.Windows.cs` — Pin handling via `MapIcon` - `MapElementHandler.Windows.cs` — Documented no-op stubs for shapes - `AppHostBuilderExtensions.cs` — Updated XML docs to reflect Windows support ## TODO for .NET 11 Refactor setup/cleanup into `ConnectHandler`/`DisconnectHandler` overrides to match iOS/Android pattern (avoided here to prevent new PublicAPI entries). --------- Co-authored-by: Copilot <223556219+Copilot@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 <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 Implements the Windows Maps handler using the new WinUI 3 `MapControl` (Windows App SDK 1.8+), which is backed by Azure Maps. Previously, all Windows `MapHandler` methods threw `NotImplementedException`. **No new public API surface** — this change only provides platform implementations behind already-shipped APIs. `PublicAPI.Unshipped.txt` is empty. This makes it suitable for a servicing release. ## What's implemented | Feature | Status | Implementation | |---------|--------|----------------| | MoveToRegion | ✅ | `map.setCamera()` via WebView2 JS (workaround for [microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)) | | MapType (Street/Satellite/Hybrid) | ✅ | `map.setStyle()` via WebView2 JS | | IsTrafficEnabled | ✅ | `map.setTraffic()` via WebView2 JS | | IsScrollEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | IsZoomEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | Pins (add/clear/click) | ✅ | `MapIcon` on `MapElementsLayer` | | Animated navigation | ✅ | Ease animation (300ms) | ## What's NOT implemented (no feature parity) These features are **no-op** on Windows due to WinUI 3 `MapControl` limitations. They don't throw — they silently do nothing, matching the pattern other platforms use for unsupported features. | Feature | Reason | |---------|--------| | IsShowingUser | No built-in user location display | | Polylines/Polygons/Circles | `MapElementsLayer` only supports `MapIcon` | | Pin Labels/InfoWindows | `MapIcon` has no label or info window support | | Map background click | `MapElementClick` only fires for `MapElement` clicks | ## Architecture The WinUI 3 `MapControl` internally wraps Azure Maps in a `WebView2`. Several dependency properties (like `Center`) don't reliably propagate to the JS layer ([microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)). This handler works around that by: 1. Discovering the internal `WebView2` child via `VisualTreeHelper.GetChild()` 2. Waiting for `NavigationCompleted` to know Azure Maps JS is ready 3. Calling Azure Maps JS APIs directly (`map.setCamera()`, `map.setStyle()`, etc.) ## Authentication Uses the existing Essentials pattern — no new API needed: ```csharp builder.ConfigureEssentials(e => e.UseMapServiceToken("YOUR_AZURE_MAPS_KEY")); ``` Get a key from the [Azure Portal](https://portal.azure.com) → Azure Maps account → Authentication. ## Files changed - `MapHandler.Windows.cs` — Full handler implementation (was all `NotImplementedException`) - `MapPinHandler.Windows.cs` — Pin handling via `MapIcon` - `MapElementHandler.Windows.cs` — Documented no-op stubs for shapes - `AppHostBuilderExtensions.cs` — Updated XML docs to reflect Windows support ## TODO for .NET 11 Refactor setup/cleanup into `ConnectHandler`/`DisconnectHandler` overrides to match iOS/Android pattern (avoided here to prevent new PublicAPI entries). --------- Co-authored-by: Copilot <223556219+Copilot@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 <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 Implements the Windows Maps handler using the new WinUI 3 `MapControl` (Windows App SDK 1.8+), which is backed by Azure Maps. Previously, all Windows `MapHandler` methods threw `NotImplementedException`. **No new public API surface** — this change only provides platform implementations behind already-shipped APIs. `PublicAPI.Unshipped.txt` is empty. This makes it suitable for a servicing release. ## What's implemented | Feature | Status | Implementation | |---------|--------|----------------| | MoveToRegion | ✅ | `map.setCamera()` via WebView2 JS (workaround for [microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)) | | MapType (Street/Satellite/Hybrid) | ✅ | `map.setStyle()` via WebView2 JS | | IsTrafficEnabled | ✅ | `map.setTraffic()` via WebView2 JS | | IsScrollEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | IsZoomEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | Pins (add/clear/click) | ✅ | `MapIcon` on `MapElementsLayer` | | Animated navigation | ✅ | Ease animation (300ms) | ## What's NOT implemented (no feature parity) These features are **no-op** on Windows due to WinUI 3 `MapControl` limitations. They don't throw — they silently do nothing, matching the pattern other platforms use for unsupported features. | Feature | Reason | |---------|--------| | IsShowingUser | No built-in user location display | | Polylines/Polygons/Circles | `MapElementsLayer` only supports `MapIcon` | | Pin Labels/InfoWindows | `MapIcon` has no label or info window support | | Map background click | `MapElementClick` only fires for `MapElement` clicks | ## Architecture The WinUI 3 `MapControl` internally wraps Azure Maps in a `WebView2`. Several dependency properties (like `Center`) don't reliably propagate to the JS layer ([microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)). This handler works around that by: 1. Discovering the internal `WebView2` child via `VisualTreeHelper.GetChild()` 2. Waiting for `NavigationCompleted` to know Azure Maps JS is ready 3. Calling Azure Maps JS APIs directly (`map.setCamera()`, `map.setStyle()`, etc.) ## Authentication Uses the existing Essentials pattern — no new API needed: ```csharp builder.ConfigureEssentials(e => e.UseMapServiceToken("YOUR_AZURE_MAPS_KEY")); ``` Get a key from the [Azure Portal](https://portal.azure.com) → Azure Maps account → Authentication. ## Files changed - `MapHandler.Windows.cs` — Full handler implementation (was all `NotImplementedException`) - `MapPinHandler.Windows.cs` — Pin handling via `MapIcon` - `MapElementHandler.Windows.cs` — Documented no-op stubs for shapes - `AppHostBuilderExtensions.cs` — Updated XML docs to reflect Windows support ## TODO for .NET 11 Refactor setup/cleanup into `ConnectHandler`/`DisconnectHandler` overrides to match iOS/Android pattern (avoided here to prevent new PublicAPI entries). --------- Co-authored-by: Copilot <223556219+Copilot@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 <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 Implements the Windows Maps handler using the new WinUI 3 `MapControl` (Windows App SDK 1.8+), which is backed by Azure Maps. Previously, all Windows `MapHandler` methods threw `NotImplementedException`. **No new public API surface** — this change only provides platform implementations behind already-shipped APIs. `PublicAPI.Unshipped.txt` is empty. This makes it suitable for a servicing release. ## What's implemented | Feature | Status | Implementation | |---------|--------|----------------| | MoveToRegion | ✅ | `map.setCamera()` via WebView2 JS (workaround for [microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)) | | MapType (Street/Satellite/Hybrid) | ✅ | `map.setStyle()` via WebView2 JS | | IsTrafficEnabled | ✅ | `map.setTraffic()` via WebView2 JS | | IsScrollEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | IsZoomEnabled | ✅ | `map.setUserInteraction()` via WebView2 JS | | Pins (add/clear/click) | ✅ | `MapIcon` on `MapElementsLayer` | | Animated navigation | ✅ | Ease animation (300ms) | ## What's NOT implemented (no feature parity) These features are **no-op** on Windows due to WinUI 3 `MapControl` limitations. They don't throw — they silently do nothing, matching the pattern other platforms use for unsupported features. | Feature | Reason | |---------|--------| | IsShowingUser | No built-in user location display | | Polylines/Polygons/Circles | `MapElementsLayer` only supports `MapIcon` | | Pin Labels/InfoWindows | `MapIcon` has no label or info window support | | Map background click | `MapElementClick` only fires for `MapElement` clicks | ## Architecture The WinUI 3 `MapControl` internally wraps Azure Maps in a `WebView2`. Several dependency properties (like `Center`) don't reliably propagate to the JS layer ([microsoft-ui-xaml#9490](microsoft/microsoft-ui-xaml#9490)). This handler works around that by: 1. Discovering the internal `WebView2` child via `VisualTreeHelper.GetChild()` 2. Waiting for `NavigationCompleted` to know Azure Maps JS is ready 3. Calling Azure Maps JS APIs directly (`map.setCamera()`, `map.setStyle()`, etc.) ## Authentication Uses the existing Essentials pattern — no new API needed: ```csharp builder.ConfigureEssentials(e => e.UseMapServiceToken("YOUR_AZURE_MAPS_KEY")); ``` Get a key from the [Azure Portal](https://portal.azure.com) → Azure Maps account → Authentication. ## Files changed - `MapHandler.Windows.cs` — Full handler implementation (was all `NotImplementedException`) - `MapPinHandler.Windows.cs` — Pin handling via `MapIcon` - `MapElementHandler.Windows.cs` — Documented no-op stubs for shapes - `AppHostBuilderExtensions.cs` — Updated XML docs to reflect Windows support ## TODO for .NET 11 Refactor setup/cleanup into `ConnectHandler`/`DisconnectHandler` overrides to match iOS/Android pattern (avoided here to prevent new PublicAPI entries). --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
## Blazor - Fix: Filter precompressed RCL assets from MAUI Blazor Hybrid APKs by @mattleibow in #33917 <details> <summary>🔧 Fixes</summary> - [.NET MAUI Blazor Hybrid App should not precompress assets](#33773) </details> - [Windows] Fix for Runtime error when closing external window with WPF Webview Control by @BagavathiPerumal in #34006 <details> <summary>🔧 Fixes</summary> - [Runtime error when closing external window with WPF Webview Control](#32944) </details> ## Button - [Android] ImageButton CornerRadius not being applied - fix by @kubaflo in #30074 <details> <summary>🔧 Fixes</summary> - [ImageButton CornerRadius not being applied on Android](#23854) </details> - Fix Disabled visual state ignored when Button has locally-set BackgroundColor/TextColor by @Dhivya-SF4094 in #34444 <details> <summary>🔧 Fixes</summary> - [[regression/9.0] VisualState "Disabled" is not properly applied for Button with custom appearance](#34363) </details> ## CollectionView - Fix CollectionView grid spacing updates for first row and column by @KarthikRajaKalaimani in #34527 <details> <summary>🔧 Fixes</summary> - [[MAUI] I2_Vertical grid for horizontal Item Spacing and Vertical Item Spacing - horizontally updating the spacing only applies to the second column](#34257) </details> - Fix CollectionView record struct selection on Windows by @jeremy-visionaid in #33488 - [Android] Ensure disconnected ItemsViewHandler doesn't hold onto the items source by @filipnavara in #24610 <details> <summary>🔧 Fixes</summary> - [Crash on NullReferenceException with measurement cells in CollectionView](#24304) </details> - [Windows] Fixed VisualState Setters not working properly for CollectionView by @Dhivya-SF4094 in #27230 <details> <summary>🔧 Fixes</summary> - [VisualState Setters not working properly on Windows for a CollectionView](#27086) - [[regression/8.0.3] [Windows][CollectionView]Label Disappear when set Style in ContentPage.Resources](#19209) - [[Windows] Label style defined as ContentPage Resource doesn't propagate to CollectionView](#18701) </details> - [Windows] Fixed Margin doesn't work inside CollectionView EmptyView by @Dhivya-SF4094 in #29897 <details> <summary>🔧 Fixes</summary> - [Margin doesn't work inside CollectionView EmptyView](#8494) </details> - [Android, Windows] Fix CarouselView PreviousPosition/PreviousItem incorrect during animated ScrollTo() by @praveenkumarkarunanithi in #34570 <details> <summary>🔧 Fixes</summary> - [[Android] CurrentItemChangedEventArgs.PreviousItem and PositionChangedEventArgs.PreviousPosition Not Updating Correctly When Using ScrollTo or Setting Position](#29544) </details> - [iOS] CarouselView2: Update internal scroll indicators for compositional layout by @SubhikshaSf4851 in #33639 <details> <summary>🔧 Fixes</summary> - [[iOS] Horizontal Scroll Bar Not Visible on CarouselView (CV2)](#29390) </details> - [CarouselViewHandler2] Fir fox CurrentItem does not work when ItemSpacing is set by @SyedAbdulAzeemSF4852 in #32135 <details> <summary>🔧 Fixes</summary> - [[CarouselViewHandler2] CurrentItem does not work when ItemSpacing is set](#32048) </details> - [iOS] Fix for Incorrect Scroll in Loop Mode When CurrentItem Is Not Found in ItemsSource by @SyedAbdulAzeemSF4852 in #32141 <details> <summary>🔧 Fixes</summary> - [[Android & iOS] Setting an invalid CurrentItem causes scroll to last item in looped CarouselView](#32139) </details> - [Android] IndicatorView: Add TalkBack accessibility descriptions for indicators by @praveenkumarkarunanithi in #31775 <details> <summary>🔧 Fixes</summary> - [[Android] IndicatorView does not convey correct accessibility information](#31446) </details> - [iOS, macOS] Fixed CollectionView KeepLastItemInView Not Updating Correctly When Items Are Added Dynamically by @NanthiniMahalingam in #32191 <details> <summary>🔧 Fixes</summary> - [[.NET10] I9 - Scroll_Position - "KeepLastItemInView" does not keep the last item at the end of the displayed list when adding new items.](#31825) </details> - [Windows, Android] Resolved issue with dynamic Header/Footer reassignment in CollectionView. by @prakashKannanSf3972 in #28403 <details> <summary>🔧 Fixes</summary> - [[Windows, Android] Toggling Header/Footer in CollectionView Dynamically is not working](#27959) - [CollectionView HeaderTemplate and FooterTemplate are not displayed when ItemsSource is initially set to null](#28337) - [[Android] Header and Footer Not Visible in CollectionView When EmptyView is Selected First](#28351) </details> - [Android] Fix CollectionView inside disabled RefreshView blocks scroll by @Vignesh-SF3580 in #34702 <details> <summary>🔧 Fixes</summary> - [C6-The C6 page cannot scroll on Windows and Android platforms.](#34666) </details> - [Android] CollectionView: Fix SelectedItem visual state not applying when re-selecting same item by @KarthikRajaKalaimani in #31591 <details> <summary>🔧 Fixes</summary> - [CollectionView - SelectedItem visual state manager not working](#20062) </details> - [Windows] Fixed CollectionView.EmptyView can not be removed by setting it to Null by @Dhivya-SF4094 in #29487 <details> <summary>🔧 Fixes</summary> - [[Windows] CollectionView.EmptyView can not be removed by setting it to Null](#18657) - [[Windows] EmptyViewTemplate Not Working in CarouselView](#29463) - [EmptyViewTemplate does not do anything](#18551) - [[MAUI] I5_EmptyView - The data template selector cannot display the correct string.](#23330) </details> - [iOS] Support for IsSwipeEnabled on CarouselView2 by @kubaflo in #29996 <details> <summary>🔧 Fixes</summary> - [[iOS] IsSwipeEnabled Not Working on CarouselView (CV2)](#29391) </details> - [iOS, MacOS] Fixed FlowDirection not working on Header/Footer in CollectionView by @Dhivya-SF4094 in #32775 <details> <summary>🔧 Fixes</summary> - [[iOS, MacOS] FlowDirection not working on Header/Footer in CollectionView](#32771) </details> - [iOS] CollectionView: Fix drag-and-drop reordering into empty groups by @SuthiYuvaraj in #34151 <details> <summary>🔧 Fixes</summary> - [CollectionView Drag and Drop Reordering Can't Drop in Empty Group](#12008) </details> - [Android] CollectionView: Fix drag-and-drop reordering into empty groups by @SuthiYuvaraj in #31867 <details> <summary>🔧 Fixes</summary> - [CollectionView Drag and Drop Reordering Can't Drop in Empty Group](#12008) </details> - [iOS] Fix vertical CarouselView MandatorySingle snapping on iOS by @Vignesh-SF3580 in #34700 <details> <summary>🔧 Fixes</summary> - [CarouselView vertical snap points ignored on iOS with Microsoft.Maui.Controls v10.0.20 (regression from v9.0.120)](#33308) </details> - [iOS26] Fix CarouselView scrolling to wrong item when navigating to last item by @Vignesh-SF3580 in #34013 <details> <summary>🔧 Fixes</summary> - [[iOS 26] CarouselView does not scroll to the correct last item](#33770) </details> - Fixed the OnPlatform does not work for header property in Collection view by @NanthiniMahalingam in #28935 <details> <summary>🔧 Fixes</summary> - [OnPlatform does not work in Header of CollectionView](#25124) </details> - [Android] [Candidate branch] Fix VerifySelectedItemClearsOnNullAssignment, CollectionViewSelectionShouldClear, SelectedItemVisualIsCleared UI test failure on Android by @KarthikRajaKalaimani in #34928 ## DateTimePicker - [iOS] Fix for DatePicker FlowDirection Not Working on iOS by @SyedAbdulAzeemSF4852 in #30193 <details> <summary>🔧 Fixes</summary> - [[iOS] DatePicker FlowDirection Not Working on iOS](#30065) </details> ## Drawing - [Shapes] Line: Fix asymmetric Stretch.None path translation when right/bottom edge overflows by @NirmalKumarYuvaraj in #34385 <details> <summary>🔧 Fixes</summary> - [Line coordinates not computed correctly](#11404) - [Lines not drawing correctly](#26961) </details> - [Android] Fixed GraphicsView drawable is visible outside the canvas by @NirmalKumarYuvaraj in #28353 <details> <summary>🔧 Fixes</summary> - [[Android] GraphicsView, The drawn image can also be visible outside the canvas](#20834) </details> - Fixed Custom Drawable does not support binding by @NirmalKumarYuvaraj in #29442 <details> <summary>🔧 Fixes</summary> - [Custom IDrawable control does not databind to a model property when used inside a CollectionView ItemTemplate](#20991) </details> - Added a support for GradientBrushes on Shape.Stroke by @kubaflo in #22208 <details> <summary>🔧 Fixes</summary> - [GradientBrushes are not supported on Shape.Stroke](#21983) </details> ## Editor - Fixed Editor HorizontalTextAlignment does not update at run time by @NirmalKumarYuvaraj in #25129 <details> <summary>🔧 Fixes</summary> - [Editor HorizontalTextAlignment Does not Works.](#10987) - [[iOS/MacOs] Right-To-Left (RTL) alignment is not applied to Editor placeholder](#30052) </details> - [Windows] Fixed Entry Editor placeholder Text CharacterSpacing by @SubhikshaSf4851 in #30324 <details> <summary>🔧 Fixes</summary> - [[Windows] CharacterSpacing not applied to Placeholder text in Entry and Editor controls](#30071) </details> ## Entry - [Windows] Fix fo setting an Entry's Keyboard to Date causes it to be interpreted as a password input by @SyedAbdulAzeemSF4852 in #29344 <details> <summary>🔧 Fixes</summary> - [[Windows] Entry Keyboad-Type "Date" results in Password-Entry](#28975) </details> - [Android] Exception thrown when give more than 5000 characters to the Text property of Entry. by @KarthikRajaKalaimani in #30242 <details> <summary>🔧 Fixes</summary> - [Android crash when Entry has >5000 characters](#30144) </details> ## Essentials - Bump MonoApiToolsMSBuildTasksPackageVersion to 0.5.0 and ship Essentials.AI public APIs by @mattleibow via @Copilot in #34574 - [Mac] DeviceDisplay.KeepScreenOn not being respected on Mac OS by @HarishwaranVijayakumar in #32708 <details> <summary>🔧 Fixes</summary> - [[Mac Catalyst] DeviceDisplay.KeepScreenOn not being respected on Mac OS](#26059) </details> ## Flyoutpage - [Windows] FlyoutPage: update CollapseStyle at runtime by @devanathan-vaithiyanathan in #29927 <details> <summary>🔧 Fixes</summary> - [Flyout Page SetCollapseStyle doesn't have any change](#18200) </details> ## Gestures - [Android] Fix for TapGestureRecognizer doesn't fire by @HarishwaranVijayakumar in #34497 <details> <summary>🔧 Fixes</summary> - [[Android] TapGestureRecognizer doesn't fire](#5825) </details> ## Image - [Android] Fix Share.RequestAsync SecurityException on Android 10+ caused by missing ClipData by @HarishwaranVijayakumar in #34417 <details> <summary>🔧 Fixes</summary> - [[Bug] Share.RequestAsync throws java.lang.SecurityException (uid=1000) on Android 10+ due to missing intent.ClipData](#34370) </details> - [Windows]Fixed the MauiImage with logical name containing path issue by @sheiksyedm in #32864 <details> <summary>🔧 Fixes</summary> - [MauiImage with LogicalName containing path - is not working on Windows](#32356) </details> - [Android, Windows & iOS] Fix Downsize/ScaleImage to maintain aspect ratio and prevent upscaling by @SyedAbdulAzeemSF4852 in #30808 <details> <summary>🔧 Fixes</summary> - [[Android & Windows] In GraphicsView, the aspect ratio is not maintained when Downsize is called with both maxWidth and maxHeight](#30803) </details> ## Label - [iOS , macOS] Fixed Label text cropping when a width request is specified on the label inside a VerticalStackLayout with specified width request by @NanthiniMahalingam in #29166 <details> <summary>🔧 Fixes</summary> - [Label text gets cropped when a width request is specified on the label inside a VerticalStackLayout](#28660) - [[iOS] Label with a fixed WidthRequest has wrong height](#26644) </details> - [Android] Fix Label word wrapping clips text depending on alignment and layout options by @Dhivya-SF4094 in #34533 <details> <summary>🔧 Fixes</summary> - [Bug: Android Label word wrapping clips text depending on alignment and layout options](#34459) </details> - LineHeight and decorations for HTML Label - fix by @kubaflo in #31202 <details> <summary>🔧 Fixes</summary> - [LineHeight with HTML Label not working](#22193) - [lineheight is broken ](#22197) </details> - [iOS] Fix Label with TailTruncation not rendering after empty-to-non-empty text transition by @kubaflo in #34812 <details> <summary>🔧 Fixes</summary> - [Label with LineBreakMode="TailTruncation" does not render text if initial Text is null or empty on first render (iOS)](#34591) </details> ## Layout - [Android] Fix overflowing children clipped when parent Opacity < 1 by @SyedAbdulAzeemSF4852 in #34565 <details> <summary>🔧 Fixes</summary> - [Maui Android parent view inappropriately creates clipping mask when its opacity is less than 1, cropping out children](#22038) </details> - Fixed the FlexLayout reverse issue with the AlignContent by @Ahamed-Ali in #32134 <details> <summary>🔧 Fixes</summary> - [FlexLayout alignment issue when Wrap is set to Reverse and AlignContent is set to SpaceAround, SpaceBetween or SpaceEvenly](#31565) </details> - [iOS/Mac] Fixed BoxView in AbsoluteLayout did not return to its default AutoSize for Height and Width after reset by @Dhivya-SF4094 in #31648 <details> <summary>🔧 Fixes</summary> - [[iOS, Catalyst] BoxView in AbsoluteLayout does not return to default AutoSize for Height/Width after reset](#31496) </details> ## Map - [Windows] Implement WinUI 3 MapControl handler using Azure Maps by @jfversluis in #34138 ## Modal - [Android] PopToRootAsync for modal pages - improvements by @kubaflo in #26851 <details> <summary>🔧 Fixes</summary> - [Shell PopToRootAsync doesn't happen instantly - previous pages flash quickly. Only happens in NET 9](#26846) </details> - [Android] Fix HideSoftInputOnTapped doesn't work on Modal Pages by @HarishwaranVijayakumar in #34770 <details> <summary>🔧 Fixes</summary> - [HideSoftInputOnTapped doesn't work on Modal Pages](#34730) </details> ## Navigation - [iOS] Alert popup may be displayed on wrong window when modal page navigation is in progress - fix by @kubaflo in #31016 <details> <summary>🔧 Fixes</summary> - [Alert popup may be displayed on wrong window when modal page navigation is in progress on iOS/MacOS](#30970) </details> - [Android] Page: Fix OnNavigatedTo called twice when NavigationPage is FlyoutPage Detail by @KarthikRajaKalaimani in #31931 <details> <summary>🔧 Fixes</summary> - [NavigationPage and FlyoutPage both call OnNavigatedTo, so it is called twice](#23902) </details> ## Picker - Fixed the Picker didn't dismiss it when tapping outside on iOS and MacCatalyst platform. by @KarthikRajaKalaimani in #30067 <details> <summary>🔧 Fixes</summary> - [[regression/8.0.3] iOS Picker dismiss does not work when clicking outside of the Picker](#19168) </details> - [Windows] Fixed Picker items width wont resize back by @SubhikshaSf4851 in #33042 <details> <summary>🔧 Fixes</summary> - [Picker items width won't resize back when its container window gets resized down.](#32984) </details> ## RadioButton - Fix TalkBack not correctly narrating RadioButtons with Content by @SubhikshaSf4851 in #34521 <details> <summary>🔧 Fixes</summary> - [[Android] TalkBack does not correctly narrate RadioButtons with Content](#34322) </details> ## SafeArea - [Android] Fix SafeAreaShouldWorkOnAllShellTabs test failure on API 36 by @praveenkumarkarunanithi in #34239 ## ScrollView - [iOS] Preserve ScrollView offsets when Orientation changes to Neither by @Vignesh-SF3580 in #34672 <details> <summary>🔧 Fixes</summary> - [Incorrect implementation of ScrollView.Orientation](#34583) </details> ## Searchbar - [Android] Fix SearchBar text bleeding between instances after navigation by @SyedAbdulAzeemSF4852 in #34703 <details> <summary>🔧 Fixes</summary> - [MAUI Android: SearchBar copies content from one to the other](#20348) </details> - Fixed SearchBar CursorPosition and SelectionLength not updating when typing by @Dhivya-SF4094 in #34347 <details> <summary>🔧 Fixes</summary> - [SearchBar - CursorPosition and SelectionLength are not updated when the user types](#30779) </details> ## SearchBar - [Windows] Fixed SearchHandler issues by @Tamilarasan-Paranthaman in #29520 <details> <summary>🔧 Fixes</summary> - [[Windows] SearchHandler APIs are not functioning properly](#29493) </details> ## Shell - [iOS, Mac] Fix for Background set to Transparent doesn't have the same behavior as BackgroundColor Transparent by @HarishwaranVijayakumar in #32245 <details> <summary>🔧 Fixes</summary> - [Background set to Transparent doesn't have the same behavior as BackgroundColor = Transparent](#22769) </details> - [iOS] Fix App crash with NullReferenceException in ShellSectionRenderer by @devanathan-vaithiyanathan in #32109 <details> <summary>🔧 Fixes</summary> - [[iOS] App crash with NullReferenceException in ShellSectionRenderer](#31961) </details> - [Android] Fixed back button icon selection logic in ShellToolbarTracker by @kubaflo in #32080 <details> <summary>🔧 Fixes</summary> - [IconOverride in Shell.BackButtonBehavior does not work.](#32050) </details> - Fix TabBarIsVisible Not Updating Dynamically When Set on ShellContent by @Vignesh-SF3580 in #33090 <details> <summary>🔧 Fixes</summary> - [Shell.TabBarIsVisible is not updated dynamically at runtime](#32994) </details> - [iOS, macOS] Shell: Fix RTL flow direction for flyout, menu cells, tab bar, and Locked flyout position by @NanthiniMahalingam in #32701 <details> <summary>🔧 Fixes</summary> - [[iOS, Mac Catalyst] Shell Flyout and Content Do Not Fully Support RightToLeft (RTL)](#32419) </details> - [IOS] Inconsistent Resize Behavior for Header/Footer - fix by @kubaflo in #28713 <details> <summary>🔧 Fixes</summary> - [[IOS, Mac] Inconsistent Resize Behavior for Header/Footer](#26397) - [Enable Shell Flyout Header/Footer resize tests on iOS/Catalyst](#33501) </details> - [Android] Fix for SearchHandler retaining previous page SearchView data in pages within Shell sections by @BagavathiPerumal in #29545 <details> <summary>🔧 Fixes</summary> - [[Shell][Android] The truth is out there...but not on top tab search handlers](#8716) </details> - [Android] Fix empty space above TabBar after navigating back when TabBar visibility is toggled by @praveenkumarkarunanithi in #34324 <details> <summary>🔧 Fixes</summary> - [Empty space appears above TabBar after navigating back when TabBar visibility is toggled](#33703) - [Grid with SafeAreaEdges=Container has incorrect size when tab bar appears](#34256) </details> ## SwipeView - [Android] SwipeView: Use MeasureSpecMode.Exactly for SwipeItem layout to fix text visibility by @Ahamed-Ali in #27399 <details> <summary>🔧 Fixes</summary> - [[Android] Right SwipeView items are not visible in the SwipeView.](#27367) </details> - [Android] Prevent the tap that closes an open SwipeView from being propagated to children by @sjordanGSS in #24275 <details> <summary>🔧 Fixes</summary> - [Tapping to close a SwipeView will activate TapGestureRecognizers on .Content](#23921) </details> ## Switch - [iOS & Mac] Fix for SearchHandler retains previous page state when switching top tabs by @BagavathiPerumal in #34735 <details> <summary>🔧 Fixes</summary> - [[Shell] [iOS & Mac] SearchHandler retains previous page state when switching top tabs](#34693) </details> ## TabbedPage - [Android] Fixed NullReferenceException in app with TabBar after returning from minimized state by @NirmalKumarYuvaraj in #34779 <details> <summary>🔧 Fixes</summary> - [NullReferenceException in app with TabBar after returning from minimized state](#34720) </details> ## Titlebar - Fixed BindingContext of the Window TitleBar is not being passed on to its child content. by @NirmalKumarYuvaraj in #30080 <details> <summary>🔧 Fixes</summary> - [The BindingContext of the Window TitleBar is not being passed on to its child content.](#24831) </details> - [Windows/Mac] Fix RTL FlowDirection causes overlap with native window control buttons in TitleBar by @devanathan-vaithiyanathan in #30400 <details> <summary>🔧 Fixes</summary> - [[Windows, Mac] RTL FlowDirection causes overlap with native window control buttons in TitleBar](#30399) </details> ## WebView - [Windows] Fix WebView background color not being applied by @SubhikshaSf4851 in #34599 <details> <summary>🔧 Fixes</summary> - [WebView background color has changed after update, can't override.](#34518) </details> - [Android] Fix for WebView/HybridWebView briefly flashes full screen before layout completes by @praveenkumarkarunanithi in #33207 <details> <summary>🔧 Fixes</summary> - [[Android] HybridWebView briefly resizes to full screen when page is opened before snapping back to correct size](#31475) </details> ## Xaml - Improved style inheritance by @kubaflo in #31317 <details> <summary>🔧 Fixes</summary> - [Styles based on a style that is based on another style that uses AppThemeBinding do not inherit properties correctly.](#31280) </details> - Fix for VisualStateManager Setter.TargetName failing when ControlTemplate is applied by @BagavathiPerumal in #33208 <details> <summary>🔧 Fixes</summary> - [Setter.TargetName + ControlTemplate crash](#26977) </details> <details> <summary>🧪 Testing (4)</summary> - [Testing] Additional Feature Matrix Event Test Cases for Slider and ScrollView by @nivetha-nagalingam in #34352 - [Testing] Fixed Build error on inflight/ candidate PR 34885 by @NafeelaNazhir in #34891 - [Testing] Fixed UI test image failure in PR 34885 - [13/4/2026] by @NafeelaNazhir in #34933 - Fixed test failure - CursorPositionUpdatesWhenSearchBarGainsFocus by @Dhivya-SF4094 in #34938 </details> <details> <summary>📦 Other (3)</summary> - Fix Loaded event not called for MAUI View added to native View by @NirmalKumarYuvaraj in #34345 <details> <summary>🔧 Fixes</summary> - [Loaded event not called for MAUI View added to native View](#34310) </details> - Add public IAlertManager and IAlertManagerSubscription interfaces by @Redth in #34228 <details> <summary>🔧 Fixes</summary> - [Alert/Dialog system (`DisplayAlert`, `DisplayActionSheet`, `DisplayPromptAsync`) needs a public extensibility point](#34104) </details> - Fix crash when displaying alerts on unloaded pages by @kubaflo in #33288 </details> <details> <summary>📝 Issue References</summary> Fixes #5825, Fixes #8494, Fixes #8716, Fixes #10987, Fixes #11404, Fixes #12008, Fixes #18200, Fixes #18551, Fixes #18657, Fixes #18701, Fixes #19168, Fixes #19209, Fixes #20062, Fixes #20348, Fixes #20834, Fixes #20991, Fixes #21983, Fixes #22038, Fixes #22193, Fixes #22197, Fixes #22769, Fixes #23330, Fixes #23854, Fixes #23902, Fixes #23921, Fixes #24304, Fixes #24831, Fixes #25124, Fixes #26059, Fixes #26397, Fixes #26644, Fixes #26846, Fixes #26961, Fixes #26977, Fixes #27086, Fixes #27367, Fixes #27959, Fixes #28337, Fixes #28351, Fixes #28660, Fixes #28975, Fixes #29390, Fixes #29391, Fixes #29463, Fixes #29493, Fixes #29544, Fixes #30052, Fixes #30065, Fixes #30071, Fixes #30144, Fixes #30399, Fixes #30779, Fixes #30803, Fixes #30970, Fixes #31280, Fixes #31446, Fixes #31475, Fixes #31496, Fixes #31565, Fixes #31825, Fixes #31961, Fixes #32048, Fixes #32050, Fixes #32139, Fixes #32356, Fixes #32419, Fixes #32771, Fixes #32944, Fixes #32984, Fixes #32994, Fixes #33308, Fixes #33501, Fixes #33703, Fixes #33770, Fixes #33773, Fixes #34104, Fixes #34256, Fixes #34257, Fixes #34310, Fixes #34322, Fixes #34363, Fixes #34370, Fixes #34459, Fixes #34518, Fixes #34583, Fixes #34591, Fixes #34666, Fixes #34693, Fixes #34720, Fixes #34730 </details> **Full Changelog**: main...inflight/candidate
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Description
Implements the Windows Maps handler using the new WinUI 3
MapControl(Windows App SDK 1.8+), which is backed by Azure Maps. Previously, all WindowsMapHandlermethods threwNotImplementedException.No new public API surface — this change only provides platform implementations behind already-shipped APIs.
PublicAPI.Unshipped.txtis empty. This makes it suitable for a servicing release.What's implemented
map.setCamera()via WebView2 JS (workaround for microsoft-ui-xaml#9490)map.setStyle()via WebView2 JSmap.setTraffic()via WebView2 JSmap.setUserInteraction()via WebView2 JSmap.setUserInteraction()via WebView2 JSMapIcononMapElementsLayerWhat's NOT implemented (no feature parity)
These features are no-op on Windows due to WinUI 3
MapControllimitations. They don't throw — they silently do nothing, matching the pattern other platforms use for unsupported features.MapElementsLayeronly supportsMapIconMapIconhas no label or info window supportMapElementClickonly fires forMapElementclicksArchitecture
The WinUI 3
MapControlinternally wraps Azure Maps in aWebView2. Several dependency properties (likeCenter) don't reliably propagate to the JS layer (microsoft-ui-xaml#9490). This handler works around that by:WebView2child viaVisualTreeHelper.GetChild()NavigationCompletedto know Azure Maps JS is readymap.setCamera(),map.setStyle(), etc.)Authentication
Uses the existing Essentials pattern — no new API needed:
Get a key from the Azure Portal → Azure Maps account → Authentication.
Files changed
MapHandler.Windows.cs— Full handler implementation (was allNotImplementedException)MapPinHandler.Windows.cs— Pin handling viaMapIconMapElementHandler.Windows.cs— Documented no-op stubs for shapesAppHostBuilderExtensions.cs— Updated XML docs to reflect Windows supportTODO for .NET 11
Refactor setup/cleanup into
ConnectHandler/DisconnectHandleroverrides to match iOS/Android pattern (avoided here to prevent new PublicAPI entries).