Example #1
0
        public void PresentShouldInvokeCallbackOnClear()
        {
            var vm = GetViewModel <NavigableViewModelMock>();
            IOperationCallback operationCallback = null;

            ApplicationSettings.Platform      = new PlatformInfo(PlatformType.WPF, new Version(0, 0));
            OperationCallbackManager.Register = (type, o, arg3, arg4) =>
            {
                type.ShouldEqual(OperationType.TabNavigation);
                operationCallback = arg3;
            };
            OperationCallbackManager.SetResult = (o, result) =>
            {
                result.Operation.ShouldEqual(OperationType.TabNavigation);
                o.ShouldEqual(vm);
                operationCallback.Invoke(result);
            };

            vm.OperationResult = true;
            MultiViewModel             viewModel = GetMultiViewModel();
            IDynamicViewModelPresenter presenter = new DynamicMultiViewModelPresenter(viewModel,
                                                                                      OperationCallbackManager);
            IAsyncOperation <bool?> task = presenter.TryShowAsync(vm, DataContext.Empty, null);

            task.ShouldNotBeNull();
            task.IsCompleted.ShouldBeFalse();
            viewModel.Clear();
            task.IsCompleted.ShouldBeTrue();
            task.Result.Result.ShouldEqual(true);
            operationCallback.ShouldNotBeNull();
        }
        protected virtual void NavigationServiceOnNavigated(object sender, NavigationEventArgsBase e)
        {
            string idOperation = null;

            try
            {
                var context = CreateContextNavigateTo(CurrentViewModel, e);
                idOperation = context.GetData(OperationIdConstant);
                IOperationCallback callback = null;
                if (idOperation == _currentOperationId)
                {
                    callback            = _currentCallback;
                    _currentCallback    = null;
                    _navigationTargetVm = null;
                    _lastContext        = null;
                }
                UpdateNavigationContext(callback, context.ViewModelTo, e, ref context);
                OnNavigated(context);
            }
            finally
            {
                if (idOperation == _currentOperationId)
                {
                    _currentOperationId = null;
                    var tcs = _navigatedTcs;
                    if (tcs != null)
                    {
                        _navigatedTcs = null;
                        tcs.TrySetResult(null);
                    }
                }
            }
        }
Example #3
0
        public void PresentShouldInvokeCallbackOnRemove()
        {
            var vm = GetViewModel <NavigableViewModelMock>();
            IOperationCallback operationCallback = null;

            OperationCallbackManager.Register = (type, o, arg3, arg4) =>
            {
                type.ShouldEqual(OperationType.TabNavigation);
                operationCallback = arg3;
            };
            OperationCallbackManager.SetResult = (o, result) =>
            {
                result.Operation.ShouldEqual(OperationType.TabNavigation);
                o.ShouldEqual(vm);
                operationCallback.Invoke(result);
            };

            vm.OperationResult = true;
            MultiViewModel             viewModel = GetMultiViewModel();
            IDynamicViewModelPresenter presenter = new DynamicMultiViewModelPresenter(viewModel,
                                                                                      OperationCallbackManager, (model, context, arg3) => true);
            IAsyncOperation <bool?> task = presenter.TryShowAsync(vm, DataContext.Empty, null);

            task.ShouldNotBeNull();
            task.IsCompleted.ShouldBeFalse();
            viewModel.RemoveViewModelAsync(vm).Result.ShouldBeTrue();
            task.IsCompleted.ShouldBeTrue();
            task.Result.Result.ShouldEqual(true);
            operationCallback.ShouldNotBeNull();
        }
