【问题标题】:Gesture Recognisers using MVVM in .NET MAUI/Xamarin.Forms在 .NET MAUI/Xamarin.Forms 中使用 MVVM 的手势识别器
【发布时间】:2022-11-11 09:59:47
【问题描述】:

我想使用带有 ICommand 的 Tap Gesture Recogniser,意思是使用 ViewModel 而不是背后的代码。

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

主页.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

主页.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="模型:QuestionPack"引发问题,因为该命令未在数据模板的模型中定义。

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

    如果有人能解释CommandParameter="{Binding .}" 的含义,请不要打扰。

    非常感谢任何帮助。

【问题讨论】:

  • 下面已经有关于如何设置路径绑定的答案,但是要回答您的其他问题{Binding .} 意味着您要绑定到整个对象,而不是特定属性。 stackoverflow.com/a/62816690/8395242

标签: c# xamarin xamarin.forms maui .net-maui


【解决方案1】:

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

告诉我更多细节

【讨论】:

    【解决方案2】:

    你可以这样做

    <Frame.GestureRecognizers>
            <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"
                                  CommandParameter="{Binding .}"/>                                 
    </Frame.GestureRecognizers>
    

    并在您的 xaml.cs 文件中

    async void TapGestureRecognizer_Tapped(System.Object sender, Microsoft.Maui.Controls.TappedEventArgs e)
    {
        var goTo = (string)e.Parameter;
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2014-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多