Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding Context to ListView does not work

I can't seem to display data to my listview via a BindingContext. The listview displays as blank. The code is below.

ViewModel:

public class DiscountPageViewModel
{
    //initalize variables here
    RestService service = new RestService();
    public List<DiscountModel> lister = new List<DiscountModel>();

    public DiscountPageViewModel()
    {
        Get_Data();
    }

    //get data
    async void Get_Data()
    {
        lister = await service.Get_Data<DiscountModel>("discount");

    }

}

View (.cs):

public partial class DiscountPage : ContentPage
{
    public DiscountPage()
    {
        InitializeComponent();

        BindingContext = new DiscountPageViewModel();
    }
}

View (XAML):

<ContentPage.Content>

    <StackLayout>

        <StackLayout Margin="12, 5, 12, 0">
            <Entry Placeholder="Search..."/>
        </StackLayout>

        <StackLayout>
            <ListView BindingContext="{Binding lister}">
                <ListView.ItemTemplate>
                    <DataTemplate >
                        <TextCell Text="{Binding name}" Detail="{Binding code}"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>

    </StackLayout>

</ContentPage.Content>

The API call works and data is being displayed elsewhere. I am trying to learn MVVM but I seem to be stuck here. The model has the properties code and name. Much help would be appreciated. Thank you!

like image 435
lrnc_vlsc Avatar asked Sep 09 '26 04:09

lrnc_vlsc


2 Answers

To update the items in your ListView after the BindingContext is set you will have to use a ObservableCollection.

Change this line

public List<DiscountModel> lister = new List<DiscountModel>();

to

public ObservableCollection<DiscountModel> lister = new ObservableCollection<DiscountModel>();

It is important that you don't create a new list afterwards.

So instead of this:

//get data
async void Get_Data()
{
    lister = await service.Get_Data<DiscountModel>("discount");
}

Implement something like this:

//get data
async void Get_Data()
{
    var results = await service.Get_Data<DiscountModel>("discount");

    lister.Clear();

    foreach (var item in results)
        lister.Add(item);
}

The reason for this, is that when you get into data-binding you will have to implement the INotifyPropertyChanged interface on your objects. This will signal the UI that a property value is changed and the UI needs to be updated. In terms of collections, use the ObservableCollection which has the collection variation of the INotifyPropertyChanged.

like image 104
Gerald Versluis Avatar answered Sep 10 '26 18:09

Gerald Versluis


You better take a look at these MVVM tutorials first:

From Data Bindings to MVVM

MVVM & Data Binding with Xamarin.Forms

Learn MVVM

public class DiscountPageViewModel : INotifyPropertyChanged
{
    private ObservableCollection<DiscountModel> _lister;

    public event PropertyChangedEventHandler PropertyChanged;

    //initalize variables here
    RestService service = new RestService();

    public ObservableCollection<DiscountModel> lister
    {
        get => _lister;
        set
        {
            _lister = value;
            OnPropertyChanged();
        }
    }
    public DiscountPageViewModel()
    {
        Get_Data();
    }

    //get data
    async void Get_Data()
    {
        lister = await service.Get_Data<DiscountModel>("discount");
    }

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

}
like image 31
VahidShir Avatar answered Sep 10 '26 17:09

VahidShir



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!