TapGestureRecognitor在ListView中不工作

TapGestureRecognitor在ListView中不工作,listview,xamarin.forms,Listview,Xamarin.forms,我正在处理一个Xamarin.Forms页面,该页面使用MVVM模式显示项目列表 我无法获取列表项的TapGestureRecognizer对象的Command属性。不管我怎么试,它都不会开火。 对于所有listview元素,此命令属性应在VM上引用单个ICommand属性。CommandParameter属性应根据元素的Id在元素之间进行选择 该事件似乎正在运行。我不确定将Command属性数据绑定到VM是错误的还是Xamarin.Forms在这里有错误 我尝试了将TapGestureReco

我正在处理一个Xamarin.Forms页面,该页面使用MVVM模式显示项目列表

我无法获取列表项的TapGestureRecognizer对象的Command属性。不管我怎么试,它都不会开火。 对于所有listview元素,此命令属性应在VM上引用单个ICommand属性。CommandParameter属性应根据元素的Id在元素之间进行选择

该事件似乎正在运行。我不确定将Command属性数据绑定到VM是错误的还是Xamarin.Forms在这里有错误

我尝试了将TapGestureRecognizer的Command属性的数据绑定到我的ViewModel的不同设置,并且在嵌套视图元素上使用了InputTransparent属性。此处无更改:命令不触发

查看XAML标题:

<ContentPage ...
             x:Class="Ch9.MainPage2"
             x:Name="page"
             >
viewmodel具有ItemTappedCommand属性:

public ICommand ItemTappedCommand { get; private set; }
...
ItemTappedCommand = new Command<int>(async id => await OnItemTappedCommand(id));
public ICommand ItemTappedCommand{get;private set;}
...
ItemTappedCommand=new命令(async id=>wait-OnItemTappedCommand(id));
在页面内部,我有一个stacklayout作为内容根,在stacklayout内部有一个listview。为了保持代码的小型化,我省略了我可以省略的,我认为不相关的内容

<ListView
    ItemsSource="{Binding SearchResults}">
    <ListView.ItemTemplate>
    <DataTemplate>                        
        <ViewCell>
            <StackLayout>
                <StackLayout.GestureRecognizers>
                      <TapGestureRecognizer 
                            BindingContext="{x:Reference page}"                                        
                            Command="{Binding Path=ViewModel.ItemTappedCommand}" CommandParameter="{Binding Id}"  NumberOfTapsRequired="1"/>
                </StackLayout.GestureRecognizers>

                                <Image InputTransparent="True">
                                    <Image.Source>
                                        <UriImageSource Uri="{Binding ImgSmSrc}"
                                                    CacheValidity="0"
                                                    CachingEnabled="False"                                                    
                                                    />
                                    </Image.Source>
                                </Image>
                               <StackLayout InputTransparent="True">
                              some content...
                              </StackLayout>

                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>

一些内容。。。

您已将
TapGestureRecognitor
BindingContext
更改为当前内容页,但它无法注意到自定义定义的属性
ViewModel
,您只能使用
ContentPage
的属性

因此,
{Binding Path=ViewModel.ItemTappedCommand}
此绑定将失败

我建议您调整装订方式,如:

<ListView x:Name="listView" ItemsSource="{Binding SearchResults}" HasUnevenRows="True">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout>
                    <StackLayout.GestureRecognizers>
                        <TapGestureRecognizer Command="{Binding Path= BindingContext.ItemTappedCommand, Source={x:Reference listView}}" 
                                            CommandParameter="{Binding Id}"  
                                            NumberOfTapsRequired="1"/>
                    </StackLayout.GestureRecognizers>
                    <!--onther stuff-->
                    <!--...-->

                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

列表视图的绑定上下文是使用代码隐藏设置的视图模型。最后,您可以在那里使用
ItemTappedCommand


此外,由于您想要访问Id,我只更改了
命令的
源代码,而不是整个手势的绑定上下文。或者您不会检索到它,因为它属于
SearchResults
的元素,而不是视图模型本身。

您已将
TapGestureRecognitor
BindingContext
更改为当前内容页,但它没有注意到自定义的属性
ViewModel
,您只能使用
ContentPage
的属性

因此,
{Binding Path=ViewModel.ItemTappedCommand}
此绑定将失败

我建议您调整装订方式,如:

<ListView x:Name="listView" ItemsSource="{Binding SearchResults}" HasUnevenRows="True">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout>
                    <StackLayout.GestureRecognizers>
                        <TapGestureRecognizer Command="{Binding Path= BindingContext.ItemTappedCommand, Source={x:Reference listView}}" 
                                            CommandParameter="{Binding Id}"  
                                            NumberOfTapsRequired="1"/>
                    </StackLayout.GestureRecognizers>
                    <!--onther stuff-->
                    <!--...-->

                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

列表视图的绑定上下文是使用代码隐藏设置的视图模型。最后,您可以在那里使用
ItemTappedCommand


此外,由于您想要访问Id,我只更改了
命令的
源代码,而不是整个手势的绑定上下文。或者您将无法检索它,因为它属于
SearchResults
的元素,而不是查看模型本身。

使用ItemSelected或ItemTapped事件,而不是GestureRecognitor。如果可能,我希望使用无代码隐藏的MVVM模式。目前,我正在从代码隐藏(我使用ItemTapped event)重构到MVVM,我想在MVVM中使用commands。您实际将ViewModel设置为视图的BindingContext吗?您的代码中有一个getter setter,但我没有看到ViewModelHi鼠标的分配!我在页面的构造函数中设置了它。我已经相应地更新了代码清单。我之前省略了,因为我不想用噪声污染代码。此页面上是否有其他绑定工作?使用ItemSelected或ItemTapped事件而不是GestureRecognitor。如果可能,我希望使用无代码隐藏的MVVM模式。目前,我正在从代码隐藏(我使用ItemTapped event)重构到MVVM,我想在MVVM中使用commands。您实际将ViewModel设置为视图的BindingContext吗?您的代码中有一个getter setter,但我没有看到ViewModelHi鼠标的分配!我在页面的构造函数中设置了它。我已经相应地更新了代码清单。我之前省略了,因为我不想用噪音污染代码。这个页面上还有其他绑定工作吗?感谢响应Lu,我已经着手解决问题(使用事件并从代码隐藏事件处理程序调用VM命令object-s Execute方法),过几天我将尝试您的解决方案并报告@你可以试试这个。我认为MVVM不应该与事件通信。感谢响应Lu,我已经着手解决问题(使用事件并从代码隐藏事件处理程序调用VM命令object-s Execute方法),几天后我将尝试您的解决方案并报告@你可以试试这个。我认为MVVM不应该与事件进行通信。