Skip to content

Add XAML TypeConverters for Map coordinates (Location, MapSpan, Map.Region)#33995

Merged
jfversluis merged 1 commit intonet11.0from
feature/map-xaml-converters
Feb 19, 2026
Merged

Add XAML TypeConverters for Map coordinates (Location, MapSpan, Map.Region)#33995
jfversluis merged 1 commit intonet11.0from
feature/map-xaml-converters

Conversation

@jfversluis
Copy link
Copy Markdown
Member

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

Adds TypeConverters that enable concise XAML syntax for map coordinates, eliminating the need for verbose x:Arguments markup.

Before (verbose):

<maps:Pin Label="Santa Cruz">
    <maps:Pin.Location>
        <sensors:Location>
            <x:Arguments>
                <x:Double>36.9628</x:Double>
                <x:Double>-122.0195</x:Double>
            </x:Arguments>
        </sensors:Location>
    </maps:Pin.Location>
</maps:Pin>

After (concise):

<maps:Map Region="36.9628,-122.0195,0.05,0.05">
    <maps:Pin Label="Santa Cruz" Location="36.9628,-122.0195" />
</maps:Map>

Changes

  1. LocationTypeConverter - Converts "latitude,longitude" string to Location object

    • Added [TypeConverter] attribute to Location class
    • Placed in Essentials assembly (same assembly as Location)
  2. MapSpanTypeConverter - Converts "lat,lon,latDeg,lonDeg" string to MapSpan object

    • Added [TypeConverter] attribute to MapSpan class
  3. Map.Region bindable property - New MapSpan property on Map control

    • Setting this property calls MoveToRegion() automatically
    • Enables setting the map's initial region declaratively in XAML
    • Without this property, there was no way to set the initial region in XAML attributes

Testing

  • 19 unit tests (11 for LocationTypeConverter, 8 for MapSpanTypeConverter)
  • All 21 existing Map unit tests pass (no regressions)
  • Verified on iOS simulator with Appium: all converters parse correctly, map centers on expected region

Part of #33787 (Maps Epic)

Add TypeConverters enabling concise XAML syntax for map coordinates:
- LocationTypeConverter: "lat,lon" → Location
  Enables: <maps:Pin Location="36.9628,-122.0195" />
- MapSpanTypeConverter: "lat,lon,latDeg,lonDeg" → MapSpan
  Enables: <maps:Map Region="36.9628,-122.0195,0.05,0.05" />

Add Map.Region bindable property (type MapSpan) so the map's visible
region can be set declaratively in XAML. Setting Region calls MoveToRegion.

Includes 19 unit tests (11 Location + 8 MapSpan) covering round-trip,
edge cases, and error handling. Verified on iOS with Appium.
Copilot AI review requested due to automatic review settings February 11, 2026 15:17
@jfversluis jfversluis added this to the .NET 11.0-preview2 milestone Feb 11, 2026
@jfversluis jfversluis added t/enhancement ☀️ New feature or request area-controls-map Map / Maps labels Feb 11, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves the .NET MAUI Maps/XAML authoring experience by adding TypeConverters for map coordinate types and introducing a bindable Map.Region property so regions can be set declaratively via XAML attributes.

Changes:

  • Add LocationTypeConverter in Essentials and attach it to Microsoft.Maui.Devices.Sensors.Location via [TypeConverter].
  • Add MapSpanTypeConverter in Core Maps and attach it to Microsoft.Maui.Maps.MapSpan via [TypeConverter] (plus unit tests).
  • Add Microsoft.Maui.Controls.Maps.Map.Region bindable property that calls MoveToRegion() when set, enabling Region="lat,lon,latDeg,lonDeg" in XAML.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Essentials/test/UnitTests/LocationTypeConverter_Tests.cs Adds unit tests for LocationTypeConverter parsing/round-tripping.
