Ejemplo n.º 1
0
        protected virtual async Task ProcessNavigationForNavigationPage(NavigationPage currentPage, string nextSegment, Queue <string> segments, NavigationParameters parameters, bool?useModalNavigation, bool animated)
        {
            if (currentPage.Navigation.NavigationStack.Count == 0)
            {
                await UseReverseNavigation(currentPage, nextSegment, segments, parameters, false, animated);

                return;
            }

            var clearNavigationStack     = GetClearNavigationPageNavigationStack(currentPage);
            var isEmptyOfNavigationStack = currentPage.Navigation.NavigationStack.Count == 0;

            List <Page> destroyPages;

            if (clearNavigationStack && !isEmptyOfNavigationStack)
            {
                destroyPages = currentPage.Navigation.NavigationStack.ToList();
                destroyPages.Reverse();

                await currentPage.Navigation.PopToRootAsync(false);
            }
            else
            {
                destroyPages = new List <Page>();
            }

            var topPage      = currentPage.Navigation.NavigationStack.LastOrDefault();
            var nextPageType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(nextSegment));

            if (topPage?.GetType() == nextPageType)
            {
                if (clearNavigationStack)
                {
                    destroyPages.Remove(destroyPages.Last());
                }

                await UseReverseNavigation(topPage, null, segments, parameters, false, animated);
                await DoNavigateAction(topPage, nextSegment, topPage, parameters);
            }
            else
            {
                await UseReverseNavigation(currentPage, nextSegment, segments, parameters, false, animated);

                if (clearNavigationStack && !isEmptyOfNavigationStack)
                {
                    currentPage.Navigation.RemovePage(topPage);
                }
            }

            foreach (var destroyPage in destroyPages)
            {
                PageUtilities.DestroyPage(destroyPage);
            }
        }
Ejemplo n.º 2
0
        protected virtual async Task ProcessNavigationForNavigationPage(NavigationPage currentPage, string nextSegment, Queue <string> segments, NavigationParameters parameters, bool?useModalNavigation, bool animated)
        {
            if (currentPage.Navigation.NavigationStack.Count == 0)
            {
                var newRoot = CreatePageFromSegment(nextSegment);
                await ProcessNavigation(newRoot, segments, parameters, false, animated);
                await DoNavigateAction(currentPage, nextSegment, newRoot, parameters, async() =>
                {
                    await DoPush(currentPage, newRoot, false, animated);
                });

                return;
            }

            var currentNavRoot = currentPage.Navigation.NavigationStack.Last();
            var nextPageType   = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(nextSegment));

            if (currentNavRoot.GetType() == nextPageType)
            {
                await ProcessNavigation(currentNavRoot, segments, parameters, false, animated);
                await DoNavigateAction(currentNavRoot, nextSegment, currentNavRoot, parameters);

                return;
            }
            else
            {
                bool clearNavStack = GetClearNavigationPageNavigationStack(currentPage);

                if (clearNavStack)
                {
                    await currentPage.Navigation.PopToRootAsync(false);
                }

                var newRoot = CreatePageFromSegment(nextSegment);
                await ProcessNavigation(newRoot, segments, parameters, false, animated);

                await DoNavigateAction(currentNavRoot, nextSegment, newRoot, parameters, async() =>
                {
                    var push = DoPush(currentPage, newRoot, false, animated);

                    if (clearNavStack)
                    {
                        var pageToRemove = currentPage.Navigation.NavigationStack[0];
                        currentPage.Navigation.RemovePage(pageToRemove);
                        PageUtilities.DestroyPage(pageToRemove);
                    }

                    await push;
                });

                return;
            }
        }
