예제 #1
0
        /// <summary>
        /// Registers a Page for navigation.
        /// </summary>
        /// <typeparam name="TView">The Type of Page to register</typeparam>
        /// <typeparam name="TViewModel">The BindableBase ViewModel to use as the unique name for the Page</typeparam>
        /// <param name="kernel"><see cref="IKernel"/> used to register type for Navigation.</param>
        public static void RegisterTypeForNavigation <TView, TViewModel>(this IKernel kernel)
            where TView : Page
            where TViewModel : BindableBase
        {
            Type   type = typeof(TView);
            string name = typeof(TViewModel).FullName;

            kernel.Bind <object>().To(type).Named(name);

            PageNavigationRegistry.Register(name, type);
        }
예제 #2
0
        /// <summary>
        /// Registers a Page for navigation.
        /// </summary>
        /// <typeparam name="T">The Type of Page to register</typeparam>
        /// <typeparam name="C">The Class to use as the unique name for the Page</typeparam>
        /// <param name="kernel"></param>
        public static void RegisterTypeForNavigation <T, C>(this IKernel kernel)
            where T : Page
            where C : class
        {
            Type   type = typeof(T);
            string name = typeof(C).FullName;

            kernel.Bind <object>().To(type).Named(name);

            PageNavigationRegistry.Register(name, type);
        }
예제 #3
0
        /// <summary>
        /// Registers a Page for navigation.
        /// </summary>
        /// <typeparam name="T">The Type of Page to register</typeparam>
        /// <param name="container"></param>
        /// <param name="name">The unique name to register with the Page</param>
        public static void RegisterTypeForNavigation <T>(this IContainer container, string name) where T : Page
        {
            Type type = typeof(T);

            var builder = new ContainerBuilder();

            builder.RegisterType(type).Named <object>(name);
            builder.Update(container);

            PageNavigationRegistry.Register(name, type);
        }
        private static void RegisterForNavigationWithViewModel <TViewModel>(this IContainerRegistry containerRegistry, Type viewType, string name)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                name = viewType.Name;
            }

            ViewModelLocationProvider.Register(viewType.ToString(), typeof(TViewModel));
            containerRegistry.RegisterForNavigation(viewType, name);
            PageNavigationRegistry.Register(viewType.Name, (viewType, typeof(TViewModel)));
        }
예제 #5
0
        /// <summary>
        /// Registers a Page for navigation.
        /// </summary>
        /// <typeparam name="TView">The Type of Page to register</typeparam>
        /// <typeparam name="TViewModel">The BindableBase ViewModel to use as the unique name for the Page</typeparam>
        /// <param name="container"></param>
        public static void RegisterTypeForNavigation <TView, TViewModel>(this IUnityContainer container)
            where TView : Page
            where TViewModel : BindableBase
        {
            Type   type = typeof(TView);
            string name = typeof(TViewModel).FullName;

            container.RegisterType(typeof(object), type, name);

            PageNavigationRegistry.Register(name, type);
        }
        /// <summary>
        /// Registers a Page for navigation.
        /// </summary>
        /// <typeparam name="T">The Type of Page to register</typeparam>
        /// <typeparam name="C">The Class to use as the unique name for the Page</typeparam>
        /// <param name="container"></param>
        public static void RegisterTypeForNavigation <T, C>(this IUnityContainer container)
            where T : Page
            where C : class
        {
            Type   type = typeof(T);
            string name = typeof(C).FullName;

            container.RegisterType(typeof(object), type, name);

            PageNavigationRegistry.Register(name, type);
        }
예제 #7
0
        /// <summary>
        /// Registers a Page for navigation.
        /// </summary>
        /// <typeparam name="T">The Type of Page to register</typeparam>
        /// <typeparam name="C">The Class to use as the unique name for the Page</typeparam>
        /// <param name="builder"></param>
        public static void RegisterTypeForNavigation <T, C>(this ContainerBuilder builder)
            where T : Page
            where C : class
        {
            Type   type = typeof(T);
            string name = typeof(C).FullName;

            builder.RegisterType(type).Named <object>(name);

            PageNavigationRegistry.Register(name, type);
        }
예제 #8
0
        public INavigationServiceExtensionsFixture()
        {
            PageNavigationRegistry.ClearRegistrationCache();

            PageNavigationRegistry.Register("NavigationPage", typeof(NavigationPage));
            PageNavigationRegistry.Register("Page1", typeof(NavigationPathPageMock));
            PageNavigationRegistry.Register("Page2", typeof(NavigationPathPageMock2));
            PageNavigationRegistry.Register("Page3", typeof(NavigationPathPageMock3));
            PageNavigationRegistry.Register("Page4", typeof(NavigationPathPageMock4));
            PageNavigationRegistry.Register("TabbedPage1", typeof(NavigationPathTabbedPageMock));
            PageNavigationRegistry.Register("MasterDetailPage", typeof(MasterDetailPage));
        }
