Quantcast
Viewing all articles
Browse latest Browse all 89864

[v2.0.1] [Android]: BindingContext updates not updating custom ContentView.

Sorry if the title is a little vague. I'm creating a custom map that has bindable pins and xaml callouts. I've got the bindable pins pretty much rocking, but my callouts are effed up.

Full source code found here.

To start, I have a custom callout adapter that get's wired up in the custom renderer.

private void SetupCalloutAdapter()
{
    if (_adapter != null)
    {
        _adapter.Dispose();
        _adapter = null;
    }

    if (FormsMap.CalloutTemplate != null)
    {
        _adapter = new XfxMapCalloutAdapter(NativeMap, FormsMap.CalloutTemplate, Element);
    }
}

This adapter essentially wires up the xaml using CreateContent() just before the view is to be shown.

public class XfxMapCalloutAdapter : Object, GoogleMap.IInfoWindowAdapter
{
    private static readonly Dictionary<int, XfxMarker> BindingContextCollection = new Dictionary<int, XfxMarker>();
    private readonly DataTemplate _mapCalloutTemplate;
    private readonly Xamarin.Forms.View _parent;

    public XfxMapCalloutAdapter(GoogleMap nativeMap, DataTemplate calloutTemplate, Xamarin.Forms.View parent)
    {
        _mapCalloutTemplate = calloutTemplate;
        _parent = parent;
        nativeMap.SetInfoWindowAdapter(this);
    }

    public View GetInfoContents(Marker marker)
    {
        if (_mapCalloutTemplate == null)
        {
            return null;
        }

        int key;
        var callout = (XfxMapCallout)_mapCalloutTemplate.CreateContent();
        callout.Parent = _parent;

        if (int.TryParse(marker.Snippet, out key))
        {
            callout.BindingContext = BindingContextCollection[key];
            //title = BindingContextCollection[key].Title;
        }

        return new XfxMapCalloutContainer(Android.App.Application.Context, callout, string.Empty);
    }

    public View GetInfoWindow(Marker marker)
    {
        // we're not drawing an entire background layout, so we'll just leave this null.
        // if we wanted to create our own custom layout, we'd use this.
        return null;
    }

    public void AddToBindingContext(XfxMarker marker)
    {
        if (!BindingContextCollection.ContainsKey(marker.HashId))
        {
            BindingContextCollection.Add(marker.HashId, marker);
        }
    }

    public void RemoveFromBindingContext(int hashId)
    {
        if (BindingContextCollection.ContainsKey(hashId))
        {
            BindingContextCollection.Remove(hashId);
        }
    }
}

The view is wrapped in a custom container that handles some measurements and also converts the Xaml view into a native view.

public sealed class XfxMapCalloutContainer : ViewGroup
{
    private readonly IVisualElementRenderer _renderer;

    public XfxMapCalloutContainer(IntPtr javaReference, JniHandleOwnership transfer)
        : base(javaReference, transfer)
    {
        // this constructor prevents the app from crashing.
    }

    public XfxMapCalloutContainer(Context context, XfxMapCallout view, string title)
        : base(context)
    {
        // todo: figure out how to get the title in here.
        _renderer = Platform.CreateRenderer(view);
        Platform.SetRenderer(view, _renderer);

        AddView(_renderer.ViewGroup);
        view.OnAppearing(this);
    }

    protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        var sizeRequest = _renderer.Element.GetSizeRequest(double.PositiveInfinity, double.PositiveInfinity);
        var width = (int)Context.ToPixels(sizeRequest.Request.Width);
        var height = (int)Context.ToPixels(sizeRequest.Request.Height);
        SetMeasuredDimension(width, height);
    }

    protected override void OnLayout(bool changed, int l, int t, int r, int b)
    {
        _renderer.Element.Layout(new Rectangle(0, 0, r - l, b - t));
        _renderer.UpdateLayout();
    }
}

What I'm running into is two fold:

  1. When I update the Bindable Properties on the ViewModel, they don't update on the view (does X.F handle this, or is there more I should be doing?)
  2. For some stupid reason, my button doesn't show text.
<xfxMap:XfxMapCallout xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:xfxMap="clr-namespace:Xfx.XfxMap;assembly=Xfx.XfxMap"
             x:Class="XfxMapExample.ExampleMarkerCallout">
  <StackLayout>
    <BoxView WidthRequest="20" HeightRequest="30" Color="Blue"/>
    <Label Text="Static Text" TextColor="Aqua" />
    <Label Text="{Binding Description}" TextColor="Fuchsia" />
    <Label x:Name="Counter" Text="{Binding Counter}" TextColor="Green" />
    <Button Image="Icon" Text="Foo" TextColor="Pink" BackgroundColor="Maroon" />
  </StackLayout>
</xfxMap:XfxMapCallout>

Essentially I'm updating the Counter on a 1 second loop in hopes of seeing it update on the view, but it never does.... what am I missing?
note: if the data is there from the beginning, it'll show up, just doesn't pick up the property changes.

public async void ExampleInit()
{
    while (true)
    {
        await Task.Delay(1000);
        Counter++;
    }
}

Image may be NSFW.
Clik here to view.
image


Viewing all articles
Browse latest Browse all 89864

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>