예제 #1
0
        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;
                }
            }
        }
예제 #2
0
 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);
     }
 }
예제 #3
0
        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);
        }
예제 #4
0
        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;
            }
        }
예제 #5
0
        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);
        }