예제 #9
0
        public FixtureBase(ITestOutputHelper testOutputHelper)
        {
            _testOutputHelper = testOutputHelper;
            Xamarin.Forms.Mocks.MockForms.Init();
            PageNavigationRegistry.ClearRegistrationCache();
            ContainerLocator.ResetContainer();

            var type     = typeof(PopupNavigation);
            var property = type.GetField("_popupNavigation", BindingFlags.NonPublic | BindingFlags.Static);

            property.SetValue(null, new PluginNavigationMock());
        }
예제 #10
0
        public void RegisterPageForNavigation()
        {
            PageNavigationRegistry.ClearRegistrationCache();

            var name = "MainPage";
            var type = typeof(PageMock);

            PageNavigationRegistry.Register(name, type);

            var info = PageNavigationRegistry.GetPageNavigationInfo(name);

            Assert.NotNull(info);
        }
예제 #11
0
        /// <summary>
        /// Registers a Page for navigation
        /// </summary>
        /// <param name="container"><see cref="ICodeBrixContainer"/> used to register type for Navigation.</param>
        /// <param name="viewType">The type of Page to register</param>
        /// <param name="name">The unique name to register with the Page</param>
        public static void RegisterForNavigation(this ICodeBrixContainer container, Type viewType, string name)
        {
            if (viewType == typeof(Xamarin.Forms.NavigationPage) && name == "NavigationPage")
            {
                throw new InvalidOperationException("It is not necessary to register the 'Xamarin.Forms.NavigationPage' type (unless you are "
                                                    + "registering it with a specific ViewFactory) - this type is automatically registered.");
            }

            PageNavigationRegistry.Register(name, viewType);
            RegisteredPages.Add(name);
            //Was: container.Register(typeof(object), viewType, name); //Not sure why it wanted to register types as 'Object'
            container.Register(viewType, viewType, name);
        }
예제 #12
0
        public void GetPageType()
        {
            PageNavigationRegistry.ClearRegistrationCache();

            var name = "MainPage";
            var type = typeof(PageMock);

            PageNavigationRegistry.Register(name, type);

            var infoType = PageNavigationRegistry.GetPageType(name);

            Assert.Equal(type, infoType);
        }
예제 #13
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.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)
                    {
                        currentPage.Navigation.RemovePage(currentPage.Navigation.NavigationStack[0]);
                    }

                    await push;
                });

                return;
            }
        }
예제 #14
0
        /// <summary>
        /// Registers a Page for navigation.
        /// </summary>
        /// <typeparam name="T">The Type of Page to register</typeparam>
        /// <typeparam name="C">The Class to use as the unique name for the Page</typeparam>
        /// <param name="container"></param>
        public static void RegisterTypeForNavigation <T, C>(this IContainer container)
            where T : Page
            where C : class
        {
            Type   type = typeof(T);
            string name = typeof(C).FullName;

            var builder = new ContainerBuilder();

            builder.RegisterType <C>().Named <T>(name);
            builder.Update(container);

            PageNavigationRegistry.Register(name, type);
        }
예제 #15
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);
            }
        }
    private void RegisterAllPages()
    {
        var pageBaseTypeInfo = typeof(Page).GetTypeInfo();
        var types            = GetType().GetTypeInfo().Assembly.DefinedTypes;
        var pageTypeInfos    = types
                               .Where(x => x.IsClass && pageBaseTypeInfo.IsAssignableFrom(x));

        foreach (var page in pageTypeInfos)
        {
            // the next two lines do what RegisterTypeForNavigation does
            Container.RegisterType(typeof(object), page.AsType(), page.Name);
            PageNavigationRegistry.Register(page.Name, page.AsType());
        }
    }
예제 #17
0
        public static async Task SafeNavigateAsync(this INavigationService navigationService, string name, NavigationParameters parameters = null, bool?useModalNavigation = null, bool animated = true)
        {
            var formsNav = ((Prism.Common.IPageAware)navigationService).Page.Navigation;
            IReadOnlyCollection <Page> stack = formsNav.NavigationStack;

            if (useModalNavigation != null && useModalNavigation.Value)
            {
                stack = formsNav.ModalStack;
            }
            var pageType = PageNavigationRegistry.GetPageType(name);

            if (stack.LastOrDefault()?.GetType() != pageType)
            {
                await navigationService.NavigateAsync(name, parameters, useModalNavigation, animated);
            }
        }
