private void ReloadViewInternal(Route route) { if (routeHead.Route == route) { try { var view = route.CreateView(true); routeHead.CachedView = view; var frameworkElement = view as FrameworkElement; if (frameworkElement != null && frameworkElement.DataContext == null) { frameworkElement.DataContext = route; } OnPropertyChanged(nameof(CurrentView)); } catch (Exception ex) { RouteErrorListener.TryOnRouteEventException(route, RouteEventType.ViewCreation, ex); } } else { var routeItem = stack.FirstOrDefault(item => item.Route == route); if (routeItem != null) { routeItem.CachedView = null; } } }
private async Task OnRouteReady(Route route, RouteActivationMethod method, List <RouteEventError> errors) { try { await route.OnRouteReady(method, errors); } catch (Exception ex) { RouteErrorListener.TryOnRouteEventException(route, RouteEventType.Ready, ex); } }
private async Task <TaskCompletionSource <object> > PushRoute(Route route, bool cacheCurrentView, bool ignoreCurrent, List <RouteEventError> errors) { route.Routes = this; var currentRoute = Current; if (currentRoute != null && !cacheCurrentView) { routeHead.CachedView = null; } if (!ignoreCurrent && currentRoute != null) { try { await currentRoute.OnRouteHiding(); } catch (Exception ex) { RouteErrorListener.TryOnRouteEventException(currentRoute, RouteEventType.Hiding, ex); } } try { await route.OnRouteInitializing(); } catch (Exception ex) { errors.Add(new RouteEventError(RouteEventType.Initializing, ex)); RouteErrorListener.TryOnRouteEventException(route, RouteEventType.Initializing, ex); } try { await route.OnRouteActivating(); } catch (Exception ex) { errors.Add(new RouteEventError(RouteEventType.Activating, ex)); RouteErrorListener.TryOnRouteEventException(route, RouteEventType.Activating, ex); } var item = new RouteItem(route); try { var view = route.CreateView(false); item.CachedView = view; var frameworkElement = view as FrameworkElement; if (frameworkElement != null && frameworkElement.DataContext == null) { frameworkElement.DataContext = route; } } catch (Exception ex) { errors.Add(new RouteEventError(RouteEventType.ViewCreation, ex)); RouteErrorListener.TryOnRouteEventException(route, RouteEventType.ViewCreation, ex); } stack.Push(item); RouteHead = item; if (!ignoreCurrent && currentRoute != null) { try { await currentRoute.OnRouteHidden(); } catch (Exception ex) { RouteErrorListener.TryOnRouteEventException(currentRoute, RouteEventType.Hidden, ex); } } try { await route.OnRouteInitialized(); } catch (Exception ex) { errors.Add(new RouteEventError(RouteEventType.Initialized, ex)); RouteErrorListener.TryOnRouteEventException(route, RouteEventType.Initialized, ex); } try { await route.OnRouteActivated(); } catch (Exception ex) { errors.Add(new RouteEventError(RouteEventType.Activated, ex)); RouteErrorListener.TryOnRouteEventException(route, RouteEventType.Activated, ex); } return(item.CompletionSource); }
private async Task ChangeRoute(Route route, List <TaskCompletionSource <object> > completionSources, List <RouteEventError> errors) { var sentinel = 0; while (true) { if (++sentinel == 32) { throw new RouteTransitionException("Detected possible loop with transient routes."); } var transientRoute = route as TransientRoute; if (transientRoute != null) { transientRoute.Routes = this; var transientRouteErrors = new List <RouteEventError>(); try { await transientRoute.OnRouteInitializing(); } catch (Exception ex) { transientRouteErrors.Add(new RouteEventError(RouteEventType.Initializing, ex)); } try { await transientRoute.OnRouteActivating(); } catch (Exception ex) { transientRouteErrors.Add(new RouteEventError(RouteEventType.Activating, ex)); } try { route = transientRoute.GetNextRoute(transientRouteErrors); } catch (Exception ex) { throw new RouteTransitionException( "A transient route threw an exception while switching to next route.", ex); } if (route == null) { throw new RouteTransitionException("A transient route resulted in a dead end."); } if (route.Routes != null && route.Routes != this) { throw new RouteTransitionException(ErrorMessages.RoutesAssociatedWithOtherStack); } continue; } while (stack.Count != 0) { var item = stack.Pop(); completionSources.Add(item.CompletionSource); try { await item.Route.OnRouteDeactivating(true); } catch (Exception ex) { RouteErrorListener.TryOnRouteEventException(item.Route, RouteEventType.Deactivating, ex); } item.CachedView = null; try { await item.Route.OnRouteDeactivated(true); } catch (Exception ex) { RouteErrorListener.TryOnRouteEventException(item.Route, RouteEventType.Deactivated, ex); } } await PushRoute(route, false, true, errors); break; } }
public async Task <Route> Pop(object result) { SynchronizationContext.VerifyAccess(); if (stack.Count <= 1) { throw new InvalidOperationException("Cannot pop base route."); } RouteItem poppedRoute; RouteItem nextRoute; List <RouteEventError> errors; using (Lock) { poppedRoute = stack.Pop(); nextRoute = stack.Peek(); errors = new List <RouteEventError>(); try { await poppedRoute.Route.OnRouteDeactivating(false); } catch (Exception ex) { RouteErrorListener.TryOnRouteEventException(poppedRoute.Route, RouteEventType.Deactivating, ex); } try { await nextRoute.Route.OnRouteRestoring(result); } catch (Exception ex) { errors.Add(new RouteEventError(RouteEventType.Restoring, ex)); RouteErrorListener.TryOnRouteEventException(nextRoute.Route, RouteEventType.Restoring, ex); } poppedRoute.CachedView = null; var route = nextRoute.Route; if (nextRoute.CachedView == null) { try { var view = route.CreateView(false); nextRoute.CachedView = view; var frameworkElement = view as FrameworkElement; if (frameworkElement != null && frameworkElement.DataContext == null) { frameworkElement.DataContext = route; } } catch (Exception ex) { errors.Add(new RouteEventError(RouteEventType.ViewCreation, ex)); RouteErrorListener.TryOnRouteEventException(route, RouteEventType.ViewCreation, ex); } } RouteHead = nextRoute; try { await poppedRoute.Route.OnRouteDeactivated(false); } catch (Exception ex) { RouteErrorListener.TryOnRouteEventException(poppedRoute.Route, RouteEventType.Deactivated, ex); } try { await nextRoute.Route.OnRouteRestored(result); } catch (Exception ex) { errors.Add(new RouteEventError(RouteEventType.Restored, ex)); RouteErrorListener.TryOnRouteEventException(nextRoute.Route, RouteEventType.Restored, ex); } } await OnRouteReady(nextRoute.Route, RouteActivationMethod.Restored, errors); poppedRoute.CompletionSource.SetResult(result); return(nextRoute.Route); }