Both TouchBehavior.CommandParameter and TouchBehavior.LongPressCommandParameter are always passed as null to Command and LongPressCommand.
In the following example, when an item in the CollectionView is tapped, the resulting alert will always display Selected value: because the CommandParameter is always null. It should say Selected vale: Item 1, for example, when the user taps Item 1.

<VerticalStackLayout Padding="30,0"
Spacing="25">
<Label Text="{Binding Title}"
Style="{StaticResource Headline}"
SemanticProperties.HeadingLevel="Level1" />
<Label Text="Tapping or long pressing an item does not correctly pass that item as CommandParameter or LongTouchCommandParameter."
Style="{StaticResource SubHeadline}"
SemanticProperties.HeadingLevel="Level1" />
<CollectionView x:Name="collectionView"
ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{x:Type x:String}">
<Label Padding="10"
Text="{Binding .}"
x:Name="Label">
<Label.Behaviors>
<toolkit:TouchBehavior Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.ShowItemCommand}"
CommandParameter="{Binding .}"
LongPressCommand="{Binding Source={x:Reference collectionView}, Path=BindingContext.ShowItemCommand}"
LongPressCommandParameter="{Binding .}"
<!--
CommandParameter and LongPressCommandParameter are always passed as null in the CommunityToolkit.Maui TouchBehavior.
this was not the case with https://github.com/Axemasta/Maui.TouchEffect -->
</Label.Behaviors>
</Label>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
public partial class MainViewModel : ObservableObject
{
public string Title => "Hello, Maui!";
public ObservableCollection<string> Items { get; set; } = ["Item 1", "Item 2", "Item 3"];
/// <summary>
/// item is always null. This was not the case in https://github.com/Axemasta/Maui.TouchEffect
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
[RelayCommand]
private Task ShowItem(string item) => Application.Current.MainPage.DisplayAlert($"Selected value:", item, "OK");
}
Here is a link to a reproduction sample for this bug: https://github.com/hansmbakker/bugrepro-communitytoolkit-maui-touchbehavior-parameter
In .NET MAUI, you are required to manually set the BindingContext for every Behavior. In other words, Behaviors do not inherit the BindingContext of the VisualElement to which they are attached.
Source: https://learn.microsoft.com/dotnet/maui/fundamentals/behaviors?view=net-maui-8.0#create-a-net-maui-behavior
Here is the updated XAML to get your code working. It uses a view-to-view binding to bind TouchBehavior.BindingContext to Label.BindingContext:
<VerticalStackLayout Padding="30,0"
Spacing="25">
<Label Text="{Binding Title}"
Style="{StaticResource Headline}"
SemanticProperties.HeadingLevel="Level1" />
<Label Text="Tapping or long pressing an item does not correctly pass that item as CommandParameter or LongTouchCommandParameter."
Style="{StaticResource SubHeadline}"
SemanticProperties.HeadingLevel="Level1" />
<CollectionView x:Name="collectionView"
ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="{x:Type x:String}">
<Label Padding="10"
Text="{Binding .}"
x:Name="label">
<Label.Behaviors>
<toolkit:TouchBehavior Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.ShowItemCommand}"
CommandParameter="{Binding .}"
LongPressCommand="{Binding Source={x:Reference collectionView}, Path=BindingContext.ShowItemCommand}"
LongPressCommandParameter="{Binding .}"
BindingContext="{Binding Source={x:Reference label}, Path=BindingContext}"/>
</Label.Behaviors>
</Label>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</VerticalStackLayout>
A bit unrelated to the Behavior BindingContext problem, here is my recommendation for small performance improvement to your ViewModel (both Title and Items can be read-only properties):
public partial class MainViewModel : ObservableObject
{
public string Title { get; } = "Hello, Maui!";
public ObservableCollection<string> Items { get; } = ["Item 1", "Item 2", "Item 3"];
[RelayCommand]
private Task ShowItem(string item) => Application.Current.MainPage.DisplayAlert($"Selected value:", item, "OK");
}
Here is a screen shot of your app working as expected after updating the code:
Here are the Unit Tests I wrote for the TouchBehavior in CommunityToolkit.Maui where we verify the LongPressCommand does indeed pass in LongPressCommandParameter;
https://github.com/CommunityToolkit/Maui/blob/51dc63a7642370849e413d87072b668fa022e303/src/CommunityToolkit.Maui.UnitTests/Behaviors/TouchBehaviorTests.cs#L612-L674
And here are the Unit Tests I wrote for the TouchBehavior in CommunityToolkit.Maui where we verify the Command does indeed pass in CommandParameter;
https://github.com/CommunityToolkit/Maui/blob/51dc63a7642370849e413d87072b668fa022e303/src/CommunityToolkit.Maui.UnitTests/Behaviors/TouchBehaviorTests.cs#L550-L610
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With