public async Task <bool> GoBack() { if (_isNavigating) { throw new InvalidOperationException("Navigation already in progress."); } _isNavigating = true; this.CanNavigate = false; this.CanGoBack = false; try { await this.WaitForLoadedAsync(); AlternativePage currentPage = null; var currentJe = this.BackStack.Pop(); var je = BackStack.Peek(); if (_currentPagePresenter != null) { currentPage = (AlternativePage)_currentPagePresenter.Content; var cancelArgs = new AlternativeNavigatingCancelEventArgs( NavigationMode.Back, je.Type); await currentPage.OnNavigatingFromInternal(cancelArgs); if (cancelArgs.Cancel) { this.BackStack.Push(currentJe); return(false); } } AlternativePage newPage; ContentPresenter newPagePresenter; if (_preloadedPageCache.ContainsKey(je)) { newPagePresenter = _preloadedPageCache[je]; newPage = (AlternativePage)newPagePresenter.Content; _preloadedPageCache.Remove(je); } else { newPage = (AlternativePage)Activator.CreateInstance(je.Type); newPage.Frame = this; newPagePresenter = new ContentPresenter { Style = PagePresenterStyle }; newPagePresenter.Content = newPage; _pagePresentersPanel.Children.Add(newPagePresenter); } newPagePresenter.Opacity = 0.005; await UnloadPreloadedPages(); var args = new AlternativeNavigationEventArgs( newPage.Content, NavigationMode.New, je.Parameter, je.Type); await newPage.OnNavigatingToInternal(args); await newPagePresenter.WaitForLoadedAsync(); await newPagePresenter.WaitForNonZeroSizeAsync(); newPagePresenter.Opacity = 1.0; if (this.PageTransition != null) { await this.PageTransition.TransitionBackward(_currentPagePresenter, newPagePresenter); } if (currentPage != null) { await currentPage.OnNavigatedFromInternal(args); _pagePresentersPanel.Children.Remove(_currentPagePresenter); } _currentPagePresenter = newPagePresenter; await newPage.OnNavigatedToInternal(args); return(true); } finally { _isNavigating = false; this.CanNavigate = true; this.CanGoBack = this.BackStack.Count > 1; } }
private async Task <bool> NavigateCore( Type sourcePageType, object parameter, NavigationMode navigationMode) { _isNavigating = true; this.CanNavigate = false; this.CanGoBack = false; this.CanGoForward = false; this.IsHitTestVisible = false; // Make sure we run on UI thread if (!Dispatcher.HasThreadAccess) { Task <bool> navigateCoreTask = null; await Dispatcher.RunAsync( CoreDispatcherPriority.High, () => navigateCoreTask = NavigateCore(sourcePageType, parameter, navigationMode)); return(await navigateCoreTask); } try { await _waitForApplyTemplateTaskSource.Task; await this.WaitForLoadedAsync(); AlternativePage currentPage = null; #region OnNavigatingFrom part if (_currentPagePresenter != null) { currentPage = (AlternativePage)_currentPagePresenter.Content; var cancelArgs = new AlternativeNavigatingCancelEventArgs( navigationMode, sourcePageType); await this.OnNavigating(cancelArgs); if (!cancelArgs.Cancel) { await currentPage.OnNavigatingFromInternal(cancelArgs); } if (cancelArgs.Cancel) { return(false); } } #endregion #region Initializing new page instance part var je = new JournalEntry { SourcePageType = sourcePageType, Parameter = parameter }; AlternativePage newPage; ContentPresenter newPagePresenter; if (_preloadedPageCache.ContainsKey(je)) { newPagePresenter = _preloadedPageCache[je]; newPage = (AlternativePage)newPagePresenter.Content; _preloadedPageCache.Remove(je); } else { newPage = _frameCache.Get(je.SourcePageType); if (newPage == null) { throw new InvalidOperationException( "Pages used in AlternativeFrame need to be of AlternativePage type."); } newPage.Frame = this; newPagePresenter = new ContentPresenter { Style = PagePresenterStyle }; newPagePresenter.Content = newPage; _pagePresentersPanel.Children.Add(newPagePresenter); } newPagePresenter.Opacity = 0.005; await UnloadAllPreloaded(); #endregion #region OnNavigatingTo part var args = new AlternativeNavigationEventArgs( newPage.Content, navigationMode, je.Parameter, je.SourcePageType); await newPage.OnNavigatingToInternal(args); #endregion #region Journal Bookeeping part switch (navigationMode) { case NavigationMode.New: this.ForwardStack.Clear(); if (this.CurrentJournalEntry != null) { this.BackStack.Push(this.CurrentJournalEntry); } break; case NavigationMode.Forward: this.ForwardStack.Pop(); if (this.CurrentJournalEntry != null) { this.BackStack.Push(this.CurrentJournalEntry); } break; case NavigationMode.Back: this.BackStack.Pop(); if (this.CurrentJournalEntry != null) { this.ForwardStack.Push(this.CurrentJournalEntry); } break; } this.CurrentJournalEntry = je; #endregion #region OnNavigated~() calls await this.OnNavigated(args); if (currentPage != null) { await currentPage.OnNavigatedFromInternal(args); } await newPage.OnNavigatedToInternal(args); #endregion #region Transition part await newPagePresenter.WaitForLoadedAsync(); await newPagePresenter.WaitForNonZeroSizeAsync(); if (this.ShouldWaitForImagesToLoad == true && newPage.ShouldWaitForImagesToLoad != false || newPage.ShouldWaitForImagesToLoad == true && this.ShouldWaitForImagesToLoad != false) { await newPage.WaitForImagesToLoad(WaitForImagesToLoadTimeout); } newPagePresenter.Opacity = 1.0; if (navigationMode == NavigationMode.Back) { await TransitionBackward( currentPage, newPage, _currentPagePresenter, newPagePresenter); } else { await TransitionForward( currentPage, newPage, _currentPagePresenter, newPagePresenter); } if (_currentPagePresenter != null) { _pagePresentersPanel.Children.Remove(_currentPagePresenter); _frameCache.Store(currentPage); } _currentPagePresenter = newPagePresenter; #endregion return(true); } finally { this.IsHitTestVisible = true; _isNavigating = false; this.CanNavigate = true; this.CanGoBack = this.BackStack.Count > 0; this.CanGoForward = this.ForwardStack.Count > 0; //DC.TraceLocalized(GetNavigationState()); } }