lrnc_vlsc
lrnc_vlsc

Reputation: 45

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!

Upvotes: 3

Views: 3373

Answers (3)

LeanManager
LeanManager

Reputation: 86

It's a simple fix. In your XAML file, instead of setting the BindingContext property of your ListView, set the ItemsSource property instead:

<ListView ItemsSource="{Binding lister}">

This will automatically set the binding context of the ListView to the collection in your ViewModel. Currently the ItemsSource property is null, that's why the collection was not displaying in your view.

Upvotes: 1

VahidShir
VahidShir

Reputation: 2106

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)));
    }

}

Upvotes: 2

Gerald Versluis
Gerald Versluis

Reputation: 33993

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.

Upvotes: 5

Related Questions