在 .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 个挑战。
我应该在 TapGestureRecognizer 下使用 Command 而不是 Tapped。每当我将命令字段绑定到代码后面的命令时,x:DataType="model:QuestionPack" 都会引发问题,因为该命令未在数据模板的模型中定义.
即使将命令应用于点击手势识别器不会导致构建应用程序失败,我如何将点击的对象传递到后面的代码中?在后面的代码中,我使用 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>
告诉我更多详情
我想使用带有 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 个挑战。
我应该在 TapGestureRecognizer 下使用 Command 而不是 Tapped。每当我将命令字段绑定到代码后面的命令时,x:DataType="model:QuestionPack" 都会引发问题,因为该命令未在数据模板的模型中定义.
即使将命令应用于点击手势识别器不会导致构建应用程序失败,我如何将点击的对象传递到后面的代码中?在后面的代码中,我使用 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>
告诉我更多详情