GestureRecognizer 无法在带有 DataTemplate 的 CollectionView 上工作

GestureRecognizer not working on CollectionView with DataTemplate

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

<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>

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

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

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

CollectionView 有一个 属性 用于 SelectedItem

SelectionMode="Single"
SelectedItem="{Binding SelectedVoice}"

然后在您的 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
}

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

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

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

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

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

然后像这样引用 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>