Exemple #1
0
        async Task <bool> INavigateInternal.GoBackInternal(NavigationParameters parameters, bool?useModalNavigation, bool animated)
        {
            try
            {
                NavigationSource = PageNavigationSource.NavigationService;

                var page = GetCurrentPage();
                var segmentParameters = UriParsingHelper.GetSegmentParameters(null, parameters);
                segmentParameters.AddInternalParameter(KnownInternalParameters.NavigationMode, NavigationMode.Back);

                var canNavigate = await PageUtilities.CanNavigateAsync(page, segmentParameters);

                if (!canNavigate)
                {
                    return(false);
                }

                bool useModalForDoPop = UseModalNavigation(page, useModalNavigation);
                Page previousPage     = PageUtilities.GetOnNavigatedToTarget(page, _applicationProvider.MainPage, useModalForDoPop);

                PageUtilities.OnNavigatingTo(previousPage, segmentParameters);

                var poppedPage = await DoPop(page.Navigation, useModalForDoPop, animated);

                if (poppedPage != null)
                {
                    PageUtilities.OnNavigatedFrom(page, segmentParameters);
                    PageUtilities.OnNavigatedTo(previousPage, segmentParameters);
                    PageUtilities.DestroyPage(poppedPage);
                    return(true);
                }
            }
            catch (Exception e)
            {
                _logger.Log(e.ToString(), Category.Exception, Priority.High);
                return(false);
            }
            finally
            {
                NavigationSource = PageNavigationSource.Device;
            }

            return(false);
        }
        public override async Task <bool> GoBackAsync(INavigationParameters parameters = null, bool?useModalNavigation = default(bool?), bool animated = true)
        {
            try
            {
                NavigationSource = PageNavigationSource.NavigationService;

                switch (PopupUtilities.TopPage(_popupNavigation, _applicationProvider))
                {
                case PopupPage popupPage:
                    var segmentParameters = UriParsingHelper.GetSegmentParameters(null, parameters);
                    segmentParameters.Add(KnownNavigationParameters.NavigationMode, NavigationMode.Back);
                    var previousPage = PopupUtilities.GetOnNavigatedToTarget(_popupNavigation, _applicationProvider);

                    PageUtilities.OnNavigatingTo(previousPage, segmentParameters);
                    await DoPop(popupPage.Navigation, false, animated);

                    if (popupPage != null)
                    {
                        PageUtilities.InvokeViewAndViewModelAction <IActiveAware>(popupPage, a => a.IsActive = false);
                        PageUtilities.OnNavigatedFrom(popupPage, segmentParameters);
                        PageUtilities.OnNavigatedTo(previousPage, segmentParameters);
                        PageUtilities.InvokeViewAndViewModelAction <IActiveAware>(previousPage, a => a.IsActive = true);
                        PageUtilities.DestroyPage(popupPage);
                        return(true);
                    }
                    break;

                default:
                    return(await base.GoBackAsync(parameters, useModalNavigation, animated));
                }
            }
            catch (Exception e)
            {
                _logger.Log(e.ToString(), Category.Exception, Priority.High);
                return(false);
            }
            finally
            {
                NavigationSource = PageNavigationSource.Device;
            }

            return(false);
        }
Exemple #3
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;
                    }
                }
            }
        }
Exemple #4
0
        protected static async Task DoNavigateAction(Page fromPage, string toSegment, Page toPage, NavigationParameters parameters, Func<Task> navigationAction = null, Action onNavigationActionCompleted = null)
        {
            var segmentParameters = UriParsingHelper.GetSegmentParameters(toSegment, parameters);
            segmentParameters.Add(KnownNavigationParameters.NavigationMode, NavigationMode.New);

            var canNavigate = await PageUtilities.CanNavigateAsync(fromPage, segmentParameters);
            if (!canNavigate)
                return;

            PageUtilities.OnNavigatingTo(toPage, segmentParameters);

            if (navigationAction != null)
                await navigationAction();

            PageUtilities.OnNavigatedFrom(fromPage, segmentParameters);

            onNavigationActionCompleted?.Invoke();

            PageUtilities.OnNavigatedTo(toPage, segmentParameters);
        }
        public void ParametersParsedFromDeepLinkAbsoluteUri()
        {
            var target = UriParsingHelper.GetUriSegments(new Uri(_deepLinkAbsoluteUri));

            Assert.Equal(target.Count, 4);

            var p1 = UriParsingHelper.GetSegmentParameters(target.Dequeue());

            Assert.Equal(p1["id"], "1");

            var p2 = UriParsingHelper.GetSegmentParameters(target.Dequeue());

            Assert.Equal(p2["id"], "2");

            var p3 = UriParsingHelper.GetSegmentParameters(target.Dequeue());

            Assert.Equal(p3["id"], "3");

            var p4 = UriParsingHelper.GetSegmentParameters(target.Dequeue());

            Assert.Equal(p4["id"], "4");
        }
        public void ParametersParsedFromDeepLinkRelativeUri()
        {
            var target = UriParsingHelper.GetUriSegments(new Uri(_deepLinkRelativeUri, UriKind.Relative));

            Assert.Equal(4, target.Count);

            var p1 = UriParsingHelper.GetSegmentParameters(target.Dequeue());

            Assert.Equal("1", p1["id"]);

            var p2 = UriParsingHelper.GetSegmentParameters(target.Dequeue());

            Assert.Equal("2", p2["id"]);

            var p3 = UriParsingHelper.GetSegmentParameters(target.Dequeue());

            Assert.Equal("3", p3["id"]);

            var p4 = UriParsingHelper.GetSegmentParameters(target.Dequeue());

            Assert.Equal("4", p4["id"]);
        }
        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;
                }
            }
        }
