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
;