Ejemplo n.º 3
0
        public NavigationPath(int index, string originalString, INavigationParameters parameters)
        {
            Index = index;

            _originalString = originalString;

            // parse name/key

            Key = originalString.Split('?').First();

            // parse query

            var queryString = originalString.Split('?').Last();

            if (queryString != Key)
            {
                QueryString = queryString;
            }

            // parse parameters

            if (!string.IsNullOrEmpty(QueryString))
            {
                var query = new WwwFormUrlDecoder(QueryString);
                foreach (var item in query)
                {
                    Parameters.Add(item.Name, item.Value);
                }
            }

            // merge parameters

            if (parameters != null)
            {
                foreach (var item in parameters)
                {
                    Parameters.Add(item.Key, item.Value);
                }
            }

            // get types

            if (PageNavigationRegistry.TryGetRegistration(Key, out var info))
            {
                Key       = info.Key;
                View      = info.View;
                ViewModel = info.ViewModel;
            }
            else
            {
                throw new Exception($"Count not find Key:[{Key}]. Use RegisterTypes()/container.RegisterForNavigation<T, T>().");
            }
        }
Ejemplo n.º 4
0
        protected virtual async Task ProcessNavigationForMasterDetailPage(MasterDetailPage currentPage, string nextSegment, Queue<string> segments, NavigationParameters parameters, bool? useModalNavigation, bool animated)
        {
            bool isPresented = GetMasterDetailPageIsPresented(currentPage);

            var detail = currentPage.Detail;
            if (detail == null)
            {
                var newDetail = CreatePageFromSegment(nextSegment);
                await ProcessNavigation(newDetail, segments, parameters, useModalNavigation, animated);
                await DoNavigateAction(null, nextSegment, newDetail, parameters, onNavigationActionCompleted: () =>
                {
                    currentPage.IsPresented = isPresented;
                    currentPage.Detail = newDetail;
                });
                return;
            }

            if (useModalNavigation.HasValue && useModalNavigation.Value)
            {
                var nextPage = CreatePageFromSegment(nextSegment);
                await ProcessNavigation(nextPage, segments, parameters, useModalNavigation, animated);
                await DoNavigateAction(currentPage, nextSegment, nextPage, parameters, async () =>
                {
                    currentPage.IsPresented = isPresented;
                    await DoPush(currentPage, nextPage, true, animated);
                });
                return;
            }

            var nextSegmentType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(nextSegment));
            if (detail.GetType() == nextSegmentType)
            {
                await ProcessNavigation(detail, segments, parameters, useModalNavigation, animated);
                await DoNavigateAction(null, nextSegment, detail, parameters, onNavigationActionCompleted: () =>
                 {
                     currentPage.IsPresented = isPresented;
                 });
                return;
            }
            else
            {
                var newDetail = CreatePageFromSegment(nextSegment);
                await ProcessNavigation(newDetail, segments, parameters, newDetail is NavigationPage ? false : true, animated);
                await DoNavigateAction(detail, nextSegment, newDetail, parameters, onNavigationActionCompleted: () =>
                {
                    currentPage.IsPresented = isPresented;
                    currentPage.Detail = newDetail;
                    PageUtilities.DestroyPage(detail);
                });
                return;
            }
        }
Ejemplo n.º 5
0
        void NavigateToPageFromMasterDetailPage(MasterDetailPage currentPage, string targetSegment, Page targetPage, NavigationParameters parameters)
        {
            var detail      = currentPage.Detail;
            var segmentType = PageNavigationRegistry.GetPageType(targetSegment);

            if (detail.GetType() == segmentType)
            {
                return;
            }

            OnNavigatedFrom(detail, parameters);
            currentPage.Detail = targetPage;
            OnNavigatedTo(targetPage, parameters);
        }
Ejemplo n.º 6
0
        private static void AddSegmentToStack(Page page, Stack <string> stack)
        {
            if (page == null)
            {
                return;
            }

            var keyInfo = PageNavigationRegistry.GetPageNavigationInfo(page.GetType());

            if (keyInfo != null)
            {
                stack.Push(keyInfo.Name);
            }
        }
