Reputation: 336
How can I add a full template click handler for each item in a MAUI CollectionView?
I have seen the documentation about TapGestureRecognizer but it is not clear to me how to do it for a competitive element, for example in my case inside a HorizontalStackLayout
<CollectionView ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{x:Type dtos:ItemDto}">
<HorizontalStackLayout>
<Image WidthRequest="75" HeightRequest="75" Source="item_default.png"></Image>
<StackLayout Orientation="Vertical">
<Label Text="{Binding Name}" FontSize="Title" />
<Label Text="{Binding Description}" FontSize="Subtitle"/>
</StackLayout>
</HorizontalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
What I want is to open a detail view of each item in case of pressing on it.
Side note: I'm also using CommunityToolkit (MVVM and MAUI ones)
Any ideas? Many thanks!
Upvotes: 1
Views: 4707
Reputation: 336
Thanks to the comment provided at the beginning from @Jason, at the end I opted for a simple approach with the events of the CollectionView:
XAML:
<CollectionView
ItemsSource="{Binding Items}"
SelectionMode="Single" x:Name="ItemsCollectionView"
SelectionChangedCommand="{Binding ClickCommand}"
SelectionChangedCommandParameter="{Binding SelectedItem, Source={x:Reference ItemsCollectionView}}"
ViewModel
[RelayCommand]
private async Task ClickAsync(PlaceDto place)
{
//Handle logic
}
Thanks all for the comment and suggestions
Upvotes: 2
Reputation: 13879
Suppose there is a button on the DataTemplate
of CollectionView, and if we click the button ,the current item will be removed from the list.
You can refer to the following code:
MainPage.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"
xmlns:MauiMvvmApp="clr-namespace:MauiMvvmApp226"
x:Class="MauiMvvmApp226.MainPage">
<ContentPage.BindingContext>
<MauiMvvmApp:TestViewModel></MauiMvvmApp:TestViewModel>
</ContentPage.BindingContext>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Start">
<CollectionView ItemsSource="{Binding Items}" x:Name="mCollectionView">
<CollectionView.ItemTemplate>
<DataTemplate>
<HorizontalStackLayout >
<StackLayout Orientation="Vertical">
<Label Text="{Binding Name}" FontSize="Title" />
<Label Text="{Binding Description}" FontSize="Subtitle"/>
</StackLayout>
<Button Text="Remove" Command="{Binding BindingContext.DeleteItemCommand, Source={x:Reference mCollectionView}}" CommandParameter="{Binding .}" Margin="10,0,10,0" WidthRequest="80" HorizontalOptions="End"/>
</HorizontalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
</ContentPage>
TestViewModel.cs
public partial class TestViewModel : ObservableObject
{
[ObservableProperty]
private ObservableCollection<ItemModel> items;
public TestViewModel()
{
PopulateObservableCollection();
}
public void PopulateObservableCollection()
{
Items = new ObservableCollection<ItemModel>();
try
{
Items.Add(new ItemModel { Name = "test1",Description= "Description 1" });
Items.Add(new ItemModel { Name = "test2", Description = "Description 2" });
Items.Add(new ItemModel { Name = "test3", Description = "Description 3" });
}
catch (Exception)
{ }
}
[RelayCommand]
private async Task DeleteItem(ItemModel obj)
{
try
{
if (Items != null && Items.Contains(obj))
{
Items.Remove(obj);
}
}
catch (Exception ex)
{
await Shell.Current.DisplayAlert("Alert", ex.ToString(), "Cancel");
}
finally
{
}
}
}
ItemModel.cs
public class ItemModel
{
public string Name { get; set; }
public string Description { get; set; }
}
Update
If you want to add a tap gesture on the item of the collectionview, you can refer to the following code:
<CollectionView ItemsSource="{Binding Items}" x:Name="mCollectionView">
<CollectionView.ItemTemplate>
<DataTemplate>
<HorizontalStackLayout >
<HorizontalStackLayout.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding BindingContext.DeleteItemCommand, Source={x:Reference mCollectionView}}" CommandParameter="{Binding .}">
</TapGestureRecognizer>
</HorizontalStackLayout.GestureRecognizers>
<StackLayout Orientation="Vertical">
<Label Text="{Binding Name}" FontSize="Title" />
<Label Text="{Binding Description}" FontSize="Subtitle"/>
</StackLayout>
<!-- <Button Text="Remove" Command="{Binding BindingContext.DeleteItemCommand, Source={x:Reference mCollectionView}}" CommandParameter="{Binding .}" Margin="10,0,10,0" WidthRequest="80" HorizontalOptions="End"/>-->
</HorizontalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Upvotes: 0