I have followed James Montemagno's excellent .Net MAUI for Beginners series. In it, he uses a TapGestureRecognizer Command to go to a detail page for the item tapped. I downloaded his repo and tested and it works fine in VS 2022 v17.4.0 Preview 1.0.
I pretty much copied his code directly into mine and it doesn't work in my project for some reason. Now Tapped does work fine and goes to a new page, but when I use that method it wants me to pass in the view model, which I can't figure out. So I thought James' Command method might work better, but can't get it to even call the TapCommand code - nothing happens when clicking/tapping on the label.
So Edit Profile works. Edit Account does not. Here's the code:
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CRUMSMobile.Views.Settings.UserSettings"
xmlns:viewmodel="clr-namespace:CRUMSMobile.ViewModels.Settings"
x:DataType="viewmodel:UserSettingsViewModel"
Title="Settings">
<VerticalStackLayout>
<Label Text="Account Settings"
FontSize="16"
FontAttributes="Bold"
TextColor="DarkGray"
TextTransform="Uppercase"
VerticalOptions="Start"
HorizontalOptions="Start"
Margin="20,20,0,30"/>
<Label Text="Edit Account"
HorizontalOptions="Start"
FontSize="14"
Margin="20,0,0,30">
<Label.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:UserSettingsViewModel}}, Path=TapCommand}"
CommandParameter="EditAccount"/>
</Label.GestureRecognizers>
</Label>
<Label Text="Edit profile"
HorizontalOptions="Start"
FontSize="14"
Margin="20,0,0,30">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="Edit_Profile_Tapped" />
</Label.GestureRecognizers>
</Label>
</VerticalStackLayout>
</ContentPage>
Code behind:
public partial class UserSettings : ContentPage
{
public UserSettings()
{
InitializeComponent();
}
private void Edit_Profile_Tapped(object sender, EventArgs e)
{
Navigation.PushAsync(new EditProfile());
}
}
View Model:
public partial class UserSettingsViewModel : BaseViewModel
{
public UserSettingsViewModel()
{
}
[RelayCommand]
async Task Tap(string s)
{
if (s == "EditAccount")
{
await Shell.Current.GoToAsync(nameof(EditAccount));
}
}
}
And here's the constructor for the EditAccount page:
public partial class EditAccount : ContentPage
{
public EditAccount(EditAccountViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
_ = GetUserAccount();
}
[...]
As @GeraldVersluis suggested, you should use TapCommand
firstly. Also, if you're using Shell
to navigate through pages, don't forget to Register the routing for EditAccount page
in AppShell.xaml.cs
. Here's the detailed steps below for your reference:
1. Install the CommunityToolkit.Mvvm
package in your project.
2. UserSettings.xaml:
<VerticalStackLayout>
<Label Text="Account Settings"
FontSize="16"
FontAttributes="Bold"
TextColor="DarkGray"
TextTransform="Uppercase"
VerticalOptions="Start"
HorizontalOptions="Start"
Margin="20,20,0,30"/>
<Label Text="Edit Account"
HorizontalOptions="Start"
FontSize="14"
BackgroundColor="Red"
Margin="20,0,0,30">
<Label.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding TapCommand}"/>
</Label.GestureRecognizers>
</Label>
</VerticalStackLayout>
UserSettings.cs:
public partial class UserSettings : ContentPage
{
public UserSettings()
{
InitializeComponent();
BindingContext = new UserSettingsViewModel();
}
}
3. ViewModel for the UserSetting Page:
public partial class UserSettingsViewModel : ObservableObject
{
[RelayCommand]
async Task Tap()
{
await Shell.Current.GoToAsync(nameof(EditAccount));
}
}
4. Register the routing:
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute(nameof(EditAccount), typeof(EditAccount));
}