Ejemplo n.º 7
0
        private static void CarouselPageSelectTab(CarouselPage carouselPage, INavigationParameters parameters)
        {
            var selectedTab = parameters?.GetValue <string>(KnownNavigationParameters.SelectedTab);

            if (!string.IsNullOrWhiteSpace(selectedTab))
            {
                var selectedTabType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(selectedTab));

                foreach (var child in carouselPage.Children)
                {
                    if (child.GetType() == selectedTabType)
                    {
                        carouselPage.CurrentPage = child;
                    }
                }
            }
        }
Ejemplo n.º 8
0
        async Task ProcessNavigationForNavigationPage(NavigationPage currentPage, string nextSegment, Queue <string> segments, NavigationParameters parameters, bool?useModalNavigation, bool animated)
        {
            if (currentPage.Navigation.NavigationStack.Count == 0)
            {
                var newRoot = CreatePageFromSegment(nextSegment);
                await ProcessNavigation(newRoot, segments, parameters, false, animated);
                await DoNavigateAction(currentPage, nextSegment, newRoot, parameters, async() =>
                {
                    await DoPush(currentPage, newRoot, false, animated);
                });

                return;
            }

            var currentNavRoot = currentPage.Navigation.NavigationStack[0];
            var nextPageType   = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(nextSegment));

            if (currentNavRoot.GetType() == nextPageType)
            {
                if (currentPage.Navigation.NavigationStack.Count > 1)
                {
                    await currentPage.Navigation.PopToRootAsync(false);
                }

                await ProcessNavigation(currentNavRoot, segments, parameters, false, animated);
                await DoNavigateAction(currentNavRoot, nextSegment, currentNavRoot, parameters);

                return;
            }
            else
            {
                await currentPage.Navigation.PopToRootAsync(false);

                var newRoot = CreatePageFromSegment(nextSegment);
                await ProcessNavigation(newRoot, segments, parameters, false, animated);

                await DoNavigateAction(currentNavRoot, nextSegment, newRoot, parameters, async() =>
                {
                    await DoPush(currentPage, newRoot, false, animated);
                    currentPage.Navigation.RemovePage(currentNavRoot);
                });

                return;
            }
        }
Ejemplo n.º 9
0
        void ConfigureCarouselPage(CarouselPage carouselPage, string segment)
        {
            var selectedTab = UriParsingHelper.GetSegmentParameters(segment).GetValue <string>(KnownNavigationParameters.SelectedTab);

            if (!string.IsNullOrWhiteSpace(selectedTab))
            {
                var selectedTabType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(selectedTab));

                foreach (var child in carouselPage.Children)
                {
                    SetAutowireViewModelOnPage(child);

                    if (child.GetType() == selectedTabType)
                    {
                        carouselPage.CurrentPage = child;
                    }
                }
            }
        }
Ejemplo n.º 10
0
        async Task ProcessNavigationForMasterDetailPage(MasterDetailPage currentPage, string nextSegment, Queue <string> segments, NavigationParameters parameters, bool?useModalNavigation, bool animated)
        {
            var detail = currentPage.Detail;

            if (detail == null)
            {
                var newDetail = CreatePageFromSegment(nextSegment);
                await ProcessNavigation(newDetail, segments, parameters, newDetail is NavigationPage?false : true, animated);
                await DoNavigateAction(null, nextSegment, newDetail, parameters, () =>
                {
                    currentPage.Detail      = newDetail;
                    currentPage.IsPresented = false;
                });

                return;
            }

            var nextSegmentType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(nextSegment));

            if (detail.GetType() == nextSegmentType)
            {
                await ProcessNavigation(detail, segments, parameters, useModalNavigation, animated);
                await DoNavigateAction(null, nextSegment, detail, parameters, () =>
                {
                    currentPage.IsPresented = false;
                });

                return;
            }
            else
            {
                var newDetail = CreatePageFromSegment(nextSegment);
                await ProcessNavigation(newDetail, segments, parameters, newDetail is NavigationPage?false : true, animated);
                await DoNavigateAction(detail, nextSegment, newDetail, parameters, () =>
                {
                    currentPage.Detail      = newDetail;
                    currentPage.IsPresented = false;
                });

                return;
            }
        }
