Пользовательский элемент управления Xamarin Forms: реализовать метод в рендерере - PullRequest
0 голосов
/ 03 октября 2019

Я пытаюсь создать расширенную версию стандартного объекта XF Map:

public class RRMap: Map
{

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

}

Я также создал средство визуализации Android (iOS появится позже):

[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;
        }

    }
}

Пока все работает нормально: карта отображается, а выводы создаются с использованием собственного цвета.

К сожалению, я застрял в реализации метода DoSomethingOnMap: это должен быть метод в общем коде, но это должно быть реализовано по-разному, в зависимости от платформы.

В других случаях я бы создал интерфейс, использующий для реализации DependencyService, но в этом конкретном случае я не могу понять, как действовать дальше.

1 Ответ

1 голос
/ 04 октября 2019

Решение first заключается в том, что вы можете использовать messaging-center , который может взаимодействовать между общим проектом и проектом iOS / Android.

Опубликуйте сообщение в методе doSomethingOnMap, и везде, где вы подписались на сообщение, будет срабатывать.

секунда - это создать событие в вашем общем проекте и подписатьсяк этому событию в рендере я написал оба решения ниже:

В вашем общем проекте:

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");

    }
}

В рендере:

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");
            };
        }
    }

В любом месте, где выхочу вызвать этот метод:

private void Button_Clicked(object sender, System.EventArgs e)
{
    customMap.doSomething();
    customMap.doSomething(customMap);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...