private void GoForwardBackCore(NavigationMode mode, bool canDoIt, Stack <JournalEntry> entries, string onFailureText) { if (canDoIt) { JournalEntry entry = entries.Peek(); bool isFragmentNavigationOnly = UriParsingHelper.InternalUriIsFragment(entry.Source) || UriParsingHelper.InternalUriGetAllButFragment(entry.Source) == UriParsingHelper.InternalUriGetAllButFragment(this._currentSourceAfterMapping); if (this.RaiseNavigating(entry.Source, mode, isFragmentNavigationOnly) == false) { if (mode == NavigationMode.Back) { this.Journal.GoBack(); } else { this.Journal.GoForward(); } } else { this.RaiseNavigationStopped(null, entry.Source); } } else { Exception ex = new InvalidOperationException(onFailureText); if (this.RaiseNavigationFailed(null, ex)) { throw ex; } } }
private void UpdateNavigationCacheModeAlwaysPages() { Page currentPage = this.Host.Content as Page; if (currentPage != null) { string currentSourceWithoutFragment = UriParsingHelper.InternalUriGetAllButFragment(this.CurrentSource); if (currentPage.NavigationCacheMode == NavigationCacheMode.Required) { // If this page is NavigationCacheMode == "Required" then put it in the dictionary to store a hard reference // to it so it can be re-used by future navigations. this._cacheRequiredPages[currentSourceWithoutFragment] = currentPage; } else { // We must always try to remove, just in case this page used to be Required and is now Enabled or Disabled this._cacheRequiredPages.Remove(currentSourceWithoutFragment); } if (currentPage.NavigationCacheMode == NavigationCacheMode.Enabled) { // If this page is NavigationCacheMode == "Enabled" then put it in the cache this.Cache.AddToCache(currentSourceWithoutFragment, currentPage); } else { // We must always try to remove in case it went from Enabled to Disabled or Required this.Cache.RemoveFromCache(currentSourceWithoutFragment); } } }
private bool NavigateCore_StartNavigation(Uri uri, NavigationMode mode, bool suppressJournalAdd, Uri mergedUriAfterMapping, Uri mergedUri, bool isFragmentNavigationOnly) { this._currentNavigation = new NavigationOperation(mergedUriAfterMapping, mergedUri, uri, mode, suppressJournalAdd); if (isFragmentNavigationOnly) { // If we're navigating only to a fragment (e.g. "#frag2") then the Uri to journal should be that merged with the base uri if (UriParsingHelper.InternalUriIsFragment(uri)) { this._currentNavigation.UriForJournal = mergedUri; } this.Host.Dispatcher.BeginInvoke(() => this.CompleteNavigation(null)); return(true); } this.UpdateNavigationCacheModeAlwaysPages(); string uriAllButFragment = UriParsingHelper.InternalUriGetAllButFragment(uri); Page reusedPage = null; if (this._cacheRequiredPages.ContainsKey(uriAllButFragment)) { reusedPage = this._cacheRequiredPages[uriAllButFragment]; } else if (this.Cache.Contains(uriAllButFragment)) { reusedPage = this.Cache[uriAllButFragment]; } // If a page was found in either cache and that page hasn't yet changed its NavigationCacheMode to Disabled, // then navigation is done, otherwise open up new content if (reusedPage != null && reusedPage.NavigationCacheMode != NavigationCacheMode.Disabled) { this.Host.Dispatcher.BeginInvoke(() => this.CompleteNavigation(reusedPage)); } else { this._currentNavigation.AsyncResult = this._contentLoader.BeginLoad(mergedUriAfterMapping, this._currentSourceAfterMapping, this.ContentLoader_BeginLoad_Callback, this._currentNavigation); } return(true); }
private bool NavigateCore(Uri uri, NavigationMode mode, bool suppressJournalAdd, bool isRedirect) { try { if (uri == null) { throw new ArgumentNullException("uri", Resource.NavigationService_NavigationToANullUriIsNotSupported); } // Make sure we're on the UI thread because of the DependencyProperties we use. if (!this.Host.Dispatcher.CheckAccess()) { // Move to UI thread this.Host.Dispatcher.BeginInvoke(() => this.NavigateCore(uri, mode, suppressJournalAdd, isRedirect)); return(true); } Uri mappedUri = uri; // If the Uri is only a fragment, mapping does not take place if (!UriParsingHelper.InternalUriIsFragment(uri)) { UriMapperBase mapper = this.Host.UriMapper; if (mapper != null) { Uri uriFromMapper = mapper.MapUri(uri); if (uriFromMapper != null && !String.IsNullOrEmpty(uriFromMapper.OriginalString)) { mappedUri = uriFromMapper; } else { mappedUri = uri; } } } Uri mergedUriAfterMapping = UriParsingHelper.InternalUriMerge(this._currentSourceAfterMapping, mappedUri) ?? mappedUri; Uri mergedUri = UriParsingHelper.InternalUriMerge(this._currentSource, uri) ?? uri; // If we're navigating to just a fragment (i.e. "#frag1") or to a page which differs only in the fragment // (i.e. "Page.xaml?id=123" to "Page.xaml?id=123#frag1") then complete navigation without involving the content loader bool isFragmentNavigationOnly = (mode != NavigationMode.Refresh) && (UriParsingHelper.InternalUriIsFragment(mappedUri) || UriParsingHelper.InternalUriGetAllButFragment(mergedUri) == UriParsingHelper.InternalUriGetAllButFragment(this._currentSource)); // Check to see if anyone wants to cancel if (mode == NavigationMode.New || mode == NavigationMode.Refresh) { if (this.RaiseNavigating(mergedUri, mode, isFragmentNavigationOnly) == true) { // Someone stopped us this.RaiseNavigationStopped(null, mergedUri); return(true); } } // If the ContentLoader cannot load the new URI, throw an ArgumentException if (!this.ContentLoader.CanLoad(mappedUri, _currentSourceAfterMapping)) { throw new ArgumentException(Resource.NavigationService_CannotLoadUri, "uri"); } if (isFragmentNavigationOnly && this.Host.Content == null) { // It doesn't make sense to fragment navigate when there's no content, so raise NavigationFailed throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resource.NavigationService_FragmentNavigationRequiresContent, "Frame")); } if (isRedirect && this._currentNavigation != null && this._currentNavigation.UriForJournal == this._currentSource) { // Do not record navigation in the journal in case of a redirection // where the original target is the current URI. suppressJournalAdd = true; } // Stop in-progress navigation this.StopLoadingCore(isRedirect); return(this.NavigateCore_StartNavigation(uri, mode, suppressJournalAdd, mergedUriAfterMapping, mergedUri, isFragmentNavigationOnly)); } catch (Exception ex) { if (this.RaiseNavigationFailed(uri, ex)) { throw; } return(true); } }