Xamarin Forms custom control: implement a method in the renderer

一笑奈何 提交于 2021-02-11 14:31:08

问题


I'm trying to create an extended version of the standard XF Map object:

public class RRMap: Map
{

    public void DoSomethingOnMap() {
        /* ... */
    }

}

I also created an Android renderer (iOS will come later):

[assembly: ExportRenderer(typeof(RRMap), typeof(RRMapRendererAndroid))]
namespace MyApp.Droid.Renderers
{
    public class RRMapRendererAndroid : MapRenderer
    {
        public RRMapRendererAndroid(Context context) : base(context) { }

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

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

        protected override MarkerOptions CreateMarker(Pin pin)
        {
            var marker = new MarkerOptions();
            marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
            marker.SetTitle(pin.Label);
            marker.SetSnippet(pin.Address);
            marker.SetIcon(BitmapDescriptorFactory.DefaultMarker(210));
            return marker;
        }

    }
}

Everything is working fine so far: the map is rendered and pins are created with a custom color.

Unfortunately, I'm stuck on the implementation of DoSomethingOnMap method: it should be a method in the shared code, but it should be implemented in different ways, depending on the platform.

In other circumstances, I would create an interface using DependencyService for implementation, but in this particular case I can't figure out how to proceed.


回答1:


The first solution is you can use a messaging-center, this can communicate between shared project and iOS/Android project.

Publish a message in the doSomethingOnMap method and anywhere you subscribed to the message will be triggered.

The second is create an event in your shared project and subscribe to that event in the renderer, I wrote both two solutions below:

In your shared project:

public class CustomMap : Map
{
    public List<CustomPin> CustomPins { get; set; }

    public event EventHandler CallToNativeMethod;

    public void doSomething()
    {
        if (CallToNativeMethod != null)
            CallToNativeMethod(this, new EventArgs());
    }

    public void doSomething(CustomMap myMap) {


        MessagingCenter.Send<CustomMap>(this, "Hi");

    }
}

In the renderer:

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

        if (e.OldElement != null)
        {

        }

        if (e.NewElement != null)
        {

            MessagingCenter.Subscribe<CustomMap>(this, "Hi", (sender) =>
            {
                // Do something whenever the "Hi" message is received
                Console.WriteLine("hi");
            });

            ((CustomMap)e.NewElement).CallToNativeMethod += (sender, arg) =>
            {
                Console.WriteLine("native method");
            };
        }
    }

At anywhere you want to call this method:

private void Button_Clicked(object sender, System.EventArgs e)
{
    customMap.doSomething();
    customMap.doSomething(customMap);
}


来源:https://stackoverflow.com/questions/58223899/xamarin-forms-custom-control-implement-a-method-in-the-renderer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!