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。