Ejemplo n.º 11
0
        protected virtual async Task ProcessNavigationForContentPage(Page currentPage, string nextSegment, Queue <string> segments, INavigationParameters parameters, bool?useModalNavigation, bool animated)
        {
            var  nextPageType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(nextSegment));
            bool useReverse   = UseReverseNavigation(currentPage, nextPageType) && !(useModalNavigation.HasValue && useModalNavigation.Value);

            if (!useReverse)
            {
                var nextPage = CreatePageFromSegment(nextSegment);

                await ProcessNavigation(nextPage, segments, parameters, useModalNavigation, animated);

                await DoNavigateAction(currentPage, nextSegment, nextPage, parameters, async() =>
                {
                    await DoPush(currentPage, nextPage, useModalNavigation, animated);
                });
            }
            else
            {
                await UseReverseNavigation(currentPage, nextSegment, segments, parameters, useModalNavigation, animated);
            }
        }
Ejemplo n.º 12
0
        void ProcessNavigationForNavigationPage(Page currentPage, string targetSegment, NavigationPage targetPage, Queue <string> segments, NavigationParameters parameters, bool useModalNavigation, bool animated)
        {
            if (targetPage.Navigation.NavigationStack.Count == 0)
            {
                ProcessNavigationSegments(targetPage, segments, parameters, false, animated);
                DoNavigate(currentPage, targetSegment, targetPage, parameters, useModalNavigation, animated);
                return;
            }

            if (segments.Count > 0) // we have a next page
            {
                var currentNavRoot = targetPage.Navigation.NavigationStack[0];
                var nextPageType   = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(segments.Peek()));
                if (currentNavRoot.GetType() == nextPageType)
                {
                    if (targetPage.Navigation.NavigationStack.Count > 1)
                    {
                        targetPage.Navigation.PopToRootAsync(false);
                    }

                    segments.Dequeue();
                    ProcessNavigationSegments(currentNavRoot, segments, parameters, false, animated);
                    DoNavigate(currentPage, targetSegment, targetPage, parameters, useModalNavigation, animated);
                    return;
                }
                else
                {
                    targetPage.Navigation.PopToRootAsync(false);
                    ProcessNavigationSegments(targetPage, segments, parameters, false, animated);
                    DoNavigate(currentPage, targetSegment, targetPage, parameters, useModalNavigation, animated);
                    targetPage.Navigation.RemovePage(currentNavRoot);
                    return;
                }
            }

            ProcessNavigationSegments(targetPage, segments, parameters, useModalNavigation, animated);
            DoNavigate(currentPage, targetSegment, targetPage, parameters, useModalNavigation, animated);
        }
Ejemplo n.º 13
0
        protected virtual async Task ProcessNavigationForCarouselPage(CarouselPage currentPage, string nextSegment, Queue<string> segments, NavigationParameters parameters, bool? useModalNavigation, bool animated)
        {
            var nextSegmentType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(nextSegment));
            foreach (var child in currentPage.Children)
            {
                if (child.GetType() != nextSegmentType)
                    continue;

                await ProcessNavigation(child, segments, parameters, useModalNavigation, animated);
                await DoNavigateAction(null, nextSegment, child, parameters, onNavigationActionCompleted: () =>
                {
                    currentPage.CurrentPage = child;
                });
                return;
            }

            var nextPage = CreatePageFromSegment(nextSegment);
            await ProcessNavigation(nextPage, segments, parameters, useModalNavigation, animated);
            await DoNavigateAction(currentPage, nextSegment, nextPage, parameters, async () =>
            {
                await DoPush(currentPage, nextPage, useModalNavigation, animated);
            });
        }
