Jelmer Beerling
Jelmer Beerling

Reputation: 57

Clearing a listview for duplicate items

I'm trying to build a listview from the items found with DeviceDiscovered, it works though when i navigate back to the main page, and search again the listview gets duplicate items. What i thought was the easiest solution was to just clear the whole deviceList if it exists. Though it isn't working.

I've also tried setting listview.ItemsSource = null, and then setting it to deviceList again. But i still get duplicate items.

public App()
    {

        // The root page of your application
        var button = new Button
        {
            Text = "Search devices",
        };
        button.Clicked += Search_Devices;

        var content = new ContentPage
        {
            Title = "BluetoothApp",
            Content = new StackLayout
            {
                VerticalOptions = LayoutOptions.Fill,
                Children = { button }
            }
        };

        MainPage = new NavigationPage(content);
    }

private async void Search_Devices(object sender, EventArgs e)
    {
        //Get bluetooth adapter
        var ble = CrossBluetoothLE.Current;
        adapter = CrossBluetoothLE.Current.Adapter;

        //Clear devicelist when it exists
        if (deviceList != null)
        {
            deviceList.Clear();
        }

        //Create devicelist
        deviceList = new List<Plugin.BLE.Abstractions.Contracts.IDevice>();
        adapter.DeviceDiscovered += async (s, a) =>
        {
            deviceList.Add(a.Device);
        };
        await adapter.StartScanningForDevicesAsync();

        //Create listview from devices
        ListView listview = new ListView();
        listview.ItemsSource = deviceList;
        listview.ItemTapped += Listview_ItemTapped;

        ContentPage devices_page = new ContentPage
        {
            Title = "Devices",
            Content = new StackLayout
            {
                VerticalOptions = LayoutOptions.Fill,
                Children = { listview }
            }
        };
        await MainPage.Navigation.PushAsync(devices_page);
    }

edit: added where Search_Button is called

Upvotes: 0

Views: 899

Answers (2)

EvZ
EvZ

Reputation: 12179

I would recommend to check https://github.com/jamesmontemagno/mvvm-helpers
It has a ObservableRangeCollection which contains Replace and ReplaceRange.

The source: https://github.com/jamesmontemagno/mvvm-helpers/blob/master/MvvmHelpers/ObservableRangeCollection.cs

Upvotes: 1

cvanbeek
cvanbeek

Reputation: 1961

I had a similar problem in an app I was working on, to get around the issue of items appearing multiple times after the page is put back into focus, I created a separate method called refresh() which I called from the overridden OnAppearing() method.

In the refresh method itself, declare your List to be a new list, that way every time it is called, you always start with a clean, new, and empty List.

async void refresh()
{
    deviceList = new List<Plugin.BLE.Abstractions.Contracts.IDevice>();
    //populate the list
    listview.ItemSource = deviceList;
}

If that doesn't work for you, you can always create a loop that checks if an item is already in the list, and only add it if there isn't an existing one already.

adapter.DeviceDiscovered += async (s, a) =>
{
    if(!deviceList.Contains(a.Device)
        deviceList.Add(a.Device);
};

Upvotes: 0

Related Questions