И TouchBehavior.CommandParameter, и TouchBehavior.LongPressCommandParameter всегда передаются как null в Command и LongPressCommand.
В следующем примере при касании элемента в CollectionView результирующее предупреждение всегда будет отображаться Selected value:, поскольку CommandParameter всегда равен null. Например, когда пользователь нажимает Selected vale: Item 1, должно быть написано 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");
}
Вот ссылка на образец воспроизведения этой ошибки: https://github.com/hansmbakker/bugrepro-communitytoolkit-maui-touchbehavior-parameter





В .NET MAUI вам необходимо вручную установить BindingContext для каждого Behavior. Другими словами, поведения не наследуют BindingContext от VisualElement, к которому они привязаны.
Вот обновленный XAML, который поможет вашему коду работать. Он использует привязку «представление-представление» для привязки TouchBehavior.BindingContext к 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>
Немного не связанный с проблемой Behavior BindingContext, вот моя рекомендация по небольшому повышению производительности вашей ViewModel (оба Title и Items могут быть свойствами только для чтения):
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");
}
Вот снимок экрана вашего приложения, работающего должным образом после обновления кода:
Вот модульные тесты, которые я написал для TouchBehavior в CommunityToolkit.Maui, где мы проверяем, что LongPressCommand действительно проходит в LongPressCommandParameter;
А вот модульные тесты, которые я написал для TouchBehavior в CommunityToolkit.Maui, где мы проверяем, что Command действительно проходит в CommandParameter;