Reputation: 45
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
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
Reputation: 2106
You better take a look at these MVVM tutorials first:
MVVM & Data Binding with Xamarin.Forms
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
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