Search code examples
android.netcommandmauicollectionview

problem deleting Item in collectionView .NET Maui


I´m trying to delete an object named SelectedOrder in TableData of my viewmodel. Binding works perfectly but when I tapped de Item to be deleted, in my viewmodel the variable SelectedOrder is null when te RelayCommand is activated... Could you tell me why?

 <CollectionView
     ItemsSource="{Binding Orders}"
     SelectedItem="{Binding SelectedOrder}">
     <CollectionView.ItemTemplate>
         <DataTemplate>                       
                 <Frame>
                 <Frame.GestureRecognizers>
                     <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodels:MainPageViewModel}}, Path=DeleteOrderCommand}" NumberOfTapsRequired="1" />
                 </Frame.GestureRecognizers>
                 <Label
                     FontSize="Medium"
                     HorizontalOptions="Start"
                     Text="{Binding Id}"
                     VerticalTextAlignment="Center" />                               
                 </Frame>                       
         </DataTemplate>
     </CollectionView.ItemTemplate>
     <CollectionView.ItemsLayout>
         <LinearItemsLayout ItemSpacing="5" Orientation="Vertical" />
     </CollectionView.ItemsLayout>
 </CollectionView>
 [ObservableProperty]
 private Order selectedOrder;


 [RelayCommand]
 private async Task DeleteOrder()
 {          
     App.OrdersRepo.TestDeleteItem(SelectedOrder);

     Orders = await App.OrdersRepo.TestGetItems();
 }

Where is the problem?


Solution

  • Based on your code, I created a demo on my side, I find that if we trigger event of Frame.GestureRecognizers of the outer Frame, then the event of SelectionChangedCommand of CollectionView will not be triggered. So, the value of SelectedOrder will not be updated once tapping the Frame.

    But as a workaround, you can pass the current Item to event DeleteOrderCommand.

    You can add CommandParameter="{Binding .}" for the TapGestureRecognizer of the Frame.

    Please refer to the following code:

            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Frame BackgroundColor="pink" >
                        <Frame.GestureRecognizers>
                            <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type local:MainPageViewModel}}, Path=DeleteOrderCommand }" CommandParameter="{Binding .}" NumberOfTapsRequired="1"  />
                        </Frame.GestureRecognizers>
                        <Label
                     FontSize="Medium"
                     HorizontalOptions="Start"
                     Text="{Binding Id}"
                     VerticalTextAlignment="Center" />
    
                    </Frame>
                </DataTemplate>
            </CollectionView.ItemTemplate>
    

    And then add a parameter to method DeleteOrder

        [RelayCommand]
        private async Task DeleteOrder(Order obj)
        {
            // do something
             
             
            //App.OrdersRepo.TestDeleteItem(obj);
    
            // Orders = await App.OrdersRepo.TestGetItems();
    
        }