Xamarin.Forms.GoogleMaps 从 ViewModel 绑定 MoveToRegion
Xamarin.Forms.GoogleMaps Bind MoveToRegion from ViewModel
我希望在我的视图中从 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) 的发帖 -
我也用过这个 NuGet 包 - https://www.nuget.org/packages/Xamarin.Forms.GoogleMaps.Bindings/ and GitHub link here - 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" }
});
}
}
自定义 BindableMap
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(西班牙语)我还没有看过,但它确实展示了如何绑定 Google 地图 MVVM。
我希望在我的视图中从 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) 的发帖 -
我也用过这个 NuGet 包 - https://www.nuget.org/packages/Xamarin.Forms.GoogleMaps.Bindings/ and GitHub link here - 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" }
});
}
}
自定义 BindableMap
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(西班牙语)我还没有看过,但它确实展示了如何绑定 Google 地图 MVVM。