使用MVVM在.NET MAUI/XAMARIN.FORMS中使用MVVM的手势识别者

发布于 2025-01-31 16:06:24 字数 2610 浏览 0 评论 0原文

我想将带有iCommand的Tap手势识别器使用,含义使用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在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;
    }

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

  1. 我应该使用命令,而不是在Tapgesturerecognizer下进行敲击。每当我将命令字段绑定到后面的代码中的命令时, x:datatype =“ model:questionpack” 提出问题,因为数据模板的模型中未定义命令。

  2. 即使将命令应用于Tap手势识别器并不会导致构建应用程序失败,我该如何传递被挖掘到后面代码的对象?在后面的代码中,我使用对象发件人将其检索,但是在ViewModel中,我不知道。我猜那是我不知道的命令参与者开始发挥作用的地方。

而且不要打扰,如果可以解释commandParameter =“ {binding。}”也意味着什么。

任何帮助将不胜感激。

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(
quot;{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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小梨窩很甜 2025-02-07 16:06:24

创建您的ViewModel文件并将其定义为BindingContext
示例

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

然后在您的ViewModel中定义您的命令和ICommand(您知道如何做)

和XAML文件中,您可以做类似的事情

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

告诉我以获取更多详细信息

Create you ViewModel file and define as BindingContext
Example

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

Then define your Command and ICommand in your ViewModel( suposing that you know how to do )

And in your xaml file, you can do something like this

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

Tell me for more details

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文