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

5q4ezhmt  于 2022-12-07  发布在  .NET
关注(0)|答案(1)|浏览(154)

I want to use Tap Gesture Recogniser with ICommand meaning using the ViewModel instead of the code behind.
I am making the gesture recogniser work through the code behind as shown below

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>

Please note the x:DataType=model:QuestionPack in the DataTemplate.

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

This is working fine but I want to know how to implement this in my ViewModel. I came across 2 challenges while trying to do this.

  1. I am supposed to use Command instead of Tapped under the TapGestureRecognizer. Whenever I bind the Command field to a Command in my code behind, the x:DataType="model:QuestionPack" raises a problem because the command is not defined in the model for the data template.
  2. Even if applying the Command to the tap gesture recognizer wasn't causing building the app to fail, how am I to pass the object that is tapped into the code behind? In the code behind, I retrieve it using object sender but in the ViewModel, I don't know. I am guessing that that is where CommandParameters come into play but how to implement them is where I don't know.
    And not to be a bother, if one can explain what CommandParameter="{Binding .}" means too.
    Any assistance is greatly appreciated.
pgky5nke

pgky5nke1#

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

请告诉我详细信息

相关问题