question

MrZabbah-1468 avatar image
0 Votes"
MrZabbah-1468 asked RobCaplan edited

Endless loop trying to navigate through the app with Routing.RegisterRoute and await Shell.Current.GoToAsync

Hi everyone I have a big problem
I'm new using Xamarin and I'm learning while developing my first app. Now, I'm trying to achieve Shell Navegation with pages that are not in the Shell Content (for example, a detail page of an object).
In many tutorials they used the following code:

On the AppShell constructor we define the Routing:
-Routing.RegisterRoute(nameof(MyCoffeeDetailsPage), typeof(MyCoffeeDetailsPage));

MyCoffeeDetailsPage is the Page I want to move on. It's empty, just default settings

Next, on the modelview we create an AsyncCommand to control the navegation:
- public AsyncCommand TravelCommand { get; }
- public CoffeeEquipmentViewModel()
{
TravelCommand = new AsyncCommand(Travel);
}
- async Task Travel ()
{
var route = $"{nameof(MyCoffeeDetailsPage)}";
await Shell.Current.GoToAsync(nameof(MyCoffeeDetailsPage));
}

Now, everything is created, the next step is on the AXML binding this command to the proper button
- <Button Text="Travel" Command="{Binding TravelCommand}"/>

It seems that this should works, but when I press the button the app crashes. Besides, I debug what is going on and the problem is the next one:
- The await sentences on Travel calls the constructor of MyCoffeeDetailsPage. Inside this constructor, it executes the InitializeComponent and when it finish... it comes again to the constructor and the InitializeComponent in an endless loop.

Someone knows what is going on??



dotnet-xamarin
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

WenyanZhang-MSFT avatar image
0 Votes"
WenyanZhang-MSFT answered

Hello,
Welcome to our Microsoft Q&A platform!

I tried your code, the issue is about MyCoffeeDetailsPage.xml, you can bind a ViewModel.

 <ContentPage.BindingContext>
 <!--you can bind a ViewModel instead of view -->
 <views:MyCoffeeDetailsPage/>
 </ContentPage.BindingContext>

I create a new page and find the route you used is right.

 public AppShell()
 {
 InitializeComponent();
 Routing.RegisterRoute(nameof(MyCoffeeDetailsPage), typeof(MyCoffeeDetailsPage));
 Routing.RegisterRoute(nameof(CoffeeEquipmentPage), typeof(CoffeeEquipmentPage));
 Routing.RegisterRoute(nameof(MyNewPage1), typeof(MyNewPage1));
 }

 async Task Travel ()
 {
 var route = $"{nameof(MyNewPage1)}";
 await Shell.Current.GoToAsync(route);
 }

Best Regards,
Wenyan Zhang


If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our [documentation][1] to enable e-mail notifications if you want to receive the related email notification for this thread.
[1]: https://docs.microsoft.com/en-us/answers/articles/67444/email-notifications.html

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

WenyanZhang-MSFT avatar image
0 Votes"
WenyanZhang-MSFT answered WenyanZhang-MSFT edited

Hello,
Welcome to our Microsoft Q&A platform!
I am not sure where you added this button. It seams like the GoToAsync method has some issues. If you want to click the button on the first page(MyCoffeePage) to go to the next page(MyCoffeeDetailsPage), the following code shows a sample:

shell page

 <TabBar>
 <ShellContent Title="About" Icon="icon_about.png" Route="AboutPage" ContentTemplate="{DataTemplate local:AboutPage}" />
 <ShellContent Title="Browse" Icon="icon_feed.png" ContentTemplate="{DataTemplate local:ItemsPage}" />
 <ShellContent Title="CoffeeDetails" Icon="icon_about.png" Route="MyCoffeePage" ContentTemplate="{DataTemplate local:MyCoffeePage}" />
 </TabBar>

 public AppShell()
 {
 InitializeComponent();
 Routing.RegisterRoute(nameof(ItemDetailPage), typeof(ItemDetailPage));
 Routing.RegisterRoute(nameof(NewItemPage), typeof(NewItemPage));
 Routing.RegisterRoute(nameof(MyCoffeePage), typeof(MyCoffeePage));
 Routing.RegisterRoute(nameof(MyCoffeeDetailsPage), typeof(MyCoffeeDetailsPage));
 }

MyCoffeePage

 <Button Text="Travel" Command="{Binding TravelCommand}"/>

CoffeeEquipmentViewModel

 public class CoffeeEquipmentViewModel : BaseViewModel
 {
 public CoffeeEquipmentViewModel()
 {
 TravelCommand = new AsyncCommand(Travel);
 }
 public AsyncCommand TravelCommand { get; }
 async Task Travel()
 {
 await Shell.Current.GoToAsync("/MyCoffeeDetailsPage");
 }
 }


For more information, you can refer:
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/navigation

Best Regards,
Wenyan Zhang


If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our [documentation][1] to enable e-mail notifications if you want to receive the related email notification for this thread.
[1]: https://docs.microsoft.com/en-us/answers/articles/67444/email-notifications.html

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

MrZabbah-1468 avatar image
0 Votes"
MrZabbah-1468 answered MrZabbah-1468 commented

Hi! Thanks for your answer. I use the code above and it continues doing the same thing. I've created the button on the MyCoffeePage XAML in the ListView.Footer tab

     <ListView.Footer>
         <Button Text="Travel" Command="{Binding TravelCommand}"/>
     </ListView.Footer>

I think the problem is here for some reason. Do I have to add MyCoffeeDetailsPage to the shell content?