Exemple #8
0
        public async void OnNavigatingTo(NavigationParameters parameters)
        {
            var tabs = parameters.GetValues <string>(AppConstants.DynamicTabKey);

            foreach (var tabSegment in tabs)
            {
                Page page = null;

                var uri = UriParsingHelper.Parse(tabSegment);
                foreach (var segment in UriParsingHelper.GetUriSegments(uri))
                {
                    if (page != null && !(page is NavigationPage))
                    {
                        continue;
                    }

                    var segmentPage = CreatePage(UriParsingHelper.GetSegmentName(segment));
                    segmentPage.Behaviors.Add(new IsActiveAwareBehavior());
                    PageUtilities.OnNavigatingTo(segmentPage,
                                                 UriParsingHelper.GetSegmentParameters(segment, parameters));
                    switch (page)
                    {
                    case null:
                        page = segmentPage;
                        break;

                    case NavigationPage navPage:
                        await navPage.PushAsync(segmentPage);

                        break;
                    }
                }

                Children.Add(page);
            }
        }
Exemple #9
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);
            }
        }
Exemple #10
0
        protected virtual async Task ProcessNavigationForNavigationPage(NavigationPage currentPage, string nextSegment, Queue <string> segments, INavigationParameters 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());
                }

                if (segments.Count > 0)
                {
                    await UseReverseNavigation(topPage, segments.Dequeue(), segments, parameters, false, animated);
                }

                await DoNavigateAction(topPage, nextSegment, topPage, parameters, onNavigationActionCompleted : () =>
                {
                    if (nextSegment.Contains(KnownNavigationParameters.SelectedTab))
                    {
                        var segmentParams = UriParsingHelper.GetSegmentParameters(nextSegment);
                        SelectPageTab(topPage, segmentParams);
                    }
                });
            }
            else
            {
                await UseReverseNavigation(currentPage, nextSegment, segments, parameters, false, animated);

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

            foreach (var destroyPage in destroyPages)
            {
                PageUtilities.DestroyPage(destroyPage);
            }
        }
        public void ParametersParsedFromEmptySegment()
        {
            var parameters = UriParsingHelper.GetSegmentParameters(string.Empty);

            Assert.NotNull(parameters);
        }
        public void ParametersParsedFromNullSegment()
        {
            var parameters = UriParsingHelper.GetSegmentParameters(null);

            Assert.NotNull(parameters);
        }
