async Task <bool> PopToNavigationState(NavigationState state) { int index = navigationStateStack.FindIndex((ns) => ns == state); if (index == -1) { return(false); } for (int i = navigationStateStack.Count - 1; i > index; i--) { if (!await navigationStateStack [i].Hide()) { return(false); } if (!await navigationStateStack [i].Unload()) { return(false); } navigationStateStack [i].ScreenState.Dispose(); navigationStateStack.RemoveAt(i); if (!await App.Current.Navigation.Pop(null)) { return(false); } } if (!await state.Show()) { return(false); } await App.Current.EventsBroker.Publish(new NavigationEvent { Name = state.Name }); return(await App.Current.Navigation.Push(state.ScreenState.Panel)); }
async Task <bool> PushModalState(NavigationState state, IScreenState current) { modalStateStack.Add(state); if (!await state.Show()) { return(false); } await App.Current.EventsBroker.Publish(new NavigationEvent { Name = state.ScreenState.Name, IsModal = true }); await App.Current.Navigation.PushModal(state.ScreenState.Panel, current.Panel); return(true); }
/// <summary> /// Moves Back to the previous transition Panel or Modal. /// </summary> /// <returns>True: If the transition could be performed. False Otherwise</returns> public async Task <bool> MoveBack() { if (modalStateStack.Count == 0 && navigationStateStack.Count <= 1 && home == null) { Log.Debug("Moving back failed because is last transition and there isn't any home"); return(false); } try { bool triggeredFromModal; NavigationState current = LastState(out triggeredFromModal); if (!CanMove(current)) { return(false); } Log.Debug("Moving Back"); if (current != null) { if (!triggeredFromModal) { if (!await PopNavigationState()) { return(false); } } else { if (!await PopModalState(current)) { return(false); } } current = LastState(); if (triggeredFromModal) { return(await current.Unfreeze()); } else { return(await current.Show()); } } return(true); } catch (Exception ex) { Log.Exception(ex); throw; } }
/// <summary> /// Moves to a Panel inside the main window. If it has some previous modal windows /// It Pops them all. /// </summary> /// <returns>True if the move could be performed. False otherwise</returns> /// <param name="transition">Transition.</param> public async Task <bool> MoveTo(string transition, dynamic properties, bool emptyStack = false, bool forceMove = false) { Log.Debug("Moving to " + transition); if (!destination.ContainsKey(transition)) { Log.Debug("Moving failed because transition " + transition + " is not in destination dictionary."); return(false); } try { bool isModal = false; NavigationState lastState = LastState(out isModal); if (!forceMove && lastState != null && lastState.Name == transition) { Log.Debug("Not moved to " + transition + "because we're already there"); return(true); } if (!CanMove(lastState) && !forceMove) { return(false); } if (emptyStack) { if (!await EmptyStateStack()) { return(false); } if (lastState == home && home.Name != transition) { if (!await lastState.Hide()) { Log.Debug("Moving failed because home panel " + lastState.Name + " cannot move."); return(false); } } } else if (isModal) { if (!await PopAllModalStates()) { return(false); } } else if (lastState != null) { if (!await lastState.Hide()) { Log.Debug("Moving failed because panel " + lastState.Name + " cannot move."); return(false); } } IScreenState state; bool isHome = transition == home?.Name; if (isHome) { state = home.ScreenState; } else { state = destination [transition] (); if (!await state.LoadState(properties)) { // If the transition failed and the stack is empty, load the home, // otherwise show again the last state that was hidden at the start of the // MoveTo if (emptyStack) { await PushNavigationState(home.Name, home.ScreenState); } else { if (!await lastState.Show()) { // This shouldn't fail... but just in case Log.Error("Last state couldn't be shown again, we'll move back home"); await PushNavigationState(home.Name, home.ScreenState); } } return(false); } } return(await PushNavigationState(transition, state)); } catch (Exception ex) { Log.Exception(ex); throw; } }