Ejemplo n.º 14
0
        //TODO: this is the exact same code as TabbedPage, how can I use this same method for both page types?
        void ProcessNavigationForCarouselPage(Page currentPage, string targetSegment, CarouselPage targetPage, Queue <string> segments, NavigationParameters parameters, bool useModalNavigation, bool animated)
        {
            if (segments.Count > 0) // we have a next page
            {
                var nextSegmentType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(segments.Peek()));
                foreach (var child in targetPage.Children)
                {
                    if (child.GetType() != nextSegmentType)
                    {
                        continue;
                    }

                    segments.Dequeue();
                    ProcessNavigationSegments(child, segments, parameters, useModalNavigation, animated);
                    targetPage.CurrentPage = child;
                    DoNavigate(currentPage, targetSegment, targetPage, parameters, useModalNavigation, animated);
                    return;
                }
            }

            ProcessNavigationSegments(targetPage, segments, parameters, useModalNavigation, animated);
            DoNavigate(currentPage, targetSegment, targetPage, parameters, useModalNavigation, animated);
        }
Ejemplo n.º 15
0
        void ConfigureTabbedPage(TabbedPage tabbedPage, string segment)
        {
            var selectedTab = UriParsingHelper.GetSegmentParameters(segment).GetValue <string>(KnownNavigationParameters.SelectedTab);

            if (!string.IsNullOrWhiteSpace(selectedTab))
            {
                //selected tab can be a single view or a view nested in a navigationpage with the syntax "NavigationPage|View"
                var selectedTabSegements = new Queue <string>(selectedTab.Split('|'));
                var selectedTabType      = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(selectedTabSegements.Dequeue()));

                string selectedTabChildSegment = string.Empty;
                if (selectedTabSegements.Count > 0)
                {
                    selectedTabChildSegment = selectedTabSegements.Dequeue();
                }

                foreach (var child in tabbedPage.Children)
                {
                    if (child.GetType() != selectedTabType)
                    {
                        continue;
                    }

                    if (child is NavigationPage)
                    {
                        var childTabType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(selectedTabChildSegment));
                        if (((NavigationPage)child).CurrentPage.GetType() != childTabType)
                        {
                            continue;
                        }
                    }

                    tabbedPage.CurrentPage = child;
                    break;
                }
            }
        }
Ejemplo n.º 16
0
        void ProcessNavigationForMasterDetailPage(Page currentPage, string targetSegment, MasterDetailPage targetPage, Queue <string> segments, NavigationParameters parameters, bool useModalNavigation, bool animated)
        {
            var detail = targetPage.Detail;

            if (detail == null)
            {
                var newDetail = CreatePage(segments.Dequeue());
                ProcessNavigationSegments(newDetail, segments, parameters, newDetail is NavigationPage ? false : true, animated);
                targetPage.Detail = newDetail;
                DoNavigate(currentPage, targetSegment, targetPage, parameters, useModalNavigation, animated);
                return;
            }

            if (segments.Count > 0) // we have a next page
            {
                var nextSegmentType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(segments.Peek()));
                if (detail.GetType() == nextSegmentType)
                {
                    segments.Dequeue();
                    ProcessNavigationSegments(detail, segments, parameters, useModalNavigation, animated);
                    DoNavigate(currentPage, targetSegment, targetPage, parameters, useModalNavigation, animated);
                    return;
                }
                else
                {
                    var newDetail = CreatePage(segments.Dequeue());
                    ProcessNavigationSegments(newDetail, segments, parameters, newDetail is NavigationPage ? false : true, animated);
                    targetPage.Detail = newDetail;
                    DoNavigate(currentPage, targetSegment, targetPage, parameters, useModalNavigation, animated);
                    return;
                }
            }

            ProcessNavigationSegments(targetPage, segments, parameters, useModalNavigation, animated);
            DoNavigate(currentPage, targetSegment, targetPage, parameters, useModalNavigation, animated);
        }
