maui-maps
Installation
SKILL.md
.NET MAUI Maps
Common gotchas
| Issue | Fix |
|---|---|
| Map is blank on Android | Google Maps API key missing or wrong in AndroidManifest.xml |
| Map crashes on startup | .UseMauiMaps() not called in MauiProgram.cs |
Map type ambiguous |
Conflicts with Microsoft.Maui.ApplicationModel.Map — add namespace alias |
| Map doesn't show on Windows | Windows has no native support — must use CommunityToolkit.Maui.Maps |
| User location dot missing | IsShowingUser="True" set but location permission not granted |
| Android 11+ can't launch external map app | Missing <queries> for geo scheme in manifest |
⚠️ Name conflict — always alias
Microsoft.Maui.Controls.Maps.Map conflicts with Microsoft.Maui.ApplicationModel.Map. This causes confusing compile errors.
// ✅ Correct — explicit alias
using Map = Microsoft.Maui.Controls.Maps.Map;
<!-- ✅ Correct — namespace prefix in XAML -->
xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.Maps"
<maps:Map ... />
<!-- ❌ Wrong — bare <Map> is ambiguous -->
<Map ... />
Platform setup pitfalls
Android — API key must be inside <application>
<!-- ✅ Correct -->
<application ...>
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="YOUR_GOOGLE_MAPS_KEY" />
</application>
<!-- ❌ Outside <application> — key is silently ignored -->
⚠️ Also required: Google Play Services version meta-data and <queries> for geo scheme on API 30+ (see references/maps-api.md).
iOS / Mac Catalyst
⚠️ Without NSLocationWhenInUseUsageDescription in Info.plist, location permission is denied without prompt.
Windows — no native support
Must add CommunityToolkit.Maui.Maps + Bing key. Use conditional package reference and #if WINDOWS for setup.
MauiProgram.cs — don't forget UseMauiMaps
// ✅ Required — without this, Map control throws at runtime
builder.UseMauiMaps();
// ❌ Forgetting this causes "No registered handler for Map" crash
Performance tips
- ⚠️ Don't add hundreds of pins directly — use
ItemsSourcewith data binding for large pin sets. - Set initial region with
MoveToRegion()to avoid the default world view zoom animation. - Avoid frequent
MoveToRegion()calls — each triggers a map animation; debounce if driven by data changes.
Data-bound pins — do this for dynamic data
<!-- ✅ Correct — data-bound pins for dynamic collections -->
<maps:Map ItemsSource="{Binding Locations}">
<maps:Map.ItemTemplate>
<DataTemplate>
<maps:Pin Label="{Binding Name}"
Address="{Binding Description}"
Location="{Binding Position}" />
</DataTemplate>
</maps:Map.ItemTemplate>
</maps:Map>
<!-- ❌ Wrong — manually adding pins in code-behind for data-driven scenarios -->
Decision framework
| Need | Approach |
|---|---|
| Basic map with pins | Map control + Pins.Add() or ItemsSource binding |
| Map with shapes | MapElements — Polygon, Polyline, Circle |
| Address → coordinates | Geocoding.Default.GetLocationsAsync(address) |
| Coordinates → address | Geocoding.Default.GetPlacemarksAsync(lat, lon) |
| Custom map overlays | Use handlers to access native map APIs |
| Windows support | Must add CommunityToolkit.Maui.Maps + Bing key |
Quick checklist
- NuGet:
Microsoft.Maui.Controls.Mapsadded -
.UseMauiMaps()called inMauiProgram.cs - Android: Google Maps API key inside
<application>inAndroidManifest.xml - Android: Google Play Services version meta-data present
- Android 11+:
<queries>for geo scheme added - iOS/Mac:
NSLocationWhenInUseUsageDescriptioninInfo.plist - Windows:
CommunityToolkit.Maui.Maps+ Bing Maps key (conditional) - Namespace alias added to avoid
Maptype conflict
Related skills