src/Essentials/src/Types/LocationTypeConverter.shared.cs Introduces LocationTypeConverter implementation.
src/Essentials/src/Types/Location.shared.cs Applies [TypeConverter(typeof(LocationTypeConverter))] to Location.
src/Essentials/src/PublicAPI/netstandard/PublicAPI.Unshipped.txt Declares new public API for LocationTypeConverter.
src/Essentials/src/PublicAPI/net/PublicAPI.Unshipped.txt Declares new public API for LocationTypeConverter.
src/Essentials/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt Declares new public API for LocationTypeConverter.
src/Essentials/src/PublicAPI/net-tizen/PublicAPI.Unshipped.txt Declares new public API for LocationTypeConverter.
src/Essentials/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt Declares new public API for LocationTypeConverter.
src/Essentials/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt Declares new public API for LocationTypeConverter.
src/Essentials/src/PublicAPI/net-android/PublicAPI.Unshipped.txt Declares new public API for LocationTypeConverter.
src/Core/maps/src/Converters/MapSpanTypeConverter.cs Introduces MapSpanTypeConverter implementation.
src/Core/maps/src/Primitives/MapSpan.cs Applies [TypeConverter(typeof(MapSpanTypeConverter))] to MapSpan.
src/Core/maps/src/PublicAPI/netstandard/PublicAPI.Unshipped.txt Declares new public API for MapSpanTypeConverter.
src/Core/maps/src/PublicAPI/net/PublicAPI.Unshipped.txt Declares new public API for MapSpanTypeConverter.
src/Core/maps/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt Declares new public API for MapSpanTypeConverter.
src/Core/maps/src/PublicAPI/net-tizen/PublicAPI.Unshipped.txt Declares new public API for MapSpanTypeConverter.
src/Core/maps/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt Declares new public API for MapSpanTypeConverter.
src/Core/maps/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt Declares new public API for MapSpanTypeConverter.
src/Core/maps/src/PublicAPI/net-android/PublicAPI.Unshipped.txt Declares new public API for MapSpanTypeConverter.
src/Controls/tests/Core.UnitTests/MapSpanTypeConverterTests.cs Adds unit tests for MapSpanTypeConverter parsing/round-tripping.
src/Controls/Maps/src/Map.cs Adds new bindable Region property which calls MoveToRegion() on change.
src/Controls/Maps/src/PublicAPI/netstandard/PublicAPI.Unshipped.txt Declares new public API for Map.Region.
src/Controls/Maps/src/PublicAPI/net/PublicAPI.Unshipped.txt Declares new public API for Map.Region.
src/Controls/Maps/src/PublicAPI/net-windows/PublicAPI.Unshipped.txt Declares new public API for Map.Region.
src/Controls/Maps/src/PublicAPI/net-tizen/PublicAPI.Unshipped.txt Declares new public API for Map.Region.
src/Controls/Maps/src/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt Declares new public API for Map.Region.
src/Controls/Maps/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt Declares new public API for Map.Region.
src/Controls/Maps/src/PublicAPI/net-android/PublicAPI.Unshipped.txt Declares new public API for Map.Region.

Comment on lines +166 to +173
/// <summary>
/// Gets or sets the region displayed by the map. Setting this property moves the map to the specified region.
/// This is a bindable property.
/// </summary>
public MapSpan? Region
{
get { return (MapSpan?)GetValue(RegionProperty); }
set { SetValue(RegionProperty, value); }
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

Region is described as “the region displayed by the map”, but it is only used as an input to call MoveToRegion() when set. It is not kept in sync with user panning/zooming (that state is exposed via VisibleRegion). This makes the public API contract misleading—please clarify the XML docs (or consider syncing Region from VisibleRegion without re-invoking MoveToRegion to avoid feedback loops).

Copilot uses AI. Check for mistakes.
@jfversluis jfversluis merged commit f039387 into net11.0 Feb 19, 2026
28 of 34 checks passed
@jfversluis jfversluis deleted the feature/map-xaml-converters branch February 19, 2026 11:01
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

🚨 API change(s) detected @davidortinau FYI

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants