Search code examples
c#sqlxamarin.formsduplicatessql-delete

SQL Xamarin Forms Delete Item Duplication


I have an application where items are added to a collection view which is swipable to be deleted. I am using SQL to do so. However, when deleting the item, sometimes the items have 'duplicated' until a refresh happens and then they disappear once again. How do I go about fixing this issue and why does it only occur sometimes? (See below for bug).

Here is the Xaml:

<RefreshView x:DataType="local:ItemsViewModel" Command="{Binding LoadItemsCommand}" IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
    <CollectionView x:Name="ItemsListView"
            ItemsSource="{Binding Items}"
            SelectionMode="None">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                 <SwipeView>
                    <SwipeView.RightItems>
                        <SwipeItems Mode="Execute">
                            <SwipeItem Text="Delete" 
                                       BackgroundColor="Red"
                                       Command="{Binding Source={RelativeSource AncestorType={x:Type local:ItemsViewModel}}, Path=DeleteItemCommand}"
                                       CommandParameter="{Binding Source={RelativeSource Self}, Path=BindingContext}"/>
                        </SwipeItems>
                    </SwipeView.RightItems>
                    <StackLayout Padding="10" x:DataType="model:Item" BackgroundColor="#333333">
                        <Label Text="{Binding Text}"
                               LineBreakMode="NoWrap" 
                               Style="{DynamicResource ListItemTextStyle}" 
                               FontSize="16"
                               FontAttributes="Bold"
                               TextColor="White"/>
                        <Label Text="{Binding Description}" 
                               LineBreakMode="NoWrap"
                               Style="{DynamicResource ListItemDetailTextStyle}"
                               FontSize="13"
                               TextColor="White"/>
                        <Label Text="{Binding DueDate}"
                               Style="{DynamicResource ListItemDetailTextStyle}"
                               FontSize="13"
                               TextColor="White"/>
                        <StackLayout.GestureRecognizers>
                            <TapGestureRecognizer 
                            NumberOfTapsRequired="1"
                            Command="{Binding Source={RelativeSource AncestorType={x:Type local:ItemsViewModel}}, Path=ItemTapped}"     
                            CommandParameter="{Binding .}">
                            </TapGestureRecognizer>
                        </StackLayout.GestureRecognizers>
                   </StackLayout>
                </SwipeView>
            </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
</RefreshView>

Here is the delete function:

private async Task OnDeleteItem(Item selectedItem)
{
    await LocalDatabaseService.DeleteItem(selectedItem);
}

SQL Delete:

public async Task DeleteItem(Item item)
{
    var databasePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "MyData3.db");
    var db = new SQLiteAsyncConnection(databasePath);

    await db.DeleteAsync(item);
    OnDeletedItem?.Invoke();
}

OnDeleteItem?.Invoke();

private void LocalDatabaseService_OnDeletedItem()
{
    _ = ExecuteLoadItemsCommand();
}

ExecuteLoadItemsCommand();

async Task ExecuteLoadItemsCommand()
{
    IsBusy = true;

    try
    {
        Items.Clear();
        var items = await LocalDatabaseService.GetAllItems();
        foreach (var item in items)
        {
            Items.Add(item);
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex);
    }
    finally
    {
        IsBusy = false;
    }
}

Here is what happens occasionally: enter image description here

any help is appreciated, Thanks.


Solution

  • You have reset IsBusy two times, one is in funtion OnAppearing and another one is in function ExecuteLoadItemsCommand. So the code in function ExecuteLoadItemsCommand will been triggered two times once deleting an item.

    You can try to remove code IsBusy = true; in function ExecuteLoadItemsCommand:

        async Task ExecuteLoadItemsCommand()
        {
          //  IsBusy = true;
    
            try
            {
                Items.Clear();
             
                var items = await LocalDatabaseService.GetAllItems();
    
    
                foreach (var item in items)
                {
                    Items.Add(item);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            finally
            {
                IsBusy = false;
            }
        }