Ejemplo n.º 17
0
        protected virtual async Task ProcessNavigationForMasterDetailPage(MasterDetailPage currentPage, string nextSegment, Queue <string> segments, INavigationParameters parameters, bool?useModalNavigation, bool animated)
        {
            bool isPresented = GetMasterDetailPageIsPresented(currentPage);

            var detail = currentPage.Detail;

            if (detail == null)
            {
                var newDetail = CreatePageFromSegment(nextSegment);
                await ProcessNavigation(newDetail, segments, parameters, useModalNavigation, animated);
                await DoNavigateAction(null, nextSegment, newDetail, parameters, onNavigationActionCompleted : () =>
                {
                    currentPage.IsPresented = isPresented;
                    currentPage.Detail      = newDetail;
                });

                return;
            }

            if (useModalNavigation.HasValue && useModalNavigation.Value)
            {
                var nextPage = CreatePageFromSegment(nextSegment);
                await ProcessNavigation(nextPage, segments, parameters, useModalNavigation, animated);
                await DoNavigateAction(currentPage, nextSegment, nextPage, parameters, async() =>
                {
                    currentPage.IsPresented = isPresented;
                    await DoPush(currentPage, nextPage, true, animated);
                });

                return;
            }

            var nextSegmentType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(nextSegment));

            //we must recreate the NavigationPage everytime or the transitions on iOS will not work properly, unless we meet the two scenarios below
            bool detailIsNavPage = false;
            bool reuseNavPage    = false;

            if (detail is NavigationPage navPage)
            {
                detailIsNavPage = true;

                //first we check to see if we are being forced to reuse the NavPage by checking the interface
                reuseNavPage = !GetClearNavigationPageNavigationStack(navPage);

                if (!reuseNavPage)
                {
                    //if we weren't forced to reuse the NavPage, then let's check the NavPage.CurrentPage against the next segment type as we don't want to recreate the entire nav stack
                    //just in case the user is trying to navigate to the same page which may be nested in a NavPage
                    var nextPageType    = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(segments.Peek()));
                    var currentPageType = navPage.CurrentPage.GetType();

                    if (nextPageType == currentPageType)
                    {
                        reuseNavPage = true;
                    }
                }
            }

            if ((detailIsNavPage && reuseNavPage) || (!detailIsNavPage && detail.GetType() == nextSegmentType))
            {
                await ProcessNavigation(detail, segments, parameters, useModalNavigation, animated);
                await DoNavigateAction(null, nextSegment, detail, parameters, onNavigationActionCompleted : () =>
                {
                    currentPage.IsPresented = isPresented;
                });

                return;
            }
            else
            {
                var newDetail = CreatePageFromSegment(nextSegment);
                await ProcessNavigation(newDetail, segments, parameters, newDetail is NavigationPage?false : true, animated);
                await DoNavigateAction(detail, nextSegment, newDetail, parameters, onNavigationActionCompleted : () =>
                {
                    currentPage.IsPresented = isPresented;
                    currentPage.Detail      = newDetail;
                    PageUtilities.DestroyPage(detail);
                });

                return;
            }
        }
