我正在玩 dotnet Maui 的新地图控件。一个简单的例子是让 XAML 像:
<?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>
这样我就可以在 cs 文件后面的代码中访问“地图”:
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);
}
}
我想要一个 ViewModel 来与 XAML 交互,但是如果我创建一个 ViewModel 类:
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);
}
}
我在“地图”上遇到错误:
"Cannot declare variable of static type 'Map'"
那是因为Map是静态类。在这种情况下,我如何才能拥有一个绑定到 XAML 中的 Map 元素的 ViewModel 类?
UI 元素和 UI 元素类型不应在您的 ViewModel 中直接引用,正如 FreakyAli 所说。
因为
Map
是一个UI元素,所以我们不能直接在我们的ViewModel中使用它。
您可以在
YourPage.xaml
中定义Map并在您的ViewModel中添加其他必要的数据。
例如:
您可以在
Map
中添加YourPage.xaml
并在视图模型中添加Positions
<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>
并在
map.MoveToRegion
中添加
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}");
}
}
并定义 viewModel 如下:
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));
}
}
更多信息,您可以查看文档:地图.
以上代码来自官方示例WorkingWithMaps。请注意PinItemsSourcePage.xaml和PinItemsSourcePageViewModel.cs.