Exemple #13
0
        public void ShowDialog(string name, IDialogParameters parameters, Action <IDialogResult> callback)
        {
            try
            {
                parameters = UriParsingHelper.GetSegmentParameters(name, parameters);

                var view = CreateViewFor(UriParsingHelper.GetSegmentName(name));

                var dialogAware = InitializeDialog(view, parameters);
                var currentPage = GetCurrentPage();

                dialogAware.RequestClose += DialogAware_RequestClose;

                void DialogAware_RequestClose(IDialogParameters outParameters)
                {
                    try
                    {
                        var result = CloseDialog(outParameters ?? new DialogParameters(), currentPage);
                        if (result.Exception is DialogException de && de.Message == DialogException.CanCloseIsFalse)
                        {
                            return;
                        }

                        dialogAware.RequestClose -= DialogAware_RequestClose;
                        callback?.Invoke(result);
                        GC.Collect();
                    }
                    catch (DialogException dex)
                    {
                        if (dex.Message != DialogException.CanCloseIsFalse)
                        {
                            callback?.Invoke(new DialogResult
                            {
                                Exception  = dex,
                                Parameters = parameters
                            });
                        }
                    }
                    catch (Exception ex)
                    {
                        callback?.Invoke(new DialogResult
                        {
                            Exception  = ex,
                            Parameters = parameters
                        });
                    }
                }

                if (!parameters.TryGetValue <bool>(KnownDialogParameters.CloseOnBackgroundTapped, out var closeOnBackgroundTapped))
                {
                    var dialogLayoutCloseOnBackgroundTapped = DialogLayout.GetCloseOnBackgroundTapped(view);
                    if (dialogLayoutCloseOnBackgroundTapped.HasValue)
                    {
                        closeOnBackgroundTapped = dialogLayoutCloseOnBackgroundTapped.Value;
                    }
                }

                InsertPopupViewInCurrentPage(currentPage as ContentPage, view, closeOnBackgroundTapped, DialogAware_RequestClose);

                PageUtilities.InvokeViewAndViewModelAction <IActiveAware>(currentPage, aa => aa.IsActive = false);
                PageUtilities.InvokeViewAndViewModelAction <IActiveAware>(view, aa => aa.IsActive        = true);
            }
            catch (Exception ex)
            {
                var error = ex.ToString();
                callback?.Invoke(new DialogResult {
                    Exception = ex
                });
            }
        }
        /// <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);
            }
        }
Exemple #15
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);
        }
Exemple #16
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;
                        }
                    }
                }
            }
        }
Exemple #17
0
        /// <inheritdoc />
        public void ShowDialog(string name, IDialogParameters parameters, Action <IDialogResult> callback)
        {
            try
            {
                parameters = UriParsingHelper.GetSegmentParameters(name, parameters);

                var view      = CreateViewFor(UriParsingHelper.GetSegmentName(name));
                var popupPage = CreatePopupPageForView(view);

                var dialogAware = InitializeDialog(view, parameters);

                if (!parameters.TryGetValue <bool>(KnownDialogParameters.CloseOnBackgroundTapped, out var closeOnBackgroundTapped))
                {
                    var dialogLayoutCloseOnBackgroundTapped = DialogLayout.GetCloseOnBackgroundTapped(view);
                    if (dialogLayoutCloseOnBackgroundTapped.HasValue)
                    {
                        closeOnBackgroundTapped = dialogLayoutCloseOnBackgroundTapped.Value;
                    }
                }

                if (!parameters.TryGetValue <bool>(KnownPopupDialogParameters.Animated, out var animated))
                {
                    animated = true;
                }

                var popupDialogLayoutIsAnimationEnabled = PopupDialogLayout.GetIsAnimationEnabled(view);
                popupPage.IsAnimationEnabled = popupDialogLayoutIsAnimationEnabled ?? true;

                dialogAware.RequestClose += DialogAware_RequestClose;

                void CloseOnBackgroundClicked(object sender, EventArgs args)
                {
                    DialogAware_RequestClose(new DialogParameters());
                }

                void DialogAware_RequestClose(IDialogParameters outParameters)
                {
                    try
                    {
                        var result = CloseDialog(outParameters ?? new DialogParameters(), popupPage, view);
                        if (result.Exception is DialogException de && de.Message == DialogException.CanCloseIsFalse)
                        {
                            return;
                        }

                        dialogAware.RequestClose -= DialogAware_RequestClose;
                        if (closeOnBackgroundTapped)
                        {
                            popupPage.BackgroundClicked -= CloseOnBackgroundClicked;
                        }
                        callback?.Invoke(result);
                        GC.Collect();
                    }
                    catch (DialogException dex)
                    {
                        if (dex.Message != DialogException.CanCloseIsFalse)
                        {
                            callback?.Invoke(new DialogResult
                            {
                                Exception  = dex,
                                Parameters = parameters
                            });
                        }
                    }
                    catch (Exception ex)
                    {
                        callback?.Invoke(new DialogResult
                        {
                            Exception  = ex,
                            Parameters = parameters
                        });
                    }
                }

                if (closeOnBackgroundTapped)
                {
                    popupPage.BackgroundClicked += CloseOnBackgroundClicked;
                }

                Action <IDialogParameters> closeCallback = closeOnBackgroundTapped ? DialogAware_RequestClose : p => { };
                PushPopupPage(popupPage, view, closeCallback, animated);
            }
            catch (Exception ex)
            {
                callback?.Invoke(new DialogResult {
                    Exception = ex
                });
            }
        }