Example #4
0
        protected virtual void RegisterInternal(OperationType operation, [NotNull] object target,
                                                [NotNull] IOperationCallback callback, [NotNull] IDataContext context)
        {
            CallbackDictionary callbacks;
            var viewModel = target as IViewModel;

            if (viewModel != null && callback.IsSerializable)
            {
                lock (_locker)
                {
                    if (!viewModel.Settings.State.TryGetData(CallbackConstant, out callbacks))
                    {
                        callbacks = new CallbackDictionary();
                        viewModel.Settings.State.Add(CallbackConstant, callbacks);
                    }
                }
            }
            else
            {
                callbacks = ServiceProvider
                            .AttachedValueProvider
                            .GetOrAdd(target, CallbacksMember, (o, o1) => new CallbackDictionary(), null);
            }
            RegisterInternal(callbacks, operation.Id, callback);
        }
 void IOperationCallbackManager.Register(OperationType operation, object source, IOperationCallback callback,
     IDataContext context)
 {
     if (Register == null)
         Tracer.Warn("OperationCallbackManagerMock: Register == null");
     else
         Register(operation, source, callback, context);
 }
        private void CancelCurrentNavigation(INavigationContext context)
        {
            var callback = _currentCallback;

            if (callback != null)
            {
                callback.Invoke(OperationResult.CreateCancelResult <bool?>(OperationType.Navigation, this, context));
                _currentCallback    = null;
                _navigationTargetVm = null;
            }
        }
        private void OnNavigating(NavigatingCancelEventArgsBase args)
        {
            if (_ignoreNavigating)
            {
                return;
            }
            var currentViewModel = CurrentViewModel;

            if (currentViewModel == null)
            {
                return;
            }
            _ignoreCloseFromViewModel = true;
            args.Cancel = true;
            var context      = CreateContextNavigateFrom(currentViewModel, _navigationTargetVm, args);
            var navigateTask = (_closedFromViewModel || !args.IsCancelable)
                ? Empty.TrueTask
                : OnNavigatingFrom(currentViewModel, context);
            var t = navigateTask.TryExecuteSynchronously(task =>
            {
                if (task.IsCanceled || !task.Result)
                {
                    CancelCurrentNavigation(context);
                    return;
                }
                if (task.IsFaulted)
                {
                    var callback = _currentCallback;
                    if (callback != null)
                    {
                        callback.Invoke(OperationResult.CreateErrorResult <bool?>(OperationType.Navigation,
                                                                                  currentViewModel, task.Exception, context));
                        _currentCallback = null;
                    }
                    return;
                }
                ThreadManager.InvokeOnUiThreadAsync(() =>
                {
                    try
                    {
                        _ignoreNavigating = true;
                        Renavigate(currentViewModel, context, args);
                    }
                    finally
                    {
                        _ignoreNavigating = false;
                    }
                });
            });

            t.TryExecuteSynchronously(task => _ignoreCloseFromViewModel = false);
            t.WithTaskExceptionHandler(this);
        }
Example #8
0
 /// <summary>
 ///     Registers the specified operation callback.
 /// </summary>
 public void Register(OperationType operation, object source, IOperationCallback callback, IDataContext context)
 {
     Should.NotBeNull(operation, "operation");
     Should.NotBeNull(source, "source");
     Should.NotBeNull(callback, "callback");
     if (context == null)
     {
         context = DataContext.Empty;
     }
     RegisterInternal(operation, source, callback, context);
     Tracer.Info("Callback '{0}' was registered, source: '{1}'", operation, source);
 }
Example #9
0
 public void Register(OperationType operation, object target, IOperationCallback callback, IDataContext context)
 {
     Should.NotBeNull(operation, nameof(operation));
     Should.NotBeNull(target, nameof(target));
     Should.NotBeNull(callback, nameof(callback));
     if (context == null)
     {
         context = DataContext.Empty;
     }
     RegisterInternal(operation, target, callback, context);
     if (Tracer.TraceInformation)
     {
         Tracer.Info("Callback '{0}' was registered, target: '{1}'", operation, target);
     }
 }
        public Task NavigateAsync(IOperationCallback callback, IDataContext context)
        {
            Should.NotBeNull(context, nameof(context));
            IViewModel viewModel = context.GetData(NavigationConstants.ViewModel);

            if (viewModel == null)
            {
                throw new InvalidOperationException($"The '{GetType()}' provider doesn't support the DataContext without navigation target.");
            }
            context = context.ToNonReadOnly();
            if (ReferenceEquals(viewModel, CurrentViewModel))
            {
                if (callback != null)
                {
                    CallbackManager.Register(OperationType.PageNavigation, viewModel, callback, context);
                }
                return(Empty.Task);
            }
            //The view model is already shown as page and we need to bring it to front
            if (viewModel.Settings.State.Contains(IsNavigatedConstant))
            {
                context.AddOrUpdate(NavigationProviderConstants.BringToFront, true);
            }

            string viewName    = viewModel.GetViewName(context);
            var    vmType      = viewModel.GetType();
            var    mappingItem = ViewMappingProvider.FindMappingForViewModel(vmType, viewName, true);
            var    id          = Guid.NewGuid().ToString("n");
            var    parameter   = GenerateNavigationParameter(vmType, id);

            var tcs = new TaskCompletionSource <object>();

            CurrentNavigationTask.TryExecuteSynchronously(_ =>
                                                          ThreadManager.InvokeOnUiThreadAsync(() =>
            {
                _navigatedTcs       = tcs;
                _navigationTargetVm = viewModel;
                _currentCallback    = callback;
                _lastContext        = context;
                _currentOperationId = id;
                if (_navigationService.Navigate(mappingItem, parameter, context))
                {
                    ClearCacheIfNeed(context, viewModel);
                }
            }));
            return(tcs.Task);
        }
