wainy
wainy

Reputation: 435

MvxAdapter Programmatic Binding

I've got a Custom MvxAdapter that is bound to a list of custom objects. I would like to bind my objects to my android resource programmatically in the Custom Adapter, rather than specifying my bindings within the xml.

I understand this is possible, as Stuart answered a question on SO here where he states " ....applying the bindings inside the custom adapter and by setting that adapter in OnCreate in your Activity".

However, I can't find any examples of this and CreateBindingSet() is not available in GetView or GetBindableView.

Can anyone point me in the right direction?

Edit: Code added to illustrate where I would like to manually do the binding

        protected override View GetBindableView(View convertView, object source, int templateId)
        {
            if (source is JobWithTabsViewModel.PictureFeature)
                templateId = Resource.Layout.jobview_withtabs_features_item_picture;
            else if (source is JobWithTabsViewModel.PointOfInterestFeature)
                templateId = Resource.Layout.jobview_withtabs_features_item_poi;
            return base.GetBindableView(convertView, source, templateId);
        }

        protected override View GetView(int position, View convertView, ViewGroup parent, int templateId)
        {

            var theView = base.GetView(position, convertView, parent, templateId);

            var item = GetRawItem(position);

            if (item is JobWithTabsViewModel.PointOfInterestFeature)
            {
                if (theView != null)
                {
                    var iv = theView.FindViewById<ImageView>(Resource.Id.card_thumbnail_image);
                    // Manually Bind From Here
                }
                else
                {
                    theView = GetBindableView(convertView, item, templateId);
                    // Manually Bind From Here
                }
            }
            return theView;
        }

Upvotes: 2

Views: 1755

Answers (2)

wainy
wainy

Reputation: 435

For future reference, this is how I tackled binding within the adapter:

The convertView is an IMvxBindingContextOwner, as set in the base.GetBindableView().

If convertView is cast to this, the binding methods, such as CreateBinding are available.

You can then create a binding for any view within ConvertView, but I also had to call BindBindableView() if the convertView!=null to ensure that the data is refereshed when the list item is being re-used. My requirement was to only bind an imageview when the source was of a particular type.

protected override View GetBindableView(View convertView, object source, int templateId)
{
    if (convertView == null)
    {
        convertView = base.GetBindableView(convertView, source, templateId);

        if (source is JobWithTabsViewModel.PictureFeature)
        {
            var imageView = convertView.FindViewById<MvxImageView>(Resource.Id.card_thumbnail_image);

            var owner = convertView as IMvxBindingContextOwner;
            owner.CreateBinding(imageView).For("Bitmap").To("TheRawImageBytes").WithConversion("InMemoryImage").Apply();
        }
    }
    else
    {
        BindBindableView(source, convertView as IMvxListItemView);
    }

    return convertView;
}

Upvotes: 6

Cheesebaron
Cheesebaron

Reputation: 24470

CreateBindingSet is located in the namespace Cirrious.MvvmCross.Binding.BindingContext. The reason your IDE might have a hard time finding it is because it is a extension method.

Setting the adapter is done with:

var listView = FindViewById<MvxListView>(Resource.Id.listView);
var adapter = new MyAdapter(..);
listView.Adapter = adapter;

Upvotes: 1

Related Questions