예제 #18
0
        public static IContainerRegistry AutoRegisterMvvmComponents(this IContainerRegistry containerRegistry, Assembly assembly)
        {
            var pageBaseTypeInfo = typeof(Page).GetTypeInfo();
            // get all pages
            var pageTypesInfos = assembly.DefinedTypes.Where(x => x.IsClass && pageBaseTypeInfo.IsAssignableFrom(x));

            foreach (var page in pageTypesInfos)
            {
                var pageName = GetPageName(page.AsType());
                // the next two lines do what  RegisterTypeForNavigation
                containerRegistry.RegisterForNavigation(page.AsType(), pageName);
                PageNavigationRegistry.Register(pageName, page.AsType());
            }

            return(containerRegistry);
        }
        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;
                    }
                }
            }
        }
        public INavigationServiceExtensionsFixture()
        {
            ContainerLocator.ResetContainer();
            var container = new Mock <IContainerExtension>();

            container.Setup(x => x.CreateScope()).Returns(Mock.Of <IScopedProvider>());
            ContainerLocator.SetContainerExtension(() => container.Object);
            PageNavigationRegistry.ClearRegistrationCache();

            PageNavigationRegistry.Register("NavigationPage", typeof(NavigationPage));
            PageNavigationRegistry.Register("Page1", typeof(NavigationPathPageMock));
            PageNavigationRegistry.Register("Page2", typeof(NavigationPathPageMock2));
            PageNavigationRegistry.Register("Page3", typeof(NavigationPathPageMock3));
            PageNavigationRegistry.Register("Page4", typeof(NavigationPathPageMock4));
            PageNavigationRegistry.Register("TabbedPage1", typeof(NavigationPathTabbedPageMock));
            PageNavigationRegistry.Register("MasterDetailPage", typeof(MasterDetailPage));
        }
예제 #21
0
        /// <summary>
        /// Registers a Page for navigation, with a function to create the Page during resolution
        /// </summary>
        /// <typeparam name="TView">The Type of Page to register</typeparam>
        /// <param name="container"><see cref="ICodeBrixContainer"/> used to register type for Navigation.</param>
        /// <param name="viewFactory">A function that will create an instance of the view type</param>
        /// <param name="name">The unique name to register with the Page</param>
        public static void RegisterForNavigation <TView>(this ICodeBrixContainer container, Func <TView> viewFactory, string name = null) where TView : Page
        {
            if (viewFactory == null)
            {
                throw new ArgumentNullException(nameof(viewFactory));
            }
            var viewType = typeof(TView);

            if (string.IsNullOrWhiteSpace(name))
            {
                name = viewType.Name;
            }

            PageNavigationRegistry.Register(name, viewType);
            RegisteredPages.Add(name);
            // ReSharper disable once RedundantTypeArgumentsOfMethod
            container.Register <TView>(viewFactory, name);
        }
예제 #22
0
            private void OnCurrentItemChanged(object sender, CurrentItemChangedEventArgs e)
            {
                if (sender is CarouselView carousel && carousel.CurrentItem != CurrentView && carousel.CurrentItem != null && carousel.CurrentItem is VisualElement newActiveView)
                {
                    var previousView = CurrentView;
                    CurrentView = newActiveView;

                    if (!_region.ActiveViews.Contains(newActiveView))
                    {
                        _region.Activate(newActiveView);
                    }

                    var info    = PageNavigationRegistry.GetPageNavigationInfo(newActiveView.GetType());
                    var context = new NavigationContext(_region.NavigationService, new Uri(info.Name, UriKind.RelativeOrAbsolute));

                    MvvmHelpers.OnNavigatedFrom(previousView, context);
                    MvvmHelpers.OnNavigatedTo(newActiveView, context);
                }
            }
        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);
            }
        }
        private static Page GetTargetPage(TabbedPage tabbedPage, string name)
        {
            var tabToSelectedType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(name));

            if (tabToSelectedType is null)
            {
                throw new Exception($"No View Type has been registered for '{name}'");
            }

            Page target = null;

            foreach (var child in tabbedPage.Children)
            {
                if (child.GetType() == tabToSelectedType)
                {
                    target = child;
                    break;
                }

                if (child is NavigationPage childNavPage)
                {
                    if (childNavPage.CurrentPage.GetType() == tabToSelectedType ||
                        childNavPage.RootPage.GetType() == tabToSelectedType)
                    {
                        target = child;
                        break;
                    }
                }
            }

            if (target is null)
            {
                throw new Exception($"Could not find a Child Tab for '{name}'");
            }

            return(target);
        }