Example #11
0
        public Task ShowAsync(IOperationCallback callback, IDataContext context)
        {
            ViewModel.NotBeDisposed();
            if (IsOpen)
            {
                throw ExceptionManager.WindowOpened();
            }
            var tcs = new TaskCompletionSource <object>();

            RaiseNavigating(context, NavigationMode.New)
            .TryExecuteSynchronously(task =>
            {
                try
                {
                    if (!task.Result)
                    {
                        tcs.TrySetCanceled();
                        if (callback != null)
                        {
                            callback.Invoke(OperationResult.CreateCancelResult <bool?>(OperationType.WindowNavigation, ViewModel, context));
                        }
                        return;
                    }
                    if (context == null)
                    {
                        context = DataContext.Empty;
                    }
                    if (callback != null)
                    {
                        OperationCallbackManager.Register(OperationType.WindowNavigation, ViewModel, callback, context);
                    }
                    _isOpen = true;
                    ShowInternal(context, tcs);
                }
                catch (Exception e)
                {
                    tcs.TrySetException(e);
                    if (callback != null)
                    {
                        callback.Invoke(OperationResult.CreateErrorResult <bool?>(OperationType.WindowNavigation, ViewModel, e, context));
                    }
                }
            });
            return(tcs.Task);
        }
        private void CancelCurrentNavigation(INavigationContext context)
        {
            var callback = _currentCallback;

            if (callback != null)
            {
                callback.Invoke(OperationResult.CreateCancelResult <bool?>(OperationType.PageNavigation, context.ViewModelTo ?? (object)this, context));
                _currentCallback    = null;
                _navigationTargetVm = null;
            }
            var tcs = _navigatedTcs;

            if (tcs != null)
            {
                _navigatedTcs = null;
                tcs.TrySetCanceled();
            }
        }
        /// <summary>
        ///     Navigates using the specified data context.
        /// </summary>
        /// <param name="callback">The specified callback, if any.</param>
        /// <param name="context">
        ///     The specified <see cref="IDataContext" />.
        /// </param>
        public void Navigate(IOperationCallback callback, IDataContext context)
        {
            Should.NotBeNull(context, "context");
            IViewModel viewModel = context.GetData(NavigationConstants.ViewModel);

            if (viewModel == null)
            {
                throw new InvalidOperationException(string.Format("The '{0}' provider doesn't support the DataContext without navigation target.", GetType()));
            }
            if (ReferenceEquals(viewModel, CurrentViewModel))
            {
                if (callback != null)
                {
                    callback.Invoke(OperationResult.CreateResult <bool?>(OperationType.Navigation, CurrentViewModel, true, context));
                }
                return;
            }

            string viewName   = viewModel.GetViewName(context);
            var    parameters = context.GetData(NavigationConstants.Parameters);

            var    vmType      = viewModel.GetType();
            var    mappingItem = FindMappingForViewModel(vmType, viewName);
            object parameter;

            if (parameters != null)
            {
                parameters = parameters.ToNonReadOnly();
                parameters.Add(VmTypeConstant, vmType.AssemblyQualifiedName);
                parameter = parameters;
            }
            else
            {
                parameter = vmType.AssemblyQualifiedName;
            }

            ThreadManager.InvokeOnUiThreadAsync(() =>
            {
                CancelCurrentNavigation(null);
                _navigationTargetVm = viewModel;
                _currentCallback    = callback;
                _navigationService.Navigate(mappingItem, parameter, context);
            });
        }
