Reputation: 1439
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.
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
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