Ejemplo n.º 18
0
        void ConfigureTabbedPage(TabbedPage tabbedPage, string segment)
        {
            foreach (var child in tabbedPage.Children)
            {
                PageUtilities.SetAutowireViewModelOnPage(child);
                _pageBehaviorFactory.ApplyPageBehaviors(child);
                if (child is NavigationPage navPage)
                {
                    PageUtilities.SetAutowireViewModelOnPage(navPage.CurrentPage);
                    _pageBehaviorFactory.ApplyPageBehaviors(navPage.CurrentPage);
                }
            }

            var parameters = UriParsingHelper.GetSegmentParameters(segment);

            var tabsToCreate = parameters.GetValues <string>(KnownNavigationParameters.CreateTab);

            if (tabsToCreate.Count() > 0)
            {
                foreach (var tabToCreate in tabsToCreate)
                {
                    //created tab can be a single view or a view nested in a NavigationPage with the syntax "NavigationPage|ViewToCreate"
                    var tabSegements = tabToCreate.Split('|');
                    if (tabSegements.Length > 1)
                    {
                        var navigationPage = CreatePageFromSegment(tabSegements[0]) as NavigationPage;
                        if (navigationPage != null)
                        {
                            var navigationPageChild = CreatePageFromSegment(tabSegements[1]);

                            navigationPage.PushAsync(navigationPageChild);

                            //when creating a NavigationPage w/ DI, a blank Page object is injected into the ctor. Let's remove it
                            if (navigationPage.Navigation.NavigationStack.Count > 1)
                            {
                                navigationPage.Navigation.RemovePage(navigationPage.Navigation.NavigationStack[0]);
                            }

                            //set the title because Xamarin doesn't do this for us.
                            navigationPage.Title = navigationPageChild.Title;
                            navigationPage.Icon  = navigationPageChild.Icon;

                            tabbedPage.Children.Add(navigationPage);
                        }
                    }
                    else
                    {
                        var tab = CreatePageFromSegment(tabToCreate);
                        tabbedPage.Children.Add(tab);
                    }
                }
            }

            var selectedTab = parameters.GetValue <string>(KnownNavigationParameters.SelectedTab);

            if (!string.IsNullOrWhiteSpace(selectedTab))
            {
                var selectedTabType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(selectedTab));

                var childFound = false;
                foreach (var child in tabbedPage.Children)
                {
                    if (!childFound && child.GetType() == selectedTabType)
                    {
                        tabbedPage.CurrentPage = child;
                        childFound             = true;
                    }

                    if (child is NavigationPage)
                    {
                        if (!childFound && ((NavigationPage)child).CurrentPage.GetType() == selectedTabType)
                        {
                            tabbedPage.CurrentPage = child;
                            childFound             = true;
                        }
                    }
                }
            }
        }
Ejemplo n.º 19
0
        protected virtual async Task UseReverseNavigation(Page currentPage, string nextSegment, Queue <string> segments, INavigationParameters parameters, bool?useModalNavigation, bool animated)
        {
            var navigationStack = new Stack <string>();

            if (!String.IsNullOrWhiteSpace(nextSegment))
            {
                navigationStack.Push(nextSegment);
            }

            var illegalSegments = new Queue <string>();

            bool illegalPageFound = false;

            foreach (var item in segments)
            {
                //if we run into an illegal page, we need to create new navigation segments to properly handle the deep link
                if (illegalPageFound)
                {
                    illegalSegments.Enqueue(item);
                    continue;
                }

                //if any page decide to go modal, we need to consider it and all pages after it an illegal page
                var pageParameters = UriParsingHelper.GetSegmentParameters(item);
                if (pageParameters.ContainsKey(KnownNavigationParameters.UseModalNavigation))
                {
                    if (pageParameters.GetValue <bool>(KnownNavigationParameters.UseModalNavigation))
                    {
                        illegalSegments.Enqueue(item);
                        illegalPageFound = true;
                    }
                    else
                    {
                        navigationStack.Push(item);
                    }
                }
                else
                {
                    var pageType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(item));
                    if (PageUtilities.IsSameOrSubclassOf <MasterDetailPage>(pageType))
                    {
                        illegalSegments.Enqueue(item);
                        illegalPageFound = true;
                    }
                    else
                    {
                        navigationStack.Push(item);
                    }
                }
            }

            var pageOffset = currentPage.Navigation.NavigationStack.Count;

            if (currentPage.Navigation.NavigationStack.Count > 2)
            {
                pageOffset = currentPage.Navigation.NavigationStack.Count - 1;
            }

            var onNavigatedFromTarget = currentPage;

            if (currentPage is NavigationPage navPage && navPage.CurrentPage != null)
            {
                onNavigatedFromTarget = navPage.CurrentPage;
            }

            bool insertBefore = false;

            while (navigationStack.Count > 0)
            {
                var segment  = navigationStack.Pop();
                var nextPage = CreatePageFromSegment(segment);
                await DoNavigateAction(onNavigatedFromTarget, segment, nextPage, parameters, async() =>
                {
                    await DoPush(currentPage, nextPage, useModalNavigation, animated, insertBefore, pageOffset);
                });

                insertBefore = true;
            }

            //if an illegal page is found, we force a Modal navigation
            if (illegalSegments.Count > 0)
            {
                await ProcessNavigation(currentPage.Navigation.NavigationStack.Last(), illegalSegments, parameters, true, animated);
            }
        }
