I am playing around with the new Maps control from dotnet Maui. A simple example is to have the XAML like:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.Maps"
x:Class="SaRM.MainPage">
<maps:Map x:Name="map" MapType="Street"/>
</ContentPage>
and with that I can access the "map" in the code behind cs file:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
var location = new Location(36.96, -122.0194);
var mapSpan = new MapSpan(location, 0.01, 0.01);
map.MoveToRegion(mapSpan);
}
}
I would like to have a ViewModel to interact with the XAML but if I create a ViewModel class as:
public class MainViewModel
{
public Map map;
public MainViewModel()
{
var location = new Location(36.96, -122.0194);
var mapSpan = new MapSpan(location, 0.01, 0.01);
map.MoveToRegion(mapSpan);
}
}
I get an error on "maps":
"Cannot declare variable of static type 'Map'"
That is because Map is a static class. How can I have a ViewModel class that binds to the Map element in XAML in that case?
Update:
Here is the Map class definition inside Microsoft.Maui.Maps:
UI elements and UI element types should not be directly referenced in your ViewModel,just as FreakyAli said.
Since Map
is a UI element, so we cannot use it in our ViewModel directly.
You can define Map in YourPage.xaml
and add other necessary data on your ViewModel.
For example:
you can add Map
in YourPage.xaml
and add Positions
in View Model
<maps:Map x:Name="map"
MapClicked="OnMapClicked"
ItemsSource="{Binding Positions}">
<maps:Map.ItemTemplate>
<DataTemplate>
<maps:Pin Location="{Binding Location}"
Address="{Binding Address}"
Label="{Binding Description}" />
</DataTemplate>
</maps:Map.ItemTemplate>
</maps:Map>
And add map.MoveToRegion
in YourPage.xaml.cs
public partial class PinItemsSourcePage : ContentPage
{
public PinItemsSourcePage()
{
InitializeComponent();
BindingContext = new PinItemsSourcePageViewModel();
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Location(39.8283459, -98.5794797), Distance.FromMiles(1500)));
}
void OnMapClicked(object sender, MapClickedEventArgs e)
{
System.Diagnostics.Debug.WriteLine($"MapClick: {e.Location.Latitude}, {e.Location.Longitude}");
}
}
and define viewModel as follows:
public class PinItemsSourcePageViewModel
{
int _pinCreatedCount = 0;
readonly ObservableCollection<Position> _positions;
public IEnumerable Positions => _positions;
public ICommand AddLocationCommand { get; }
public ICommand RemoveLocationCommand { get; }
public ICommand ClearLocationsCommand { get; }
public ICommand UpdateLocationsCommand { get; }
public ICommand ReplaceLocationCommand { get; }
public PinItemsSourcePageViewModel()
{
_positions = new ObservableCollection<Position>()
{
new Position("New York, USA", "The City That Never Sleeps", new Location(40.67, -73.94)),
new Position("Los Angeles, USA", "City of Angels", new Location(34.11, -118.41)),
new Position("San Francisco, USA", "Bay City", new Location(37.77, -122.45))
};
AddLocationCommand = new Command(AddLocation);
RemoveLocationCommand = new Command(RemoveLocation);
ClearLocationsCommand = new Command(() => _positions.Clear());
UpdateLocationsCommand = new Command(UpdateLocations);
ReplaceLocationCommand = new Command(ReplaceLocation);
}
void AddLocation()
{
_positions.Add(NewPosition());
}
void RemoveLocation()
{
if (_positions.Any())
{
_positions.Remove(_positions.First());
}
}
void UpdateLocations()
{
if (!_positions.Any())
{
return;
}
double lastLatitude = _positions.Last().Location.Latitude;
foreach (Position position in Positions)
{
position.Location = new Location(lastLatitude, position.Location.Longitude);
}
}
void ReplaceLocation()
{
if (!_positions.Any())
{
return;
}
_positions[_positions.Count - 1] = NewPosition();
}
Position NewPosition()
{
_pinCreatedCount++;
return new Position(
$"Pin {_pinCreatedCount}",
$"Desc {_pinCreatedCount}",
RandomPosition.Next(new Location(39.8283459, -98.5794797), 8, 19));
}
}
Fore more information, you can check document:Map.
And above code is from official sample WorkingWithMaps. Please pay attention to PinItemsSourcePage.xaml and PinItemsSourcePageViewModel.cs.