Xamarin.Forms.Maps - 灾难性故障(HRESULT 异常:0x8000FFFF (E_UNEXPECTED))

Xamarin.Forms.Maps - Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))

我关注了Xamarin Tutorial Customizing a Map。 我稍微改变了一下,以便能够绘制路线。

public class CustomMap : Map
{
    public static readonly BindableProperty RouteCoordinatesProperty =
    BindableProperty.Create(nameof(RouteCoordinates), typeof(List<Position>), typeof(CustomMap), new List<Position>(), BindingMode.TwoWay);

    public List<Position> RouteCoordinates
    {
        get { return (List<Position>)GetValue(RouteCoordinatesProperty); }
        set { SetValue(RouteCoordinatesProperty, value); }
    }
}

WinPhone 8.1 渲染器:

[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace PROJECT.WinPhone
{
public class CustomMapRenderer : MapRenderer
{
    MapControl nativeMap;
    CustomMap formsMap;

    protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            nativeMap = Control as MapControl;
        }

        if (e.NewElement != null)
        {
            formsMap = (CustomMap)e.NewElement;
            nativeMap = Control as MapControl;
            //UpdatePolyLine();

            var coordinates = new List<BasicGeoposition>();
            foreach (var position in formsMap.RouteCoordinates)
            {
                coordinates.Add(new BasicGeoposition() { Latitude = position.Latitude, Longitude = position.Longitude });
            }

            var polyline = new MapPolyline();
            polyline.StrokeColor = Windows.UI.Color.FromArgb(128, 255, 0, 0);
            polyline.StrokeThickness = 5;
            polyline.Path = new Geopath(coordinates);
            nativeMap.MapElements.Add(polyline);
        }
    }
}
}

polyline.Path = new Geopath(坐标); 抛出 Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED)) 问题是我的另外两个渲染器 (Android & iOS) 工作..也许有些事情是不可能的,因为我使用 WinPhone8.1 不像教程,它是 UWP

Android渲染器

[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace PROJECT.Droid
{
public class CustomMapRenderer : MapRenderer, IOnMapReadyCallback
{
    GoogleMap map;
    Polyline polyline;

    protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Xamarin.Forms.View> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            // Unsubscribe
        }

        if (e.NewElement != null)
        {
            ((MapView)Control).GetMapAsync(this);
        }

        UpdatePolyLine();
    }

    protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        if (this.Element == null || this.Control == null)
            return;

        if (e.PropertyName == CustomMap.RouteCoordinatesProperty.PropertyName)
        {
            UpdatePolyLine();
        }
    }

    private void UpdatePolyLine()
    {
        if (map != null)
        {
            if (polyline != null)
            {
                polyline.Remove();
                polyline.Dispose();
            }
            var polylineOptions = new PolylineOptions();
            polylineOptions.InvokeColor(0x66FF0000);

            int a = 0;

            foreach (var position in ((CustomMap)this.Element).RouteCoordinates)
            {
                polylineOptions.Add(new LatLng(position.Latitude, position.Longitude));
            }

            polyline = map.AddPolyline(polylineOptions);
        }
    }

    public void OnMapReady(GoogleMap googleMap)
    {
        map = googleMap;
        UpdatePolyLine();
    }
}
}

iOS渲染器

[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace PROJECT.iOS
{
public class CustomMapRenderer : MapRenderer
{
    MKMapView nativeMap;
    MKPolylineRenderer polylineRenderer;

    protected override void OnElementChanged(ElementChangedEventArgs<View> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            nativeMap = Control as MKMapView;
            nativeMap.OverlayRenderer = null;
        }

        if (e.NewElement != null)
        {
            UpdatePolyLine();
        }
    }

    protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        if (this.Element == null || this.Control == null)
            return;

        if (e.PropertyName == CustomMap.RouteCoordinatesProperty.PropertyName)
        {
            UpdatePolyLine();
        }
    }

    MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlay)
    {
        if (polylineRenderer == null)
        {
            polylineRenderer = new MKPolylineRenderer(overlay as MKPolyline);
            polylineRenderer.FillColor = UIColor.Blue;
            polylineRenderer.StrokeColor = UIColor.Red;
            polylineRenderer.LineWidth = 3;
            polylineRenderer.Alpha = 0.4f;
        }
        return polylineRenderer;
    }

    private void UpdatePolyLine()
    {
        if (nativeMap != null)
        {
            var formsMap = ((CustomMap)this.Element);
            nativeMap = Control as MKMapView;

            nativeMap.OverlayRenderer = GetOverlayRenderer;

            CLLocationCoordinate2D[] coords = new CLLocationCoordinate2D[formsMap.RouteCoordinates.Count];

            int index = 0;
            foreach (var position in formsMap.RouteCoordinates)
            {
                coords[index] = new CLLocationCoordinate2D(position.Latitude, position.Longitude);
                index++;
            }

            var routeOverlay = MKPolyline.FromCoordinates(coords);
            nativeMap.AddOverlay(routeOverlay);
        }
    }
}
}

弄了半天,发现为什么不行了...

如果你像我一样,如果你对Google方向APIHttpRequest,那么结果将在 OnElementChanged().

的第一段之后出现

因为 formsMap.RouteCoordinates 不是 null 而是 ,所以抛出 Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))..

这是好的 CustomMapRenderer for PolyLine use

using PROJECT;
using PROJECT.UWP;
using System.Collections.Generic;
using Windows.Devices.Geolocation;
using Windows.UI.Xaml.Controls.Maps;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Maps.UWP;
using Xamarin.Forms.Platform.UWP;

[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace PROJECT.UWP
{
    public class CustomMapRenderer : MapRenderer
    {
        MapControl nativeMap;
        CustomMap formsMap;

        protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                nativeMap = Control as MapControl;
            }

            if (e.NewElement != null)
            {
                formsMap = (CustomMap)e.NewElement;
                nativeMap = Control as MapControl;
                UpdatePolyLine();
            }
        }

        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if (this.Element == null || this.Control == null)
                return;

            if (e.PropertyName == CustomMap.RouteCoordinatesProperty.PropertyName)
            {
                UpdatePolyLine();
            }
        }

        private void UpdatePolyLine()
        {
            if (formsMap != null && formsMap.RouteCoordinates.Count > 0)
            {
                List<BasicGeoposition> coordinates = new List<BasicGeoposition>();

                foreach (var position in formsMap.RouteCoordinates)
                {
                    coordinates.Add(new BasicGeoposition() { Latitude = position.Latitude, Longitude = position.Longitude });
                }

                Geopath path = new Geopath(coordinates);
                MapPolyline polyline = new MapPolyline();
                polyline.StrokeColor = Windows.UI.Color.FromArgb(128, 255, 0, 0);
                polyline.StrokeThickness = 5;
                polyline.Path = path;
                nativeMap.MapElements.Add(polyline);
            }
        }
    }
}