Example #14
0
 /// <summary>
 ///     Shows the specified <see cref="IViewModel" />.
 /// </summary>
 /// <param name="callback">The specified callback, if any.</param>
 /// <param name="context">The specified context.</param>
 public void Show(IOperationCallback callback, IDataContext context)
 {
     ViewModel.NotBeDisposed();
     if (IsOpen)
     {
         throw ExceptionManager.WindowOpened();
     }
     _isOpen = true;
     if (context == null)
     {
         context = DataContext.Empty;
     }
     if (callback != null)
     {
         OperationCallbackManager.Register(OperationType.WindowNavigation, ViewModel, callback, context);
     }
     OnShow(context);
     ShowInternal(context);
 }
        private void UpdateNavigationContext(IOperationCallback callback, IViewModel navigationViewModel, NavigationEventArgsBase args, ref INavigationContext context)
        {
            var vmType = context.GetData(ViewModelTypeConstant);

            if (vmType == null)
            {
                return;
            }

            var viewModel = GetViewModelForView(args, navigationViewModel, context, vmType);

            if (!ReferenceEquals(context.ViewModelTo, viewModel))
            {
                context = new NavigationContext(NavigationType.Page, context.NavigationMode, context.ViewModelFrom, viewModel, context.NavigationProvider);
            }
            if (viewModel != null && callback != null)
            {
                RegisterOperationCallback(viewModel, callback, context);
            }
        }
        public Task NavigateAsync(IOperationCallback callback, IDataContext context)
        {
            Should.NotBeNull(context, "context");
            IViewModel viewModel = context.GetData(NavigationConstants.ViewModel);

            if (viewModel == null)
            {
                throw new InvalidOperationException(string.Format("The '{0}' provider doesn't support the DataContext without navigation target.", GetType()));
            }
            if (ReferenceEquals(viewModel, CurrentViewModel))
            {
                if (callback != null)
                {
                    callback.Invoke(OperationResult.CreateResult <bool?>(OperationType.PageNavigation, CurrentViewModel, true, context));
                }
                return(Empty.Task);
            }

            string viewName    = viewModel.GetViewName(context);
            var    vmType      = viewModel.GetType();
            var    mappingItem = FindMappingForViewModel(vmType, viewName);
            var    id          = Guid.NewGuid().ToString("n");
            var    parameter   = GenerateNavigationParameter(vmType, id);

            var tcs = new TaskCompletionSource <object>();

            CurrentNavigationTask.TryExecuteSynchronously(_ =>
                                                          ThreadManager.InvokeOnUiThreadAsync(() =>
            {
                _navigatedTcs       = tcs;
                _navigationTargetVm = viewModel;
                _currentCallback    = callback;
                _lastContext        = context;
                _currentOperationId = id;
                if (_navigationService.Navigate(mappingItem, parameter, context))
                {
                    ClearCacheIfNeed(context, viewModel);
                }
            }));
            return(tcs.Task);
        }
