1
votes

I saw an article on xamarin forms with some "Bindable love" https://blog.xamarin.com/xamarin-forms-3-5-a-little-bindable-love/.

I wanted to try it out and create a scrolling list but for some reason, the data that i am binding does not seem to appear in the view. The binding should work fine because in my XAML i bind plenty of other things and it works successfully, but for some reason this particular binding is not working.

XAML:

<ScrollView>
   <StackLayout BackgroundColor="Transparent" BindableLayout.ItemsSource="{Binding CategoriesList}"  >
                <BindableLayout.ItemTemplate>
                        <DataTemplate>         
                           <StackLayout Orientation = "Horizontal" HeightRequest="150" WidthRequest="80">

                                <Button Text="{Binding Name}" />

                         </StackLayout>
                       </DataTemplate>
                </BindableLayout.ItemTemplate>          
             </StackLayout>
        </ScrollView>

This is how my list looks in the VM:

private ObservableCollection<Categories> _Categories;
    public ObservableCollection<Categories> CategoriesList
    {
        get
        {
            return this._Categories;
        }
        set
        {
            if (_Categories != value)
            {
                this._Categories = value;
                RaisePropertyChanged("CategoriesList");
            }
        }
    }

And when i create data to it:

        CategoriesList = new ObservableCollection<Categories>();

        CategoriesList.Add(new Categories() { Name = "Data 1", ID = "1" });
        CategoriesList.Add(new Categories() { Name = "Data 2", ID = "2" });
        CategoriesList.Add(new Categories() { Name = "Data 3", ID = "3" });
1

1 Answers

2
votes

I guess there is an issue with your getter and setter. It is not properly updating the value once it is changed. I have done by using INotifyPropertyChanged and it is working fine.

MainPage.xaml:

    <?xml version="1.0" encoding="utf-8"?>
<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:App"
    x:Class="App.MainPage">
    <ContentPage.Content>
        <ScrollView HorizontalOptions="FillAndExpand">
            <StackLayout
                HorizontalOptions="FillAndExpand"
                BackgroundColor="Transparent"
                BindableLayout.ItemsSource="{Binding CategoriesList}">
                <BindableLayout.ItemTemplate>
                    <DataTemplate>
                        <StackLayout
                            Orientation="Horizontal"
                            HeightRequest="150"
                            HorizontalOptions="FillAndExpand">
                            <Button
                                Text="{Binding Name}" />
                        </StackLayout>
                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </StackLayout>
        </ScrollView>
    </ContentPage.Content>
</ContentPage>

MainPage.xaml.cs:

  namespace App
  {
    public partial class MainPage : ContentPage
    {

        public MainPage()
        {
            InitializeComponent();
            BindingContext = new MainPageViewModel();
        }

    }
}

MainPageViewModel:

 public class MainPageViewModel : BaseViewModel
{
    private ObservableCollection<CategoriesModel> _Categories;
    public ObservableCollection<CategoriesModel> CategoriesList
    {
        get
        {
            return this._Categories;
        }
        set
        {
            if (_Categories != value)
            {
                this._Categories = value;
                SetPropertyValue(ref _Categories, value);

            }
        }
    }

    public MainPageViewModel()
    {

        CategoriesList = new ObservableCollection<CategoriesModel>
        {
            new CategoriesModel() { Name = "Data 1", ID = "1" },
            new CategoriesModel() { Name = "Data 2", ID = "2" },
            new CategoriesModel() { Name = "Data 3", ID = "3" },
            new CategoriesModel() { Name = "Data 4", ID = "4" },
            new CategoriesModel() { Name = "Data 5", ID = "5" },
            new CategoriesModel() { Name = "Data 6", ID = "6" },
            new CategoriesModel() { Name = "Data 7", ID = "7" }
        };
    }
}

My BaseViewModel which extent the INotifyPropertyChanged:

public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanges([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    protected void SetPropertyValue<T>(ref T bakingFiled, T value, [CallerMemberName] string proertyName = null)
    {
        bakingFiled = value;
        OnPropertyChanges(proertyName);

    }

}

All the view model class extend the BaseViewModel in order to access the SetPropertyValue() method.

Output:

OutPut