Custom ItemsSource bindable property

CalvinMorooney.2531CalvinMorooney.2531 USMember
edited February 2017 in Xamarin.Forms

I'm working on a control for my application that I'd like to have an ItemsSource bindable property that behaves like the stock ListView. I have a backing property of ObservableCollection but am not seeing the bindable property observe when I add or remove elements to that collection.

Here is my bindable property in my custom control (for now just doing simple console writes for POC

public static readonly BindableProperty ItemsSourceProperty =
            BindableProperty.Create (nameof (ItemsSource), typeof (IEnumerable), typeof (MyControl), null,
                                     BindingMode.Default, null, OnItemsSourceChanged);

public IEnumerable ItemsSource
{
    get { return (IEnumerable) GetValue (ItemsSourceProperty); }
    set { SetValue (ItemsSourceProperty, value); }
}

static void OnItemsSourceChanged (BindableObject bindable, object oldvalue, object newvalue)
{
    System.Diagnostics.Debug.WriteLine ("source changed");
}

and the XAML in my view using this control

<local:MyControl ItemsSource="{Binding Models}"

and here is the property that is bound in the VM

ObservableCollection<MyModel> _models;
public ObservableCollection<MyModel> Models
{
    get { return _models; }
    set { SetProperty (ref _models, value); }
}

When I initially set my Models property to a new ObservableCollection, I see the console write in the control. However, when I Add an item to the collection, I don't see that the control is aware of the collection change. I've looked at ListView and ItemsView in the Forms repo but haven't been able to figure out what I'm doing wrong and I think I just need a second pair of eyes...I should note that I'm using the latest Prism library, so their implementation of SetProperty is what I'm using in my VM

Answers

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Adding and removing items requires that you also handle INotifyCollection changed.
    I'm guessing that you're only handling INotifyPropertyChanged, meaning when you assign the entire collection you're getting notificaiton but not when you change elements within the collection property.

    This article on Reusable Controls should help you out.

  • TobnilTobnil SEMember ✭✭

    @ClintStLaurent said:
    Adding and removing items requires that you also handle INotifyCollection changed.
    I'm guessing that you're only handling INotifyPropertyChanged, meaning when you assign the entire collection you're getting notificaiton but not when you change elements within the collection property.

    This article on Reusable Controls should help you out.

    Sorry for stealing the thread a bit, but I am facing the same problem.

    How can i connect the Collection changes? I read the article, and it helped a bit. But I am still a bit confused.

    In my ViewModel CartViewModel i have an ObservableCollection that is the one getting all the changes (added stuff in the cart, removed stuff and so on).
    On this collection I can get a hold of the "CollectionChanged" which fires every time i change the list in some way.

    But how about the ObservableCollection i have bound in my custom class with my own BindableProperty ItemSource?
    I can, as the OP can, snap up events with properyChanged where the whole ObservableCollection is changed like "CartItems = new ObservableCollection();"

    But just modifying the CartItems isn't doing anything with my ItemSource-list

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    In your custom control, in the property changed handler for the ItemsSource, you check if the source implements INotifyCollectionChanged.

    If it does, subscribe to the collection changed event in the control, then handle doing whatever you need to do in that handler.

Sign In or Register to comment.