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.OnNavigatingFromInternalAsync(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 UnloadAllPreloadedAsync();
#endregion
#region OnNavigatingTo part
var args = new AlternativeNavigationEventArgs(
newPage.Content, navigationMode, je.Parameter, je.SourcePageType);
await newPage.OnNavigatingToInternalAsync(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
this.UpdateCans();
if (currentPage != null)
{
await currentPage.OnNavigatedFromInternalAsync(args);
}
await this.OnNavigated(args);
await newPage.OnNavigatedToInternalAsync(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.UpdateCans();
//DC.TraceLocalized(GetNavigationState());
}
}