Ejemplo n.º 20
0
        protected virtual async Task UseReverseNavigation(Page currentPage, string nextSegment, Queue <string> segments, NavigationParameters parameters, bool?useModalNavigation, bool animated)
        {
            if (String.IsNullOrWhiteSpace(nextSegment))
            {
                return;
            }

            var navigationStack = new Stack <string>();

            var nextSegmentPageType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(nextSegment));

            if (IsSameOrSubclassOf <TabbedPage>(nextSegmentPageType))
            {
                var tabbedPage = (TabbedPage)CreatePageFromSegment(nextSegment);

                if (segments.Count > 0)
                {
                    nextSegment         = segments.Dequeue();
                    nextSegmentPageType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(nextSegment));

                    foreach (var child in tabbedPage.Children)
                    {
                        if (child.GetType() != nextSegmentPageType)
                        {
                            continue;
                        }

                        tabbedPage.CurrentPage = child;
                    }
                }

                await DoNavigateAction(currentPage, nextSegment, tabbedPage, parameters, async() =>
                {
                    await DoPush(currentPage, tabbedPage, useModalNavigation, animated, false);
                });

                currentPage = tabbedPage;
            }
            else
            {
                navigationStack.Push(nextSegment);
            }


            var illegalSegments = new Queue <string>();

            bool illegalPageFound = false;

            foreach (var item in segments)
            {
                //if we run into an illegal page, we need to create new navigation segments to properly handle the deep link
                if (illegalPageFound)
                {
                    illegalSegments.Enqueue(item);
                    continue;
                }

                var pageType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(item));
                if (IsSameOrSubclassOf <MasterDetailPage>(pageType))
                {
                    illegalSegments.Enqueue(item);
                    illegalPageFound = true;
                }
                else
                {
                    navigationStack.Push(item);
                }
            }

            var pageOffset = currentPage.Navigation.NavigationStack.Count;

            if (currentPage.Navigation.NavigationStack.Count > 2)
            {
                pageOffset = currentPage.Navigation.NavigationStack.Count - 1;
            }

            bool insertBefore = false;

            while (navigationStack.Count > 0)
            {
                Page nextPage = null;
                var  segment  = navigationStack.Pop();

                if (navigationStack.Count > 0)
                {
                    //since we are building the stack backwards, check next segment to see if it's a tabbedpage
                    var peekSegment     = navigationStack.Peek();
                    var peekSegmentType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(peekSegment));

                    //if we have a TabbedPage we must see if the prior segment is a child so we can select the tab
                    if (IsSameOrSubclassOf <TabbedPage>(peekSegmentType))
                    {
                        var tabbedPageSegment = navigationStack.Pop();
                        var tabbedPage        = (TabbedPage)CreatePageFromSegment(tabbedPageSegment);

                        var childPageType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(segment));

                        foreach (var child in tabbedPage.Children)
                        {
                            if (child.GetType() != childPageType)
                            {
                                continue;
                            }

                            await DoNavigateAction(null, segment, child, parameters, onNavigationActionCompleted : () =>
                            {
                                tabbedPage.CurrentPage = child;
                            });
                        }

                        nextPage = tabbedPage;
                    }
                }

                if (nextPage == null)
                {
                    nextPage = CreatePageFromSegment(segment);
                }

                await DoNavigateAction(currentPage, segment, nextPage, parameters, async() =>
                {
                    await DoPush(currentPage, nextPage, useModalNavigation, animated, insertBefore, pageOffset);
                });

                insertBefore = true;
            }

            //if an illegal page is found, we force a Modal navigation
            if (illegalSegments.Count > 0)
            {
                await ProcessNavigation(currentPage.Navigation.NavigationStack.Last(), illegalSegments, parameters, true, animated);
            }
        }