예제 #25
0
 /// <summary>
 /// Registers a Page for navigation
 /// </summary>
 /// <param name="containerRegistry"><see cref="IContainerRegistry"/> used to register type for Navigation.</param>
 /// <param name="viewType">The type of Page to register</param>
 /// <param name="name">The unique name to register with the Page</param>
 public static void RegisterForNavigation(this IContainerRegistry containerRegistry, Type viewType, string name)
 {
     PageNavigationRegistry.Register(name, viewType);
     containerRegistry.Register(typeof(object), viewType, name);
 }
        /// <inheritdoc />
        protected override 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 : p =>
                {
                    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;

                //we only care if we the next segment is also a NavigationPage.
                if (IsSameOrSubclassOf <NavigationPage>(nextSegmentType))
                {
                    //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 : p =>
                {
                    if (detail is TabbedPage && nextSegment.Contains(KnownNavigationParameters.SelectedTab))
                    {
                        var segmentParams = UriParsingHelper.GetSegmentParameters(nextSegment);
                        SelectPageTab(detail, segmentParams);
                    }

                    currentPage.IsPresented = isPresented;
                });

                return;
            }
            else
            {
                var newDetail         = CreatePageFromSegment(nextSegment);
                var segmentParameters = UriParsingHelper.GetSegmentParameters(nextSegment, parameters);
                await ProcessNavigation(newDetail, segments, segmentParameters, newDetail is NavigationPage?false : true, animated);

                await DoNavigationActionForNewDetail(currentPage, newDetail, detail, detailIsNavPage, isPresented, animated, nextSegment, segmentParameters);
            }
        }
예제 #27
0
        public static async Task <INavigationResult> SelectTabAsync(this INavigationService navigationService, string name, INavigationParameters parameters = null)
        {
            NavigationResult navigationResult = new NavigationResult {
                Success = true
            };

            try
            {
                var currentPage = ((IPageAware)navigationService).Page;
                var canNavigate = await PageUtilities.CanNavigateAsync(currentPage, parameters);

                if (!canNavigate)
                {
                    throw new Exception($"IConfirmNavigation for {currentPage} returned false");
                }
                TabbedPage tabbedPage = null;
                if (currentPage is TabbedPage)
                {
                    tabbedPage = currentPage as TabbedPage;
                }
                if (currentPage.Parent is TabbedPage parent)
                {
                    tabbedPage = parent;
                }
                else if (currentPage.Parent is NavigationPage navPage)
                {
                    if (navPage.Parent != null && navPage.Parent is TabbedPage parent2)
                    {
                        tabbedPage = parent2;
                    }
                }
                if (tabbedPage == null)
                {
                    throw new Exception("No parent TabbedPage could be found");
                }
                var tabToSelectedType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(name));
                if (tabToSelectedType is null)
                {
                    throw new Exception($"No View Type has been registered for '{name}'");
                }
                Page target = null;
                foreach (var child in tabbedPage.Children)
                {
                    if (child.GetType() == tabToSelectedType)
                    {
                        target = child;
                        break;
                    }
                    if (child is NavigationPage childNavPage)
                    {
                        if (childNavPage.CurrentPage.GetType() == tabToSelectedType ||
                            childNavPage.RootPage.GetType() == tabToSelectedType)
                        {
                            target = child;
                            break;
                        }
                    }
                }
                if (target is null)
                {
                    throw new Exception($"Could not find a Child Tab for '{name}'");
                }
                var tabParameters = UriParsingHelper.GetSegmentParameters(name, parameters);
                tabbedPage.CurrentPage = target;
                PageUtilities.OnNavigatedFrom(currentPage, tabParameters);
                PageUtilities.OnNavigatedTo(target, tabParameters);
            }
            catch (Exception ex)
            {
                navigationResult = new NavigationResult {
                    Exception = ex
                };
            }
            return(navigationResult);
        }
예제 #28
0
 /// <summary>
 /// Registers a Page for navigation
 /// </summary>
 /// <param name="container"><see cref="IKernel"/> used to register type for Navigation.</param>
 /// <param name="viewType">The type of Page to register</param>
 /// <param name="name">The unique name to register with the Page</param>
 public static void RegisterTypeForNavigation(this IKernel container, Type viewType, string name)
 {
     PageNavigationRegistry.Register(name, viewType);
     container.Bind <object>().To(viewType).Named(name);
 }
예제 #29
0
 public void Dispose()
 {
     PageNavigationRegistry.ClearRegistrationCache();
 }
예제 #30
0
 /// <summary>
 /// Registers a Page for navigation
 /// </summary>
 /// <param name="container"><see cref="IUnityContainer"/> used to register type for Navigation.</param>
 /// <param name="viewType">The type of Page to register</param>
 /// <param name="name">The unique name to register with the Page</param>
 /// <returns><see cref="IUnityContainer"/></returns>
 public static IUnityContainer RegisterTypeForNavigation(this IUnityContainer container, Type viewType, string name)
 {
     PageNavigationRegistry.Register(name, viewType);
     return(container.RegisterType(typeof(object), viewType, name));
 }