Barney Chambers
Barney Chambers

Reputation: 2783

Xamarin Forms - Reference XAML from Android specific .cs file

I have a page called MapPage.xaml and a code behind called MapPage.xaml.cs. In my android project, I have another file called CustomMapRenderer.cs. In the CustomMapRenderer.cs file, I need to retrieve the item selected variable in a XAML picker found in my MapPage.xaml file, which changes when a user picks an option in my XAML picker.

How to I reference the picker from my CustomMapRenderer.cs?

Upvotes: 0

Views: 179

Answers (1)

Grace Feng
Grace Feng

Reputation: 16652

In the CustomMapRenderer.cs file, I need to retrieve the item selected variable in a XAML picker found in my MapPage.xaml file, which changes when a user picks an option in my XAML picker.

If you followed the official doc Customizing a Map to create your CustomMapRenderer, then in PCL, there should be a class which inherits from Map, for example:

public class CustomMap : Map
{

}

Then, if your picker is another control in your MainPage, you can create a bindable property for your CustomMap, and override OnElementPropertyChanged in your renderer to get this property when it changed.

For example, in PCL:

public class MapWithMyZoomControl : Map
{
    public ZoomState MyZoom
    {
        get { return (ZoomState)GetValue(MyZoomProperty); }
        set { SetValue(MyZoomProperty, value); }
    }

    public static readonly BindableProperty MyZoomProperty =
        BindableProperty.Create(
            propertyName: "MyZoom",
            returnType: typeof(ZoomState),
            declaringType: typeof(MapWithMyZoomControl),
            defaultValue: ZoomState.normal,
            propertyChanged: OnZoomPropertyChanged);

    public static void OnZoomPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
    }

    public enum ZoomState
    {
        normal,
        zoomin,
        zoomout
    }
}

And in its renderer:

public class MapWithMyZoomControlRenderer : MapRenderer, IOnMapReadyCallback
{
    private GoogleMap map;

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

        map.UiSettings.ZoomControlsEnabled = false;
    }

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

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

        if (e.NewElement != null)
        {
            var formsMap = (MapWithMyZoomControl)e.NewElement;

            ((MapView)Control).GetMapAsync(this);
        }
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        var element = Element as MapWithMyZoomControl;
        if (e.PropertyName == "MyZoom" && map != null)
        {
            if (element.MyZoom == MapWithMyZoomControl.ZoomState.zoomin)
            {
                map.AnimateCamera(CameraUpdateFactory.ZoomIn());
            }
            else if (element.MyZoom == MapWithMyZoomControl.ZoomState.zoomout)
            {
                map.AnimateCamera(CameraUpdateFactory.ZoomOut());
            }
            element.MyZoom = MapWithMyZoomControl.ZoomState.normal;
        }
    }
}

Out of this map control, I use buttons to control to zoom the map:

map.MyZoom = MapWithMyZoomControl.ZoomState.zoomin;

It'a a demo, but you can modify it to make property connected to your picker.

Upvotes: 1

Related Questions