I suspect a combination of the two reason is to blame:
- You have accidentally replaced the instance of the
ObservableCollection
without calling OnPropertyChanged - You are using hot reload with a XAML-instantiated BindingContext
I highly discourage you from setting BindingContext in XAML like that. This is because Xamarin will reload the the XAML and you can end up with duplicates of the BindingContext. Please visit https://devblogs.microsoft.com/xamarin/tips-tricks-xaml-hot-reload/ and read the Making the Most of MVVM section.
Fixing Things Up
Please take the following steps so that you can start on solid ground and eliminate basic problems.
Step 1. Delete this
<ContentPage.BindingContext>
<vm:Azioni_Righe></vm:Azioni_Righe>
</ContentPage.BindingContext>
Step 2. Set the BindingContext
after InitializeComponent() in the page's constructor, like this
using Xamarin.Forms;
namespace Goal.Funzioni
{
public partial class YourPage : ContentPage
{
public YourPage()
{
InitializeComponent();
// Set the BindingContext here
BindingContext = new Azioni_Righe();
}
}
}
This does not break MVVM. It just makes sure that the view model is only instantiated once
Loading data
Okay, now let's move onto the point where you want to load data using the OnAppearing method. Let's start with the assumption that you have a valid ObservableCollection
in the view model and it is ready to accept the data.
public class Azioni_Righe
{
public Azioni_Righe()
{
Names = new ObservableCollection<string>();
}
// This is a READONLY property so that you do not accidentally replace the collection
public ObservableCollection<string> Names { get; }
public async Task LoadDataAsync()
{
// Clear any old data
Names.Clear();
// Get new data
var data = myApi.FetchData();
// Add the new data to the ObservableColleciton
foreach(name in data)
{
Names.Add(name);
}
}
}
Notice that the Names ObservableCollection is a readonly property (i.e. it only has a getter). This is important so that you do not accidentally reset it without using
INotifyPropertyChanged
. If you do want to replace the instance, you need to add a backing field for the ObservableCollection and invokeOnPropertyChanged
in the setter.
Now you can call your LoadDataAsync
method in the page's OnAppearing
override
namespace Goal.Funzioni
{
public partial class YourPage : ContentPage
{
public YourPage()
{
InitializeComponent();
// Set the BindingContext here
BindingContext = new Azioni_Righe();
}
protected override OnAppearing(...)
{
await (BindingContext as Azioni_Righe).LoadDataAsync();
}
}
}