public bool TryClose(IDataContext dataContext)
        {
            Should.NotBeNull(dataContext, nameof(dataContext));
            var viewModel = dataContext.GetData(NavigationConstants.ViewModel);

            if (viewModel == null)
            {
                return(false);
            }
            if (CurrentContent?.DataContext() == viewModel)
            {
                return(GoBack(dataContext));
            }

            if (!CanClose(dataContext))
            {
                return(false);
            }
            if (RaiseNavigating(new NavigatingCancelEventArgs(NavigationMode.Remove, dataContext)))
            {
                var message = new MvvmActivityMediator.FinishActivityMessage(viewModel);
                EventAggregator.Publish(this, message);
                if (message.IsFinished)
                {
                    RaiseNavigated(viewModel, NavigationMode.Remove, null, dataContext);
                }
                return(message.IsFinished);
            }
            return(true);
        }
        public virtual bool TryClose(IViewModel viewModel, IDataContext dataContext)
        {
            Should.NotBeNull(viewModel, nameof(viewModel));
            if (CurrentContent != null && CurrentContent.DataContext() == viewModel)
            {
                GoBack();
                //Ignore close just in case there backstack fragments.
                return(false);
            }
            var message = new MvvmActivityMediator.FinishActivityMessage(viewModel);

            ServiceProvider.EventAggregator.Publish(this, message);
            return(message.Finished);
        }
        private void ClearBackStack(Intent intent, IViewModel viewModel, bool bringToFront, IDataContext dataContext)
        {
            if (intent != null)
            {
                if (AndroidToolkitExtensions.IsApiLessThanOrEqualTo10)
                {
                    intent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop);
                }
                else
                {
                    intent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);
                }
            }
            var message = new MvvmActivityMediator.FinishActivityMessage();

            if (bringToFront)
            {
                if (viewModel != null)
                {
                    message.IgnoredViewModels = new[] { viewModel }
                }
                ;
            }
            EventAggregator.Publish(this, message);
            if (message.FinishedViewModels != null)
            {
                message.FinishedViewModels.Reverse();
                foreach (var vm in message.FinishedViewModels)
                {
                    var ctx = new DataContext(dataContext);
                    ctx.AddOrUpdate(NavigationConstants.ViewModel, vm);
                    RaiseNavigated(vm, NavigationMode.Remove, null, ctx);
                }
            }
        }

        #endregion

        #region Implementation of INavigationService

        object INavigationService.CurrentContent => AndroidToolkitExtensions.CurrentActivity;
 public virtual bool TryClose(IViewModel viewModel, IDataContext dataContext)
 {
     Should.NotBeNull(viewModel, "viewModel");
     if (CurrentContent != null && CurrentContent.DataContext() == viewModel)
     {
         GoBack();
         //Ignore close just in case there backstack fragments.
         return false;
     }
     var message = new MvvmActivityMediator.FinishActivityMessage(viewModel);
     ServiceProvider.EventAggregator.Publish(this, message);
     return message.Finished;
 }
        public virtual bool Navigate(IViewMappingItem source, string parameter, IDataContext dataContext)
        {
            Should.NotBeNull(source, nameof(source));
            if (dataContext == null)
                dataContext = DataContext.Empty;
            bool bringToFront;
            dataContext.TryGetData(NavigationProviderConstants.BringToFront, out bringToFront);
            if (!RaiseNavigating(new NavigatingCancelEventArgs(source, bringToFront ? NavigationMode.Refresh : NavigationMode.New, parameter)))
                return false;
            var activity = PlatformExtensions.CurrentActivity ?? SplashScreenActivityBase.Current;
            var context = activity ?? Application.Context;

            var intent = new Intent(context, source.ViewType);
            if (activity == null)
                intent.AddFlags(ActivityFlags.NewTask);
            else if (dataContext.GetData(NavigationConstants.ClearBackStack))
            {
                if (PlatformExtensions.IsApiLessThanOrEqualTo10)
                    intent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop);
                else
                    intent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);
                ServiceProvider.EventAggregator.Publish(this, MvvmActivityMediator.FinishActivityMessage.Instance);
                dataContext.AddOrUpdate(NavigationProviderConstants.InvalidateAllCache, true);
            }
            if (parameter != null)
                intent.PutExtra(ParameterString, parameter);

            if (bringToFront)
            {
                _isReorder = true;
                //http://stackoverflow.com/questions/20695522/puzzling-behavior-with-reorder-to-front
                //http://code.google.com/p/android/issues/detail?id=63570#c2
                bool closed = false;
                if (PlatformExtensions.IsApiGreaterThanOrEqualTo19)
                {
                    var viewModel = dataContext.GetData(NavigationConstants.ViewModel);
                    if (viewModel != null)
                    {
                        var view = viewModel.Settings.Metadata.GetData(ViewModelConstants.View);
                        var activityView = ToolkitExtensions.GetUnderlyingView<object>(view) as Activity;
                        if (activityView != null && activityView.IsTaskRoot)
                        {
                            var message = new MvvmActivityMediator.FinishActivityMessage(viewModel);
                            ServiceProvider.EventAggregator.Publish(this, message);
                            closed = message.Finished;
                        }
                    }
                }
                if (!closed)
                    intent.AddFlags(ActivityFlags.ReorderToFront);
                dataContext.AddOrUpdate(NavigationProviderConstants.InvalidateCache, true);
            }
            _isNew = true;
            _parameter = parameter;
            StartActivity(context, intent, source, dataContext);
            return true;
        }
        public bool Navigate(IViewMappingItem source, string parameter, IDataContext dataContext)
        {
            Should.NotBeNull(source, nameof(source));
            Should.NotBeNull(dataContext, nameof(dataContext));

            bool clearBackStack = dataContext.GetData(NavigationConstants.ClearBackStack);
            var  viewModel      = dataContext.GetData(NavigationConstants.ViewModel);
            var  currentView    = viewModel?.GetCurrentView <object>();

            if (currentView != null && ReferenceEquals(currentView, CurrentContent))
            {
                if (clearBackStack)
                {
                    ClearBackStack(null, viewModel, true, dataContext);
                }
                RaiseNavigated(currentView, NavigationMode.Refresh, parameter, dataContext);
                return(true);
            }

            bool bringToFront;

            dataContext.TryGetData(NavigationProvider.BringToFront, out bringToFront);
            if (!RaiseNavigating(new NavigatingCancelEventArgs(source, bringToFront ? NavigationMode.Refresh : NavigationMode.New, parameter, dataContext)))
            {
                return(false);
            }

            _newContext = dataContext;
            var activity = AndroidToolkitExtensions.CurrentActivity;
            var context  = activity ?? Application.Context;

            var intent = new Intent(context, source.ViewType);

            if (activity == null)
            {
                intent.AddFlags(ActivityFlags.NewTask);
            }
            else if (clearBackStack)
            {
                ClearBackStack(intent, viewModel, bringToFront, dataContext);
            }

            if (parameter != null)
            {
                intent.PutExtra(IntentParameterKey, parameter);
            }

            if (bringToFront)
            {
                if (viewModel != null)
                {
                    intent.PutExtra(MvvmActivityMediator.IntentViewModelIdKey, viewModel.GetViewModelId().ToString("N"));
                }
                //http://stackoverflow.com/questions/20695522/puzzling-behavior-with-reorder-to-front
                //http://code.google.com/p/android/issues/detail?id=63570#c2
                bool closed = false;
                if (!clearBackStack && AndroidToolkitExtensions.IsApiGreaterThanOrEqualTo19)
                {
                    var activityView = viewModel?.GetCurrentView <object>() as Activity;
                    if (activityView != null && activityView.IsTaskRoot)
                    {
                        var message = new MvvmActivityMediator.FinishActivityMessage(viewModel);
                        EventAggregator.Publish(this, message);
                        closed = message.IsFinished;
                    }
                }
                if (!closed)
                {
                    intent.AddFlags(ActivityFlags.ReorderToFront);
                }
                viewModel?.Settings.Metadata.AddOrUpdate(NavigationProvider.BringToFront, true);
            }
            StartActivity(context, intent, source, dataContext);
            return(true);
        }
        public bool Navigate(IViewMappingItem source, string parameter, IDataContext dataContext)
        {
            Should.NotBeNull(source, nameof(source));
            Should.NotBeNull(dataContext, nameof(dataContext));
            bool bringToFront;

            dataContext.TryGetData(NavigationProvider.BringToFront, out bringToFront);
            if (!RaiseNavigating(new NavigatingCancelEventArgs(source, bringToFront ? NavigationMode.Refresh : NavigationMode.New, parameter, dataContext)))
            {
                return(false);
            }

            _newContext = dataContext;
            bool clearBackStack = dataContext.GetData(NavigationConstants.ClearBackStack);
            var  activity       = AndroidToolkitExtensions.CurrentActivity;
            var  context        = activity ?? Application.Context;

            var intent = new Intent(context, source.ViewType);

            if (activity == null)
            {
                intent.AddFlags(ActivityFlags.NewTask);
            }
            else if (clearBackStack)
            {
                if (AndroidToolkitExtensions.IsApiLessThanOrEqualTo10)
                {
                    intent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop);
                }
                else
                {
                    intent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);
                }
                var message = new MvvmActivityMediator.FinishActivityMessage();
                if (bringToFront)
                {
                    var viewModel = dataContext.GetData(NavigationConstants.ViewModel);
                    if (viewModel != null)
                    {
                        message.IgnoredViewModels = new[] { viewModel }
                    }
                    ;
                }
                ServiceProvider.EventAggregator.Publish(this, message);
                if (message.FinishedViewModels != null)
                {
                    message.FinishedViewModels.Reverse();
                    foreach (var vm in message.FinishedViewModels)
                    {
                        var ctx = new DataContext(dataContext);
                        ctx.AddOrUpdate(NavigationConstants.ViewModel, vm);
                        RaiseNavigated(vm, NavigationMode.Remove, null, ctx);
                    }
                }
            }

            if (parameter != null)
            {
                intent.PutExtra(ParameterId, parameter);
            }

            if (bringToFront)
            {
                //http://stackoverflow.com/questions/20695522/puzzling-behavior-with-reorder-to-front
                //http://code.google.com/p/android/issues/detail?id=63570#c2
                bool closed = false;
                if (!clearBackStack && AndroidToolkitExtensions.IsApiGreaterThanOrEqualTo19)
                {
                    var viewModel    = dataContext.GetData(NavigationConstants.ViewModel);
                    var activityView = viewModel?.GetCurrentView <object>() as Activity;
                    if (activityView != null && activityView.IsTaskRoot)
                    {
                        var message = new MvvmActivityMediator.FinishActivityMessage(viewModel);
                        ServiceProvider.EventAggregator.Publish(this, message);
                        closed = message.IsFinished;
                    }
                }
                if (!closed)
                {
                    intent.AddFlags(ActivityFlags.ReorderToFront);
                }
            }
            StartActivity(context, intent, source, dataContext);
            return(true);
        }
        public virtual bool Navigate(IViewMappingItem source, string parameter, IDataContext dataContext)
        {
            Should.NotBeNull(source, nameof(source));
            if (dataContext == null)
            {
                dataContext = DataContext.Empty;
            }
            bool bringToFront;

            dataContext.TryGetData(NavigationProviderConstants.BringToFront, out bringToFront);
            if (!RaiseNavigating(new NavigatingCancelEventArgs(source, bringToFront ? NavigationMode.Refresh : NavigationMode.New, parameter)))
            {
                return(false);
            }
            var activity = PlatformExtensions.CurrentActivity ?? SplashScreenActivityBase.Current;
            var context  = activity ?? Application.Context;

            var intent = new Intent(context, source.ViewType);

            if (activity == null)
            {
                intent.AddFlags(ActivityFlags.NewTask);
            }
            else if (dataContext.GetData(NavigationConstants.ClearBackStack))
            {
                if (PlatformExtensions.IsApiLessThanOrEqualTo10)
                {
                    intent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTop);
                }
                else
                {
                    intent.AddFlags(ActivityFlags.NewTask | ActivityFlags.ClearTask);
                }
                ServiceProvider.EventAggregator.Publish(this, MvvmActivityMediator.FinishActivityMessage.Instance);
                dataContext.AddOrUpdate(NavigationProviderConstants.InvalidateAllCache, true);
            }
            if (parameter != null)
            {
                intent.PutExtra(ParameterString, parameter);
            }

            if (bringToFront)
            {
                _isReorder = true;
                //http://stackoverflow.com/questions/20695522/puzzling-behavior-with-reorder-to-front
                //http://code.google.com/p/android/issues/detail?id=63570#c2
                bool closed = false;
                if (PlatformExtensions.IsApiGreaterThanOrEqualTo19)
                {
                    var viewModel = dataContext.GetData(NavigationConstants.ViewModel);
                    if (viewModel != null)
                    {
                        var view         = viewModel.Settings.Metadata.GetData(ViewModelConstants.View);
                        var activityView = ToolkitExtensions.GetUnderlyingView <object>(view) as Activity;
                        if (activityView != null && activityView.IsTaskRoot)
                        {
                            var message = new MvvmActivityMediator.FinishActivityMessage(viewModel);
                            ServiceProvider.EventAggregator.Publish(this, message);
                            closed = message.Finished;
                        }
                    }
                }
                if (!closed)
                {
                    intent.AddFlags(ActivityFlags.ReorderToFront);
                }
                dataContext.AddOrUpdate(NavigationProviderConstants.InvalidateCache, true);
            }
            _isNew     = true;
            _parameter = parameter;
            StartActivity(context, intent, source, dataContext);
            return(true);
        }