wojtek
wojtek

Reputation: 99

Navigation in .Net maui doesn't work - TapgestureRecognizer

I am new to .net maui. I want to make navigation between my Main page and other pages. I used this tutorial on yt: https://www.youtube.com/watch?v=ddmZ6k1GIkM but it doesn't work. I don't know what should i do. Maybe TapGestureRecognizer is used bad or a frame should be in other place. (I use CommunityToolkit.Mvvm.)

Should I use something diffrent than TapGestureRecognizer? And if yes how? Can you also suggest any tutorials that could help me?

I think that problem may be also related to my method where i try to navigate - MenuListViewSelectedItem in ViewModel.

Link to git: https://github.com/wojblaz/Clicer-Game---final

This is my code:

Main Page xaml:

            <CollectionView ItemsSource="{Binding GameDescription}"
                        Grid.Row="2"
                        Margin="9,40"
                        SelectionMode="None">

            <CollectionView.ItemsLayout>
                <LinearItemsLayout Orientation="Vertical"
                                   ItemSpacing="15"/>
            </CollectionView.ItemsLayout>

            <CollectionView.ItemTemplate>
                <DataTemplate x:DataType="models:MainMenuModel">

                    <Frame BackgroundColor="#87c5ff">
                        
                        <Frame.GestureRecognizers>
                            <TapGestureRecognizer 
                                 Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodels:MainMenuViewModel}}, Path=MenuListViewSelectedItem}"
                                 CommandParameter="{Binding .}"/>
                        </Frame.GestureRecognizers>

                        <Grid MaximumHeightRequest="165" >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>

                            <Grid.RowDefinitions>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>

                            <!-- Name -->
                            <Label Text="{Binding Name}"
                                   FontSize="30"
                                   Grid.Row="1"
                                   VerticalOptions="End"
                                   FontFamily="Anton"
                                   TextColor="White"
                                   Grid.Column="0"/>


                            <!-- Description -->
                            <Label Text="{Binding Description}"
                                   FontSize="Default"
                                   FontFamily="FAS"
                                   Grid.Row="2"
                                   Grid.Column="0"
                                   TextColor="#555"
                                   Margin="0,10,10,25"/>

                            <!-- Nice image -->
                            <Image Source="{Binding Image}"
                                   Grid.RowSpan="3"
                                   MaximumHeightRequest="100"
                                   MaximumWidthRequest="125"
                                   Grid.Column="1"/>
                            
                        </Grid>
                    </Frame>                        
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>

MainMenuViewModel:

    public MainMenuViewModel()
    {
     LoadGameDescription();
    }

    [RelayCommand]
    public void LoadGameDescription()
    {
        GameDescription = new()
        {
            new MainMenuModel (
                Name : "Classic", 
                Description : "Click as fast as you can." , 
                Image :new Uri("https://cdn-icons-png.flaticon.com/512/2055/2055568.png")),


            new MainMenuModel (
                Name : "Race light", 
                Description : "Test your reaction time." , 
                Image : new Uri("https://cdn-icons-png.flaticon.com/512/2380/2380748.png")),
        };
    

   

    [RelayCommand] 
    async public void MenuListViewSelectedItem(TapGestureRecognizer e)
    {

        switch (((MainMenuModel)e.CommandParameter).Name)
        {
            case "Classic":
                await Shell.Current.GoToAsync(nameof(ClassicMode));
                break;
                /* 
            case "Race light":
                await Shell.Current.GoToAsync(nameof()); 
                break;
                */
        }
    }
}

AppShell.xaml.cs

    public AppShell()
    {
        InitializeComponent();

        Routing.RegisterRoute(nameof(ClassicMode), typeof(ClassicMode));
    }

ClassicMode.xaml.cs

    public ClassicMode()
    {
        InitializeComponent();
        BindingContext = new ClassicModelViewModel();

    }

MauiProgram.cs

    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");


                fonts.AddFont("OFree-Solid-900.otf", "FAS");
                fonts.AddFont("Anton-Regular.ttf", "Anton");
            });

        builder.Services.AddSingleton<MainPage>();
        builder.Services.AddSingleton<MainMenuViewModel>();

        builder.Services.AddTransient<ClassicMode>();
        builder.Services.AddTransient<ClassicModelViewModel>();

        return builder.Build();
    }

Upvotes: 3

Views: 2172

Answers (1)

Julian
Julian

Reputation: 8914

Your Command is taking the wrong type of parameter.

It should be:

[RelayCommand] 
async void MenuListViewSelectedItem(MainMenuModel e)
{
    switch (e.Name)
    {
        case "Classic":
            await Shell.Current.GoToAsync(nameof(ClassicMode));
            break;
        //...
    }
}

UPDATE

In your XAML you need to use MenuListViewSelectedItemCommand instead of MenuListViewSelectedItem:

<TapGestureRecognizer 
  Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodels:MainMenuViewModel}}, Path=MenuListViewSelectedItemCommand}"
  CommandParameter="{Binding .}"/>

That's because you need to bind to the Command that the MVVM source generator creates, not the method itself.

Upvotes: 3

Related Questions