英文:
How to add on Click event on entire DataTemplate inside MAUI Collection View
问题
如何为MAUI CollectionView中的每个项目添加完整的模板点击处理程序?
我已经看过有关TapGestureRecognizer的文档,但对于竞技元素如何执行此操作并不清楚,例如在我的情况下,内嵌在HorizontalStackLayout中。
我想要的是,在按下每个项目时打开详细视图。
附注:我还在使用CommunityToolkit(MVVM和MAUI版本)。
有什么想法吗?
英文:
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!
答案1
得分: 0
以下是您提供的代码的翻译部分:
在CollectionView
的DataTemplate
上有一个按钮,如果点击该按钮,当前项目将从列表中删除。
您可以参考以下代码:
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; }
}
更新
如果您想在CollectionView的项目上添加一个触摸手势,您可以参考以下代码:
<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>
</HorizontalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
请注意,您的原始代码中还包含了一些注释,这些注释未被翻译。如果您需要对这些注释进行翻译,请提供额外的信息。
英文:
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>
答案2
得分: 0
感谢@Jason在开头提供的评论,最终我选择了一个简单的方法来处理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)
{
//处理逻辑
}
感谢大家的评论和建议。
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论