在 .NET MAUI/Xamarin.Forms 中使用 MVVM 的手势识别器

Gesture Recognisers using MVVM in .NET MAUI/Xamarin.Forms

我想使用带有 ICommand 的点击手势识别器,这意味着使用 ViewModel 而不是背后的代码。

我正在通过后面的代码让手势识别器工作,如下所示

HomePage.xaml

<CollectionView Margin="10,0,10,0"
                            ItemSizingStrategy="MeasureAllItems"
                            ItemsLayout="VerticalList"
                            VerticalScrollBarVisibility="Always"
                            ItemsSource="{Binding QuestionPacks}">
            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="model:QuestionPack">
                    <Frame Margin="5"
                           CornerRadius="10">
                        <Frame.GestureRecognizers>
                            <TapGestureRecognizer 
                                Tapped="TapGestureRecognizer_Tapped"/>
                            <TapGestureRecognizer 
                                NumberOfTapsRequired="2"
                                Tapped="TapGestureRecognizer_Tapped_1"/>
                        </Frame.GestureRecognizers>
                        <VerticalStackLayout Margin="5">
                        
                            <Label Text="{Binding Topic}" />
                            <Label Text="{Binding TopicId}" />
                        </VerticalStackLayout>
                    </Frame>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

请注意数据模板中的 x:DataType=model:QuestionPack

HomePage.xaml.cs

private async void TapGestureRecognizer_Tapped(object sender, EventArgs e)
    {

        var selectedItem = ((VisualElement)sender).BindingContext as QuestionPack;

        if (selectedItem == null)
            return;


        LoadingQuestions.IsRunning = true;
        LoadingQuestions.IsEnabled = true;

        await Shell.Current.GoToAsync($"{nameof(QuestionsPage)}?topicSelected={selectedItem.TopicId}");

        LoadingQuestions.IsRunning = false;
        LoadingQuestions.IsEnabled = false;
    }

这工作正常,但我想知道如何在我的 ViewModel 中实现它。我在尝试这样做时遇到了 2 个挑战。

  1. 我应该在 TapGestureRecognizer 下使用 Command 而不是 Tapped。每当我将命令字段绑定到代码后面的命令时,x:DataType="model:QuestionPack" 都会引发问题,因为该命令未在数据模板的模型中定义.

  2. 即使将命令应用于点击手势识别器不会导致构建应用程序失败,我如何将点击的对象传递到后面的代码中?在后面的代码中,我使用 object sender 检索它,但在 ViewModel 中,我不知道。我猜这就是 CommandParameters 发挥作用的地方,但我不知道如何实现它们。

不要打扰,如果有人能解释一下 CommandParameter="{Binding .}" 的意思。

非常感谢任何帮助。

创建您的 ViewModel 文件并定义为 BindingContext 例子

<ContentPage.BindingContext>
      <vm:MyViewModel />
</ContentPage.BindingContext>

然后在您的 ViewModel 中定义您的 Command 和 ICommand(假设您知道该怎么做)

在你的 xaml 文件中,你可以做这样的事情

 <Frame.GestureRecognizers>
     <TapGestureRecognizer NumberOfTapsRequired="1" 
                           CommandParameter="{Binding .}"
                           Command="{Binding 
                           Source={RelativeSource AncestorType={x:Type vm:MyViewModel}}, Path=TapGestureRecognizer_Tapped}"/>                  
 </Frame.GestureRecognizers>

告诉我更多详情