Example #1
0
 public async Task <bool> RefreshAsync(object param)
 {
     return(await NavigationOrchestratorAsync(CurrentPageType, param, NavigationMode.Refresh, () =>
     {
         Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
         FrameEx2.SetNavigationState(FrameEx2.GetNavigationState());
         return true;
     }));
 }
Example #2
0
        public async Task <bool> NavigateAsync(Type page, object parameter = null, NavigationTransitionInfo infoOverride = null)
        {
            LogThis($"Page: {page}, Parameter: {parameter ?? "null"}, NavigationTransitionInfo: {infoOverride}");

            return(await NavigationOrchestratorAsync(page, parameter, NavigationMode.New, () =>
            {
                if (Settings.SerializeParameters)
                {
                    var serializedParameter = parameter.TrySerializeEx(out var result) ? result : throw new Exception("Parameter cannot be serialized.");
                    return FrameEx2.Navigate(page, serializedParameter, infoOverride);
                }
Example #3
0
        public async Task <bool> NavigateAsync(Type page, object parameter = null, NavigationTransitionInfo infoOverride = null)
        {
            this.Log($"Page: {page}, Parameter: {parameter ?? "null"}, NavigationTransitionInfo: {infoOverride}");

            return(await NavigationOrchestratorAsync(page, parameter, NavigationMode.New, () =>
            {
                try
                {
                    return FrameEx2.Navigate(page, parameter, infoOverride);
                }
                catch (Exception)
                {
                    Debugger.Break();
                    throw;
                }
            }));
        }
Example #4
0
        public async Task <bool> GoForwardAsync()
        {
            if (!CanGoForward)
            {
                return(true);
            }
            var next = FrameEx.ForwardStack.FirstOrDefault();

            // there is no parameter when going forward and back
            return(await NavigationOrchestratorAsync(next.SourcePageType, null, NavigationMode.Forward, () =>
            {
                if (CanGoForward)
                {
                    FrameEx2.GoForward();
                }
                return true;
            }));
        }
Example #5
0
        public async Task <bool> GoBackAsync(NavigationTransitionInfo infoOverride = null)
        {
            if (!CanGoBack)
            {
                return(true);
            }
            var previous = FrameEx.BackStack.LastOrDefault();

            // there is no parameter when going forward and back
            return(await NavigationOrchestratorAsync(previous.SourcePageType, null, NavigationMode.Back, () =>
            {
                if (CanGoBack)
                {
                    FrameEx2.GoBack(infoOverride);
                }
                return true;
            }));
        }
Example #6
0
        private async Task <bool> NavigationOrchestratorAsync(Type page, object parameter, NavigationMode mode, Func <bool> navigate)
        {
            try
            {
                await _navigationOrchestratorAsyncSemaphore.WaitAsync();

                this.Log($"Page: {page}, Parameter: {parameter}, NavigationMode: {mode}");

                if (page == null)
                {
                    throw new ArgumentNullException(nameof(page));
                }

                if (navigate == null)
                {
                    throw new ArgumentNullException(nameof(navigate));
                }

                // this cannot be used for duplicate navigation, except for refresh
                if (!Equals(mode, NavigationMode.Refresh))
                {
                    if (Equals(page, CurrentPageType))
                    {
                        if (Equals(parameter, CurrentPageParam))
                        {
                            return(false);
                        }
                    }
                }

                // fetch current (which will become old)
                var fromPage      = FrameEx.Content as Page;
                var fromParameter = CurrentPageParam;
                var fromViewModel = fromPage?.DataContext;
                var fromPageName  = fromPage?.GetType().ToString();
                var fromPageState = await FrameEx2.GetPageStateAsync(fromPage?.GetType());

                var from = new NavigationInfo(fromPage?.GetType(), fromParameter, fromPageState);

                var toPageName  = page?.ToString();
                var toPageState = await FrameEx2.GetPageStateAsync(toPageName);

                var to = new NavigationInfo(page, parameter, toPageState);

                // call fromViewModel.OnNavigatingFromAsync()
                var NavigatingFromAsyncResult = await ViewModelActionStrategy.NavigatingFromAsync(fromViewModel, mode, false, from, to, this);

                if (NavigatingFromAsyncResult == ContinueResult.Stop)
                {
                    return(false);
                }

                // raise Navigating event
                Two.RaiseNavigatingCancels(parameter, false, mode, to, out var RaiseNavigatingCancelsResult);
                if (RaiseNavigatingCancelsResult == ContinueResult.Stop)
                {
                    return(false);
                }

                // try to resolve the view-model before navigation
                var newViewModel = await ViewModelResolutionStrategy.ResolveViewModelAsync(page);

                if (newViewModel != null)
                {
                    if (newViewModel is ITemplate10ViewModel t)
                    {
                        t.NavigationService = this;
                    }
                    await ViewModelActionStrategy.NavigatingToAsync(newViewModel, mode, false, from, to, this);
                }

                // navigate
                var newPage = default(Page);
                if (navigate.Invoke())
                {
                    if ((newPage = FrameEx.Content as Page) == null)
                    {
                        return(false);
                    }
                    CurrentPageParam = parameter;
                    CurrentPageType  = page;
                }
                else
                {
                    return(false);
                }

                // fetch current (which is now new)
                if (newViewModel != null)
                {
                    newPage.DataContext = newViewModel;
                }
                else if ((newViewModel = newPage?.DataContext) != null)
                {
                    await ViewModelActionStrategy.NavigatingToAsync(newViewModel, mode, false, from, to, this);
                }

                // raise Navigated event
                Two.RaiseNavigated(new NavigatedEventArgs()
                {
                    Parameter      = parameter,
                    NavigationMode = mode,
                    PageType       = newPage?.GetType(),
                });

                // call fromViewModel.OnNavigatedFrom()
                await ViewModelActionStrategy.NavigatedFromAsync(fromViewModel, mode, false, from, to, this);

                // call toTemplate10ViewModel.Properties
                if (newViewModel is ITemplate10ViewModel vm)
                {
                    vm.NavigationService = this;
                }

                // call newViewModel.OnNavigatedToAsync()
                await ViewModelActionStrategy.NavigatedToAsync(newViewModel, mode, false, from, to, this);

                // finally, all-good
                return(true);
            }
            catch (Exception ex)
            {
                this.Log(ex.Message, Severities.Error);
                Debugger.Break();
                throw;
            }
            finally
            {
                _navigationOrchestratorAsyncSemaphore.Release();
            }
        }