Here is the whole code of the xaml in MyCoffeePage
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:MyCoffeeApp.ViewModels"
xmlns:model="clr-namespace:MyCoffeeApp.Models"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
x:Class="MyCoffeeApp.Views.CoffeeEquipmentPage"
BackgroundColor="White"
x:DataType="viewmodels:CoffeeEquipmentViewModel"
x:Name="CoffeePage">
<!--This is called compiled bindings and increase performance of data binding and give me compile time checks -->

 <ContentPage.BindingContext>
     <!--Give intellisense -->
     <viewmodels:CoffeeEquipmentViewModel/>
 </ContentPage.BindingContext>

 <ContentPage.Resources>
     <ResourceDictionary>
         <xct:ItemSelectedEventArgsConverter x:Key="ItemSelectedEventArgsConverter"/>
     </ResourceDictionary>
 </ContentPage.Resources>
    
 <ListView
     SelectedItem="{Binding SelectedCoffee, Mode=TwoWay}"
     CachingStrategy="RecycleElement"
     BackgroundColor="Transparent"           
     ItemsSource="{Binding Coffee}"      
     HasUnevenRows="True"
     SeparatorVisibility="None"
     IsPullToRefreshEnabled="True"
     IsRefreshing="{Binding IsBusy, Mode=OneWay}" 
     RefreshCommand="{Binding RefreshCommand}"
     RefreshControlColor="OrangeRed"
     SeparatorColor="Red">
     <!--Only view model update the ui, not reverse-->
     <!--It has scrolling capability, HasUnevenRows adjust height automatically RowHeight="100"
         RecicleElement is super important and gives performance
      GroupDisplayBinding="{Binding Key}" 
     IsGroupingEnabled="True"
             IsGroupingEnabled="True"
     GroupDisplayBinding="{Binding Key}"-->

     <ListView.Behaviors>
         <xct:EventToCommandBehavior
             EventName="ItemSelected"
             Command="{Binding SelectedCommand}"
             EventArgsConverter="{StaticResource ItemSelectedEventArgsConverter}"/>
     </ListView.Behaviors>
        
     <ListView.ItemTemplate>
         <!--Allows modify the template of the cell of an item-->
         <DataTemplate x:DataType="model:Coffee">
             <!--Every item template is a data template, there are text cells, switch cells, image cells, but we are goint to create custom viewCells-->
             <ViewCell>
                 <ViewCell.ContextActions>
                     <!--When pressing shows a menu-->
                     <MenuItem Text="Favourite" 
                               Command="{Binding 
                         Source={x:Reference CoffeePage},
                         Path= BindingContext.FavouriteCommand}"
                               CommandParameter="{Binding .}"/>
                     <MenuItem Text="Delete" IsDestructive="True"/>
                 </ViewCell.ContextActions>
                 <Grid Padding="10" RowDefinitions="Auto, Auto" ColumnDefinitions="Auto, Auto">
                     <Frame BackgroundColor="AliceBlue"
                            CornerRadius="20"
                            HasShadow="True">
                         <StackLayout Orientation="Horizontal">
                             <Image Source="{Binding Image}"
                                    WidthRequest="66"/>
                             <StackLayout VerticalOptions="Center">
                                 <Label
                                     VerticalOptions="Center"
                                     Text="{Binding Name}"
                                     FontSize="Large"
                                     TextColor="{StaticResource TextColor}"/>
                                 <Label
                                     VerticalOptions="Center"
                                     Text="{Binding Roaster}"
                                     FontSize="Large"
                                     TextColor="{StaticResource TextColor}"/>
                             </StackLayout>
                         </StackLayout>
                     </Frame>
                 </Grid>
             </ViewCell>
         </DataTemplate>
     </ListView.ItemTemplate>

     <ListView.Header>
         <StackLayout>
             <StackLayout Orientation="Horizontal" BackgroundColor="{StaticResource Primary}">
                 <Image Source="https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/495f34ea-e9dc-412f-a873-6c31cde052c6/dc06j59-0aaeea8c-aafc-4a25-9a2a-30c25bf712f5.png?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7InBhdGgiOiJcL2ZcLzQ5NWYzNGVhLWU5ZGMtNDEyZi1hODczLTZjMzFjZGUwNTJjNlwvZGMwNmo1OS0wYWFlZWE4Yy1hYWZjLTRhMjUtOWEyYS0zMGMyNWJmNzEyZjUucG5nIn1dXSwiYXVkIjpbInVybjpzZXJ2aWNlOmZpbGUuZG93bmxvYWQiXX0.e3QLhHCvfol1wVSLVR1fzKFfd1UOIBCfMWc1zxh_UNA"
                                    WidthRequest="66"/>
                 <Label HorizontalOptions="Center" VerticalOptions="Center" Text="MOJACAR 2021" FontSize="48" TextColor="White"/>
             </StackLayout>
             <StackLayout Padding="5">
                 <Frame BackgroundColor="CadetBlue" CornerRadius="20" HasShadow="True" BorderColor="Black" Padding="15">
                     <Label Text="WIDGET DEL TIEMPO SEMANAL" FontSize="36" />
                 </Frame>
             </StackLayout>
         </StackLayout>
     </ListView.Header>

     <ListView.Footer>
         <Button Text="Travel" Command="{Binding TravelCommand}"/>
     </ListView.Footer>

 </ListView>

</ContentPage>

· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Would you mind sharing a basic, minimal project to test ? You can upload it to github and attach the link here .

0 Votes 0 ·