我希望从ViewModel绑定视图中的Map实例,特别是MoveToRegion。我能够在我的ViewModel中绑定ObservableCollection中的Pins,如下所示:
查看Xaml:
<maps:Map
x:Name="mapView"
HasRotationEnabled="False"
HeightRequest="180"
MapType="Street"
MyLocationEnabled="True">
<maps:Map.Behaviors>
<bindings:BindingPinsBehavior Value="{Binding Pins}" />
</maps:Map.Behaviors>
</maps:Map>
视图模型:
ObservableCollection<Pin> _pins;
public ObservableCollection<Pin> Pins
{
get => _pins;
set => SetProperty(ref _pins, value);
}
public override void Init(ClinicViewModel parameter)
{
LoadData(parameter);
}
private void LoadData(ClinicViewModel clinic)
{
Pin clinicPin = new Pin()
{
Type = PinType.Place,
Label = clinic.Name,
Address = clinic.CompleteAddress,
Position = new Position(Convert.ToDouble(clinic.Latitude), Convert.ToDouble(clinic.Longitude)),
Tag = "id_" + clinic.Id
};
Pins.Add(clinicPin);
}
这很好,但我不确定如何将地图设置为MoveToRegion,因为我想将地图的位置设置为诊所的经度和纬度,与Pin相同。
好的,所以我想我现在已经可以工作了,在Android上我已经测试过了,它也可以工作,一旦我知道IOS正常工作,我会在这里发表评论。
我用这个SO答案作为我工作的基础,所以他们(Pejeman(发布了-https://stackoverflow.com/a/53804163/676875
我还使用了这个NuGet包-https://www.nuget.org/packages/Xamarin.Forms.GoogleMaps.Bindings/和GitHub链接在这里-https://github.com/nuitsjp/Xamarin.Forms.GoogleMaps.Bindings
我的代码:
视图:
<Frame
Margin="15,0,15,0"
Padding="0"
CornerRadius="10"
IsClippedToBounds="True">
<map:BindableMap
x:Name="mapView"
HasRotationEnabled="False"
HeightRequest="180"
MapSpan="{Binding ClinicMapSpan}"
MapType="Street"
MyLocationEnabled="True">
<maps:Map.Behaviors>
<bindings:BindingPinsBehavior Value="{Binding Pins}" />
</maps:Map.Behaviors>
</map:BindableMap>
</Frame>
查看模型
ObservableCollection<Pin> _pins;
public ObservableCollection<Pin> Pins
{
get => _pins;
set => SetProperty(ref _pins, value);
}
public override void Init(ClinicViewModel parameter)
{
LoadData(parameter);
}
private void LoadData(ClinicViewModel clinic)
{
try
{
Pin clinicPin = new Pin()
{
Type = PinType.Place,
Label = clinic.Name,
Address = clinic.CompleteAddress,
Position = new Position(Convert.ToDouble(clinic.Latitude), Convert.ToDouble(clinic.Longitude)),
Tag = "id_" + clinic.Id
};
ClinicMapSpan = MapSpan.FromCenterAndRadius(new Position(clinicPin.Position.Latitude, clinicPin.Position.Longitude), Distance.FromMiles(1));
Pins.Add(clinicPin);
}
catch (Exception e)
{
AnalyticService.TrackEvent("Clinic Details", new Dictionary<string, string>
{
{ "Method", clinic.ClinicName + " ClinicDetailViewModel.LoadData" }
});
}
}
自定义可绑定地图
public class BindableMap : Map
{
public BindableMap()
{
PinsSource = new ObservableCollection<Pin>();
PinsSource.CollectionChanged += PinsSourceOnCollectionChanged;
}
public ObservableCollection<Pin> PinsSource
{
get { return (ObservableCollection<Pin>)GetValue(PinsSourceProperty); }
set { SetValue(PinsSourceProperty, value); }
}
public static readonly BindableProperty PinsSourceProperty = BindableProperty.Create(
propertyName: "PinsSource",
returnType: typeof(ObservableCollection<Pin>),
declaringType: typeof(BindableMap),
defaultValue: null,
defaultBindingMode: BindingMode.TwoWay,
validateValue: null,
propertyChanged: PinsSourcePropertyChanged);
public MapSpan MapSpan
{
get { return (MapSpan)GetValue(MapSpanProperty); }
set { SetValue(MapSpanProperty, value); }
}
public static readonly BindableProperty MapSpanProperty = BindableProperty.Create(
propertyName: "MapSpan",
returnType: typeof(MapSpan),
declaringType: typeof(BindableMap),
defaultValue: null,
defaultBindingMode: BindingMode.TwoWay,
validateValue: null,
propertyChanged: MapSpanPropertyChanged);
private static void MapSpanPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
var thisInstance = bindable as BindableMap;
var newMapSpan = newValue as MapSpan;
thisInstance?.MoveToRegion(newMapSpan);
}
private static void PinsSourcePropertyChanged(BindableObject bindable, object oldvalue, object newValue)
{
var thisInstance = bindable as BindableMap;
var newPinsSource = newValue as ObservableCollection<Pin>;
if (thisInstance == null ||
newPinsSource == null)
return;
UpdatePinsSource(thisInstance, newPinsSource);
}
private void PinsSourceOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
UpdatePinsSource(this, sender as IEnumerable<Pin>);
}
private static void UpdatePinsSource(Map bindableMap, IEnumerable<Pin> newSource)
{
bindableMap.Pins.Clear();
foreach (var pin in newSource)
bindableMap.Pins.Add(pin);
}
}
我希望这能帮助到别人。我还发现了这个YouTube视频-https://www.youtube.com/watch?v=icMM2cviOJo(西班牙语(我还没看过,但它确实展示了如何绑定谷歌地图MVVM。