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); } } } }
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(); }
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); }
/// <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); }
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); }
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); }); }
/// <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); }
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; }