Search code examples
c#xamarinxamarin.formsxamarin.androidxamarin.ios

Xamarin Forms ListView stays empty after filling the source


I have a problem. I created a ListView with as itemsource a List called unknownDeviceList from my ViewModel. Here is my ViewModel:

public class VM_AddDeviceList : BindableObject
{
    private List<UnknownDevice> _unknownDeviceList;
    public List<UnknownDevice> unknownDeviceList
    {
        get
        {
            return _unknownDeviceList;
        }
        set
        {
            if (_unknownDeviceList != value)
            {
                _unknownDeviceList = value;
                OnPropertyChanged();
            }
        }
    }

    public List<UnknownDevice> deviceList_raw;

    public VM_AddDeviceList()
    {
        deviceList_raw = new List<UnknownDevice>();
        unknownDeviceList = new List<UnknownDevice>();
        MyHandler();
    }

    private async Task LoadUnknownDeviceList()
    {
        deviceList_raw = await App.RestService.GetDevices();

        foreach (UnknownDevice device in deviceList_raw)
        {
            bool containsItem = App.knownDeviceList.Any(item => item.MAC == device.MAC);

            if (!containsItem)
            {
                unknownDeviceList.Add(device);
            }
        }
    }

    public Task MyHandler()
    {
        return LoadUnknownDeviceList();
    }
}

Now I can see that unknownDeviceList gets filled in the foreach, but on the screen the ListView stays empty. What am I doing wrong? Something with the async and await?


Solution

  • You are raising PropertyChanged when setting unknownDeviceList to inform the view that the list has changed. Anyway, there is no way for the view to know that there were items added to unknownDeviceList.

    The most idiomatic way to solve the issue would be to use an ObservableCollection<string> instead.

    private ObservableCollection<string> _unknownDevices = new ObservableCollection<string>();
    
    public ObservableCollection<string> UnknownDevices => _unknownDevices;
    

    Please note that I've used the expression body syntax for read-only properties for UnknownDevices, it's not a field.

    Since ObservableCollection<string> implements INotifyCollectionChanged which can be subscribed to by the binding to UnknownDevices the view is informed about the changes in UnknownDevices and will be updated when any items are added or removed.