Stephen York
Stephen York

Reputation: 1439

.NET MAUI - Pass CollectionView item index to command

I have a CollectionView that I can add Euipment items to. If the user adds too many I want to be able to remove them. enter image description here

When the red button is pressed how do I pass the index of the item in the ItemsSource to the RemoveEquipmentCommand?

<CollectionView ItemsSource="{Binding NewLogEntry.EquipmentDetails}"
                SelectionMode="None">
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="model:EquipmentDetails">
            <Frame Margin="0,0,0,10">
                <VerticalStackLayout>
                    <Grid ColumnDefinitions="*,Auto">
                        <Picker Title="Pick Component Type"
                            ItemsSource="{Binding Source={RelativeSource AncestorType={x:Type viewModel:AddLogEntryViewModel}}, Path=ComponentTypes}"
                            SelectedItem="{Binding ComponentType}"
                            Style="{StaticResource MediumLabel}"
                            HorizontalOptions="Center"
                            Grid.Column="0" />

                        <Button Text="x"
                                BackgroundColor="Red"
                                Grid.Column="1"
                                Command="{Binding RemoveEquipmentCommand}" />
                    </Grid>

I know that there's a gesture recognizer to make it a swipe left to delete function, but they're not supported on the Windows Application platform. I would still need this delete button on the desktop application.

Upvotes: 1

Views: 4254

Answers (1)

Jessie Zhang -MSFT
Jessie Zhang -MSFT

Reputation: 13919

We generally do not get the index of the data, because if we change the data, the value of the index will always change.

We can get the selected item by passing the item to the CommandParameter.

I created a demo to achieve this function, you can refer to the following code:

The xaml:

   <?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiCollectionApp.MainPage"
              xmlns:local="clr-namespace:MauiCollectionApp"
             x:Name="myPage"
             >

    <ContentPage.BindingContext>
        <local:MyViewModel></local:MyViewModel>
    </ContentPage.BindingContext>


   <CollectionView  ItemsSource="{ Binding Data}" x:Name="mCollectionView" >
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <HorizontalStackLayout  Margin="3" >
                             <Label Text="{Binding Name}" BackgroundColor="Gray"/>
                             

                           <Button Text="delete"  Margin="10,0,0,0"
                                BackgroundColor="Red"
                                Command="{Binding  Path= BindingContext.RemoveEquipmentCommand,Source={Reference mCollectionView }}"  CommandParameter="{Binding .}"  
                                 />
                       </HorizontalStackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
   </CollectionView>

</ContentPage>

MyViewModel.cs

public class MyViewModel: INotifyPropertyChanged 
    {
       public  ObservableCollection<MyModel> Data {get;set;}

        public ICommand RemoveEquipmentCommand => new Command<MyModel>(ReMoveItem);

        private void ReMoveItem(MyModel obj)
        {
            System.Diagnostics.Debug.WriteLine(" the selected item's name  is:  " + obj.Name   );
             // Here we can remove the seletced obj from the data
             Data.Remove(obj);
        }

        public MyViewModel() {
            Data = new ObservableCollection<MyModel>();

            Data.Add(new MyModel { Name ="model_1", Car= new Vehicle {Make="Make1" } });
            Data.Add(new MyModel { Name = "model_2", Car = new Vehicle { Make = "Make2" } });
            Data.Add(new MyModel { Name = "model_3", Car = new Vehicle { Make = "Make3" } });
            Data.Add(new MyModel { Name = "model_4", Car = new Vehicle { Make = "Make4" } });


        }

        bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (Object.Equals(storage, value))
                return false;

            storage = value;
            OnPropertyChanged(propertyName);
            return true;
        }

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

Upvotes: 2

Related Questions