Narender Reddy
Narender Reddy

Reputation: 145

Xamarin Forms Collection view ItemsSource Binding not updating the UI

Xamarin.Forms 4.0 collection view ItemsSource binding is not working as expected if I set the binding in code behind. The items are displayed based on the initial value of the source collection but, the UI is not updating when the source collection is updated. Same is working if I set the binding in xaml.

Code behind:

    public MainPage()
    {
        this.InitializeComponent();
        this.BindingContext = this.mainViewModel = new MainViewModel();


        CollectionView courseCollectionView = new CollectionView
        {
            ItemSizingStrategy = ItemSizingStrategy.MeasureFirstItem,
            ItemTemplate = new DataTemplate(typeof(ItemView))
        };


     courseCollectionView.SetBinding(CollectionView.ItemsSourceProperty, 
     new Binding() { Source = this.mainViewModel.CountryNames, Mode = 
     BindingMode.TwoWay });

     courseCollectionView.ItemsLayout = new GridItemsLayout(4, 
      ItemsLayoutOrientation.Vertical);

        this.CoursesStack.Children.Clear();
        this.CoursesStack.Children.Add(courseCollectionView);

    }

View Model Property which is using for ItemsSource Binding:

   ObservableCollection<Country> countryNames;

    public ObservableCollection<Country> CountryNames
    {
        get => this.countryNames;
        set
        {
            this.countryNames = value;
            RaisePropertyChanged("CountryNames");
        }
    }

Expected: View should be updated as per the changes made to the ObsevableCollection (add/delete items from collection) which is bound to the ItemsSource Property.

Actual: View is not updated with changes to the ObservableCollection.

Upvotes: 4

Views: 12729

Answers (3)

Cherry Bu - MSFT
Cherry Bu - MSFT

Reputation: 10346

About updating UI when using CollectionView, I do one sample that you can take a look:

public partial class MainPage : ContentPage
{
    public mainvidemodel viewmodel { get; set; }
    public MainPage()
    {
        InitializeComponent();
        viewmodel = new mainvidemodel();
        this.BindingContext = viewmodel;

        CollectionView collectionView = new CollectionView();

        collectionView.SetBinding(ItemsView.ItemsSourceProperty, "countries");

        collectionView.ItemTemplate = new DataTemplate(() =>
        {
            StackLayout stacklayout = new StackLayout();

            Label label1 = new Label();
            label1.SetBinding(Label.TextProperty,"Id");

            Label label2 = new Label();
            label2.SetBinding(Label.TextProperty, "Name");

            Label label3 = new Label();
            label3.SetBinding(Label.TextProperty, "caption");


            stacklayout.Children.Add(label1);
            stacklayout.Children.Add(label2);

            stacklayout.Children.Add(label3);
            return stacklayout;

        });
        Button btn = new Button() { Text = "btn", WidthRequest = 200, HeightRequest = 50 };
        btn.Clicked += Btn_Clicked;
        stacklayout1.Children.Add(collectionView);
        stacklayout1.Children.Add(btn);

    }

    private void Btn_Clicked(object sender, EventArgs e)
    {
        viewmodel.countries.Add(new Country()  { Id = 8, Name = "country8", caption = "caption 8" });
    }
}
public class mainvidemodel
{
    public ObservableCollection<Country> countries { get; set; }
    public mainvidemodel()
    {
        countries = new ObservableCollection<Country>()
        {
            new Country(){Id=1,Name="country1",caption="caption 1"},
            new Country(){Id=2,Name="country2",caption="caption 2"},
            new Country(){Id=3,Name="country3",caption="caption 3"},
            new Country(){Id=4,Name="country4",caption="caption 4"},
            new Country(){Id=5,Name="country5",caption="caption 5"},
            new Country(){Id=6,Name="country6",caption="caption 6"},
            new Country(){Id=7,Name="country7",caption="caption 7"},

        };

    }
}
public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string caption { get; set; }
}

enter image description here

Upvotes: 2

ottermatic
ottermatic

Reputation: 1012

I believe your binding is wrong. Try: courseCollectionView.SetBinding(CollectionView.ItemsSourceProperty, nameof(mainViewModel.CountryNames));

You need to specify the Path (mainViewModel.CountryNames) and not the Source

Upvotes: 2

Afonso
Afonso

Reputation: 75

In this case try to extend the MainPage from INotifyPropertyChanged and instead of RaisePropertyChanged("CountryNames") in set property, use OnPropertyChanged()

Upvotes: 0

Related Questions