Example #17
0
        private void RegisterInternal(CallbackDictionary callbacks, string id, IOperationCallback callback)
        {
            //Only for debug callback
            if (AlwaysSerializeCallback && callback.IsSerializable)
            {
                var stream = _serializer.Serialize(callback);
                stream.Position = 0;
                callback        = (IOperationCallback)_serializer.Deserialize(stream);
            }

            lock (callbacks)
            {
                List <object> list;
                if (!callbacks.TryGetValue(id, out list))
                {
                    list          = new List <object>();
                    callbacks[id] = list;
                }
                list.Add(callback);
            }
        }
 protected void RegisterOperationCallback([NotNull] IViewModel viewModel, [NotNull] IOperationCallback callback, [NotNull] INavigationContext context)
 {
     CallbackManager.Register(OperationType.PageNavigation, viewModel, callback, context);
 }
 private void CancelCurrentNavigation(INavigationContext context)
 {
     var callback = _currentCallback;
     if (callback != null)
     {
         callback.Invoke(OperationResult.CreateCancelResult<bool?>(OperationType.PageNavigation, this, context));
         _currentCallback = null;
         _navigationTargetVm = null;
     }
     var tcs = _navigatedTcs;
     if (tcs != null)
     {
         _navigatedTcs = null;
         tcs.TrySetCanceled();
     }
 }
        private void UpdateNavigationContext(IOperationCallback callback, IViewModel navigationViewModel, NavigationEventArgsBase args, ref INavigationContext context)
        {
            var vmType = context.GetData(ViewModelTypeConstant);
            if (vmType == null)
                return;

            var viewModel = GetViewModelForView(args, navigationViewModel, context, vmType);
            if (!ReferenceEquals(context.ViewModelTo, viewModel))
                context = new NavigationContext(NavigationType.Page, context.NavigationMode, context.ViewModelFrom, viewModel, context.NavigationProvider);
            if (viewModel != null && callback != null)
                RegisterOperationCallback(viewModel, callback, context);
        }
 private void OnNavigating(NavigatingCancelEventArgsBase args)
 {
     if (_ignoreNavigating)
         return;
     var currentViewModel = CurrentViewModel;
     if (currentViewModel == null)
         return;
     try
     {
         _closingViewModel = currentViewModel;
         args.Cancel = true;
         var context = CreateContextNavigateFrom(currentViewModel, args);
         var navigateTask = (_closedFromViewModel || !args.IsCancelable)
             ? Empty.TrueTask
             : OnNavigatingFrom(currentViewModel, context);
         var t = navigateTask.TryExecuteSynchronously(task =>
         {
             if (!task.IsCanceled && task.IsFaulted)
             {
                 _closingViewModel = null;
                 var callback = _currentCallback;
                 if (callback != null)
                 {
                     callback.Invoke(OperationResult.CreateErrorResult<bool?>(OperationType.PageNavigation,
                         currentViewModel, task.Exception, context));
                     _currentCallback = null;
                 }
                 return;
             }
             if (task.IsCanceled || !task.Result)
             {
                 _closingViewModel = null;
                 CancelCurrentNavigation(context);
                 return;
             }
             ThreadManager.InvokeOnUiThreadAsync(() =>
             {
                 try
                 {
                     _ignoreNavigating = true;
                     Renavigate(currentViewModel, context, args);
                 }
                 finally
                 {
                     _closingViewModel = null;
                     _ignoreNavigating = false;
                 }
             });
         });
         t.WithTaskExceptionHandler(this);
     }
     catch (Exception)
     {
         _closingViewModel = null;
         throw;
     }
 }
        private void OnNavigated(INavigationContext context)
        {
            var vmFrom = context.ViewModelFrom;
            var vmTo   = context.ViewModelTo;
            var mode   = context.NavigationMode;

            //only this mode allows to renavigate.
            if (ReferenceEquals(vmFrom, vmTo) && mode != NavigationMode.Refresh && mode != NavigationMode.Reset && mode != NavigationMode.Undefined)
            {
                Tracer.Warn("Possible bug in navigation, navigate to the same view model with mode " + mode);
                return;
            }
            try
            {
                CurrentViewModel = vmTo;
                if (vmFrom != null)
                {
                    var navigableViewModel = vmFrom as INavigableViewModel;
                    if (navigableViewModel != null)
                    {
                        navigableViewModel.OnNavigatedFrom(context);
                    }
                }

                var closeableViewModel = vmFrom as ICloseableViewModel;
                if (closeableViewModel != null)
                {
                    closeableViewModel.Closed -= _closeViewModelHandler;
                    var wrapper = closeableViewModel.CloseCommand as CloseCommandWrapper;
                    if (wrapper != null)
                    {
                        closeableViewModel.CloseCommand = wrapper.NestedCommand;
                    }
                }

                closeableViewModel = vmTo as ICloseableViewModel;
                if (closeableViewModel != null && !(closeableViewModel.CloseCommand is CloseCommandWrapper))
                {
                    closeableViewModel.Closed      += _closeViewModelHandler;
                    closeableViewModel.CloseCommand = new CloseCommandWrapper(closeableViewModel.CloseCommand, this);
                }

                if (vmTo != null)
                {
                    OnNavigatedTo(vmTo, context);
                    RaiseNavigated(context, vmTo);
                }
                if (vmFrom != null)
                {
                    TryCompleteOperationCallback(vmFrom, context);
                }

                Tracer.Info("Navigated from '{0}' to '{1}', navigation mode '{2}'", vmFrom, vmTo, mode);
            }
            catch (Exception ex)
            {
                Tracer.Error(ex.Flatten(true));
                throw;
            }
            finally
            {
                _currentCallback    = null;
                _navigationTargetVm = null;
            }
        }
 void IOperationCallbackManager.Register(OperationType operation, object source, IOperationCallback callback,
                                         IDataContext context)
 {
     if (Register == null)
     {
         Tracer.Warn("OperationCallbackManagerMock: Register == null");
     }
     else
     {
         Register(operation, source, callback, context);
     }
 }
        /// <summary>
        ///     Navigates using the specified data context.
        /// </summary>
        /// <param name="callback">The specified callback, if any.</param>
        /// <param name="context">
        ///     The specified <see cref="IDataContext" />.
        /// </param>
        public Task NavigateAsync(IOperationCallback callback, IDataContext context)
        {
            Should.NotBeNull(context, "context");
            IViewModel viewModel = context.GetData(NavigationConstants.ViewModel);
            if (viewModel == null)
                throw new InvalidOperationException(string.Format("The '{0}' provider doesn't support the DataContext without navigation target.", GetType()));
            if (ReferenceEquals(viewModel, CurrentViewModel))
            {
                if (callback != null)
                    callback.Invoke(OperationResult.CreateResult<bool?>(OperationType.PageNavigation, CurrentViewModel, true, context));
                return Empty.Task;
            }

            string viewName = viewModel.GetViewName(context);
            var vmType = viewModel.GetType();
            var mappingItem = FindMappingForViewModel(vmType, viewName);
            var id = Guid.NewGuid().ToString("n");
            var parameter = vmType.AssemblyQualifiedName + IdSeparator[0] + id;

            var tcs = new TaskCompletionSource<object>();
            CurrentNavigationTask.TryExecuteSynchronously(_ =>
                ThreadManager.InvokeOnUiThreadAsync(() =>
                {
                    _navigatedTcs = tcs;
                    _navigationTargetVm = viewModel;
                    _currentCallback = callback;
                    _lastContext = context;
                    _currentOperationId = id;
                    if (_navigationService.Navigate(mappingItem, parameter, context))
                        ClearCacheIfNeed(context, viewModel);
                }));
            return tcs.Task;
        }
 /// <summary>
 ///     Subscriber to the Navigated event.
 /// </summary>
 protected virtual void NavigationServiceOnNavigated(object sender, NavigationEventArgsBase e)
 {
     string idOperation = null;
     try
     {
         var context = CreateContextNavigateTo(CurrentViewModel, e);
         idOperation = context.GetData(OperationIdConstant);
         IOperationCallback callback = null;
         if (idOperation == _currentOperationId)
         {
             callback = _currentCallback;
             _currentCallback = null;
             _navigationTargetVm = null;
             _lastContext = null;
         }
         UpdateNavigationContext(callback, context.ViewModelTo, e, ref context);
         OnNavigated(context);
     }
     finally
     {
         if (idOperation == _currentOperationId)
         {
             _currentOperationId = null;
             var tcs = _navigatedTcs;
             if (tcs != null)
             {
                 _navigatedTcs = null;
                 tcs.TrySetResult(null);
             }
         }
     }
 }
        public Task NavigateAsync(IOperationCallback callback, IDataContext context)
        {
            Should.NotBeNull(context, nameof(context));
            IViewModel viewModel = context.GetData(NavigationConstants.ViewModel);
            if (viewModel == null)
                throw new InvalidOperationException($"The '{GetType()}' provider doesn't support the DataContext without navigation target.");
            context = context.ToNonReadOnly();
            if (ReferenceEquals(viewModel, CurrentViewModel))
            {
                if (callback != null)
                    CallbackManager.Register(OperationType.PageNavigation, viewModel, callback, context);
                return Empty.Task;
            }
            //The view model is already shown as page and we need to bring it to front
            if (viewModel.Settings.State.Contains(IsNavigatedConstant))
                context.AddOrUpdate(NavigationProviderConstants.BringToFront, true);

            string viewName = viewModel.GetViewName(context);
            var vmType = viewModel.GetType();
            var mappingItem = ViewMappingProvider.FindMappingForViewModel(vmType, viewName, true);
            var id = Guid.NewGuid().ToString("n");
            var parameter = GenerateNavigationParameter(vmType, id);

            var tcs = new TaskCompletionSource<object>();
            CurrentNavigationTask.TryExecuteSynchronously(_ =>
                ThreadManager.InvokeOnUiThreadAsync(() =>
                {
                    _navigatedTcs = tcs;
                    _navigationTargetVm = viewModel;
                    _currentCallback = callback;
                    _lastContext = context;
                    _currentOperationId = id;
                    if (_navigationService.Navigate(mappingItem, parameter, context))
                        ClearCacheIfNeed(context, viewModel);
                }));
            return tcs.Task;
        }