Extremely frustrated with Shell Navigation, hope someone can help
Flow
- App loads and the Landing Page appears (this is the main page)
- The user taps the account icon and is routed to Login
- User enters their details and clicks the login button (i want to navigate back to Landing Page)
App Shell XAML
<ShellContent
Title="LandingPage"
ContentTemplate="{DataTemplate local:LandingPage}"
Route="LandingPage" />
</Shell>
AppShell.xaml.cs
public AppShell()
{
InitializeComponent();
We dont register this route because its already defined in xaml
// Routing.RegisterRoute(nameof(LandingPage), typeof(LandingPage));
Routing.RegisterRoute(nameof(StoreItems), typeof(StoreItems));
Routing.RegisterRoute(nameof(Register), typeof(Register));
Routing.RegisterRoute(nameof(PasswordRecovery), typeof(PasswordRecovery));
Routing.RegisterRoute(nameof(NewStoreRequest), typeof(NewStoreRequest));
Routing.RegisterRoute(nameof(AccountInfo), typeof(AccountInfo));
Routing.RegisterRoute(nameof(AllPromotions), typeof(AllPromotions));
Routing.RegisterRoute(nameof(AllStores), typeof(AllStores));
Routing.RegisterRoute(nameof(ChangePassword), typeof(ChangePassword));
Routing.RegisterRoute(nameof(Checkout), typeof(Checkout));
Routing.RegisterRoute(nameof(CreateAddress), typeof(CreateAddress));
Routing.RegisterRoute(nameof(TrackOrder), typeof(TrackOrder));
Routing.RegisterRoute(nameof(TrackOrderDetails), typeof(TrackOrderDetails));
Routing.RegisterRoute(nameof(StoreBasket), typeof(StoreBasket));
Routing.RegisterRoute(nameof(ProcessingPayment), typeof(ProcessingPayment));
Routing.RegisterRoute(nameof(PaymentConfirmed), typeof(PaymentConfirmed));
Routing.RegisterRoute(nameof(Login), typeof(Login));
}
MauiProgram.cs (UPDATED)
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureSyncfusionCore()
.UseMauiCommunityToolkit()
.ConfigureFonts(fonts =>
{
fonts.AddFont("FontAwesome6BrandsRegular400.otf", "BrandsRegular");
fonts.AddFont("FontAwesome6DuotoneSolid900.otf", "DuoToneSolid");
fonts.AddFont("FontAwesome6ProLight300.otf", "ProLight");
fonts.AddFont("FontAwesome6ProRegular.otf", "ProRegular");
fonts.AddFont("FontAwesome6ProSolid900.otf", "ProSolid");
fonts.AddFont("FontAwesome6ProThin100.otf", "ProThin");
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
// Services
builder.Services.AddSingleton<INippyDataService, NippyDataService>();
// Views
builder.Services.AddTransient<LandingPage>();
builder.Services.AddTransient<StoreItems>();
builder.Services.AddSingleton<Login>();
builder.Services.AddSingleton<Register>();
builder.Services.AddSingleton<PasswordRecovery>();
builder.Services.AddTransient<AccountInfo>();
builder.Services.AddTransient<AllPromotions>();
builder.Services.AddTransient<AllStores>();
builder.Services.AddSingleton<ChangePassword>();
builder.Services.AddTransient<Checkout>();
builder.Services.AddTransient<CreateAddress>();
builder.Services.AddSingleton<NewStoreRequest>();
builder.Services.AddTransient<TrackOrder>();
builder.Services.AddTransient<TrackOrderDetails>();
builder.Services.AddTransient<StoreBasket>();
builder.Services.AddTransient<ProcessingPayment>();
builder.Services.AddTransient<PaymentConfirmed>();
// View Models
builder.Services.AddTransient<LandingPageVM>();
builder.Services.AddTransient<StoreItemsVM>();
builder.Services.AddSingleton<LoginVM>();
builder.Services.AddSingleton<RegisterVM>();
builder.Services.AddSingleton<PasswordRecoveryVM>();
builder.Services.AddTransient<AccountInfoVM>();
builder.Services.AddTransient<AllPromotionsVM>();
builder.Services.AddTransient<AllStoresVM>();
builder.Services.AddSingleton<ChangePasswordVM>();
builder.Services.AddTransient<CheckoutVM>();
builder.Services.AddTransient<CreateAddressVM>();
builder.Services.AddSingleton<NewStoreRequestVM>();
builder.Services.AddTransient<TrackOrderVM>();
builder.Services.AddTransient<TrackOrderDetailsVM>();
builder.Services.AddTransient<StoreBasketVM>();
builder.Services.AddTransient<ProcessingPaymentVM>();
builder.Services.AddTransient<PaymentConfirmedVM>();
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
}
Ive tried these
await Shell.Current.GoToAsync("..", true); (Hangs and eventually times out)
await Shell.Current.GoToAsync(nameof(LandingPage), true); (Relative routing error try ..// etc)
Crazy thing, back from a different page
LandingPage -> AllStores
await Shell.Current.GoToAsync("..", true);
Its takes me to CreateAddress???
** Updated ** (Account button click code that takes the user to login)
[RelayCommand]
async Task BtnAccount()
{
if (CurrentUser != null)
{
await Shell.Current.GoToAsync(nameof(AccountInfo), true);
}
else
{
bool result = await Application.Current.MainPage.DisplayAlert("Account Required", $"You must be logged in to view Account details, do you wish to login now?", "Yes", "No");
if (result)
{
await Shell.Current.GoToAsync(nameof(Login), true);
}
}
}
Login Button click
[RelayCommand]
async Task Login()
{
if (IsBusy)
return;
try
{
IsBusy = true;
if (ValidateFormData())
{
User user = await _dataService.LoginUserAsync(Email, Password);
if (user != null)
{
user.Order.Charity = await _dataService.GetCharityAsync();
if (user.ContactDetails.Email != null)
{
SharedSettings.SetCurrentUser(user);
if (!user.ChangePassword)
{
try
{
var p = Shell.Current.Navigation.NavigationStack;
await Shell.Current.GoToAsync(nameof(LandingPage), true);
}
catch (Exception ex)
{
var p = ex.Message;
}
}
else
{
await Shell.Current.GoToAsync(nameof(ChangePassword), true);
}
}
else
{
await Shell.Current.DisplayAlert("Error!", "Login Failed", "OK");
}
}
else
{
await Shell.Current.DisplayAlert("Error!", $"Login Failed, account not found", "OK");
}
}
else
{
await Shell.Current.DisplayAlert("Error!", ErrorMessage, "OK");
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
await Shell.Current.DisplayAlert("Error!", $"Service is not responding, please try again later", "OK");
}
finally
{
IsBusy = false;
}
}
UPDATED The navigation stack in postion 0 is null and position 1 is the login page. I have change the navigation to use nameof(LandingPage) to create a new instance of the page instead of the ".." (pop) method however im still getting the hang and time out