GestureRecognizer 不适用于带有 DataTemplate 的 CollectionView

Tim*_*uin 0 c# xaml gesture xamarin xamarin.forms

我正在使用 GestureRecognizers 在 Xamarin 中玩耍,我有以下代码:

<CollectionView
  Grid.Row="0"
  EmptyView="No player information"
  ItemsSource="{Binding Voices, Mode=OneWay}">

  <CollectionView.GestureRecognizers>
    <TapGestureRecognizer
      Command="{Binding CommandPlayerTapped}"
      CommandParameter="hi"
      NumberOfTapsRequired="1" />
  </CollectionView.GestureRecognizers>

  <CollectionView.ItemTemplate>
    <DataTemplate>

      <StackLayout>
        <views:PancakeItemView Margin="5" BorderColor="Black">
          <views:VoiceInfoContainerView Style="{StaticResource VoiceDisplayStyle}" />
        </views:PancakeItemView>
      </StackLayout>

    </DataTemplate>
  </CollectionView.ItemTemplate>
</CollectionView>
Run Code Online (Sandbox Code Playgroud)

MyTapGestureRecognizer绑定到一个简单的命令,它会弹出一个消息;没什么复杂的。DataTemplate 是一个 PancakeView 包装一个简单的视图来显示一些名称,如下所示:

显示视图的屏幕截图

同样,这并不复杂,但是,我觉得这可能是问题所在,因为我在网上找不到任何其他信息。

我尝试将手势代码放在其他元素中,但没有成功。关于为什么点击这些视图无法触发命令的任何想法?

Ric*_*ais 6

CollectionView 具有SelectedItem的属性

SelectionMode="Single"
SelectedItem="{Binding SelectedVoice}"
Run Code Online (Sandbox Code Playgroud)

然后在您的 ViewModel 上:

private Voice _selectedVoice; //I don't know what type of items is your Collection Voices, so i'm using Voice here
public Voice SelectedVoice
{
    get { return _selectedVoice; }
    set { 
          _selectedVoice = value; 
          CommandPlayerTapped.Execute();
        }
}


...

//On the function that CommandPlayerTapped called:

if(SelectedVoice != null)
{
    //Your code
}
else{
    //The Item was deselected
}
Run Code Online (Sandbox Code Playgroud)

这里有一些额外的关于您之前尝试的方式以及为什么它不起作用:

如果您尝试为 CollectionView 中的每个项目设置 GestureRecognizer,那么您在错误的地方使用它,您是在集合本身中设置 GR,而不是在每个项目中。

您需要传递正确的BindingContext,您的项目具有VoicesItemSource BindingContext,但您需要 ViewModel Context,您可以引用不同的 Context(例如:CollectionView 本身),

首先通过添加 x:Name="CollectionViewForBinding" 来创建 CollectionView 引用,例如:

<CollectionView
  x:Name="CollectionViewForBinding"
  Grid.Row="0"
  EmptyView="No player information"
  ItemsSource="{Binding Voices, Mode=OneWay}">
Run Code Online (Sandbox Code Playgroud)

然后你像这样引用 BindingContext:

<StackLayout>
    <StackLayout.GestureRecognizers>
          <TapGestureRecognizer
              Command="{Binding BindingContext.CommandPlayerTapped, Source={x:Reference Name=CollectionViewForBinding}}"
              CommandParameter="{Binding ThePropertyOfTheItemYouWantToPass}"
              NumberOfTapsRequired="1" />
    </StackLayout.GestureRecognizers>
    <views:PancakeItemView Margin="5" BorderColor="Black">
        <views:VoiceInfoContainerView Style="{StaticResource VoiceDisplayStyle}" />
    </views:PancakeItemView>
</StackLayout>
Run Code Online (Sandbox Code Playgroud)