diff options
Diffstat (limited to 'Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation')
| -rw-r--r-- | Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs | 382 |
1 files changed, 109 insertions, 273 deletions
diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs index d247ab23c..fe3cabcc1 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Navigation/DefaultNavigationManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; @@ -13,7 +12,6 @@ using Tango.Core.Commands; using Tango.PPC.Common; using Tango.PPC.Common.Modules; using Tango.PPC.Common.Navigation; -using Tango.PPC.Common.Notifications; using Tango.PPC.Common.Threading; using Tango.PPC.UI.Views; using Tango.SharedUI.Controls; @@ -26,49 +24,23 @@ namespace Tango.PPC.UI.Navigation /// <seealso cref="Tango.PPC.Common.Navigation.INavigationManager" /> public class DefaultNavigationManager : ExtendedObject, INavigationManager { - //private event Action<Object, Object> NavigationCycleCompleted; - //private event Action<Object, Object> BeforeNavigationCycleCompleted; - private class AwaitingVMResult - { - public PPCViewModel FromVM { get; set; } - public PPCViewModel ToVM { get; set; } - public Action Action { get; set; } - } + private event Action<Object, Object> NavigationCycleCompleted; - private List<AwaitingVMResult> _awaitingVMResults; private IDispatcherProvider _dispatcherProvider; private IPPCModuleLoader _moduleLoader; - private INotificationProvider _notificationProvider; + private Object _currentVM; private String _lastFullPath; private bool _preventHistory; private bool _navigating_back; - public event EventHandler<PPCViewModel> CurrentVMChanged; - private Stack<String> _navigationHistory; - private Object _currentVM; /// <summary> /// Gets the current view model. /// </summary> public PPCViewModel CurrentVM { - set - { - var previous = _currentVM; - _currentVM = value; - - var vm = _currentVM as PPCViewModel; - - if (_currentVM != previous && vm != null) - { - CurrentVMChanged?.Invoke(this, vm); - } - } - get - { - return _currentVM as PPCViewModel; - } + get { return _currentVM as PPCViewModel; } } private IPPCModule _currentModule; @@ -95,13 +67,10 @@ namespace Tango.PPC.UI.Navigation /// Initializes a new instance of the <see cref="DefaultNavigationManager"/> class. /// </summary> /// <param name="moduleLoader">The module loader.</param> - public DefaultNavigationManager(IPPCModuleLoader moduleLoader, IDispatcherProvider dispatcherProvider, INotificationProvider notificationProvider) + public DefaultNavigationManager(IPPCModuleLoader moduleLoader, IDispatcherProvider dispatcherProvider) { - IsBackEnabled = true; - _awaitingVMResults = new List<AwaitingVMResult>(); _navigationHistory = new Stack<String>(); _moduleLoader = moduleLoader; - _notificationProvider = notificationProvider; NavigateToCommand = new RelayCommand<string>(async (x) => await NavigateTo(x)); NavigateBackCommand = new RelayCommand(async () => await NavigateBack()); @@ -144,19 +113,7 @@ namespace Tango.PPC.UI.Navigation { LogManager.Log($"Navigating to: {view.ToString()}..."); - - var fromView = MainView.Instance.NavigationControl.SelectedElement; - FrameworkElement toView = null; - - toView = MainView.Instance.NavigationControl.NavigateTo(view.ToString(), (Action)(() => - { - CurrentVM = toView.DataContext as PPCViewModel; - NotifyOnNavigated(fromView.DataContext, toView.DataContext); - - })); - - NotifyOnBeforeNavigated(fromView.DataContext, toView.DataContext); - + MainView.Instance.NavigationControl.NavigateTo(view.ToString()); return Task.FromResult(true); } } @@ -216,155 +173,88 @@ namespace Tango.PPC.UI.Navigation /// Navigates to the specified module and view by full path (e.g Jobs.JobsView). /// </summary> /// <param name="fullPath">The full path.</param> - public async Task<bool> NavigateTo(String fullPath, bool pushToHistory = true, Action<PPCViewModel, PPCViewModel> onNavigating = null, Action<PPCViewModel, PPCViewModel> onNavigated = null) + public async Task<bool> NavigateTo(String fullPath, bool pushToHistory = true) { - try - { - IsNavigating = true; + String[] path = fullPath.Split('.'); + var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType().Name == path[0] || x.Name == path[0]); - String[] path = fullPath.Split('.'); - var module = _moduleLoader.UserModules.SingleOrDefault(x => x.GetType().Name == path[0] || x.Name == path[0]); + if (path.Length == 1 && path[0] == CurrentModule.Name) return true; - if (module == null) - { - await _notificationProvider.ShowError("The specified module was not loaded."); - IsNavigating = false; - return false; - } + LogManager.Log($"Navigating to: {fullPath}..."); - if (path.Length == 1 && path[0] == CurrentModule.Name) - { - IsNavigating = false; - return true; - } - - LogManager.Log($"Navigating to: {fullPath}..."); + var fromVM = _currentVM; - var fromVM = CurrentVM; - - if (CurrentVM != null && CurrentVM is INavigationBlocker) + if (_currentVM != null && _currentVM is INavigationBlocker) + { + if (_navigating_back) { - if (_navigating_back) + if (!await (_currentVM as INavigationBlocker).OnNavigateBackRequest()) { - if (!await (CurrentVM as INavigationBlocker).OnNavigateBackRequest()) - { - IsNavigating = false; - return false; - } + return false; } - else + } + else + { + if (!await (_currentVM as INavigationBlocker).OnNavigateOutRequest()) { - if (!await (CurrentVM as INavigationBlocker).OnNavigateOutRequest()) - { - IsNavigating = false; - return false; - } + return false; } } + } + if (pushToHistory && _lastFullPath != null && !_preventHistory) + { + _navigationHistory.Push(_lastFullPath); + RaisePropertyChanged(nameof(CanNavigateBack)); + } + _lastFullPath = fullPath; - if (pushToHistory && _lastFullPath != null && !_preventHistory) - { - _navigationHistory.Push(_lastFullPath); - RaisePropertyChanged(nameof(CanNavigateBack)); - } - - _lastFullPath = fullPath; + MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString()); + var navigationControl = LayoutView.Instance.NavigationControl; + CurrentModule = module; + var moduleView = navigationControl.NavigateTo(module.Name); - MainView.Instance.NavigationControl.NavigateTo(NavigationView.LayoutView.ToString()); - var navigationControl = LayoutView.Instance.NavigationControl; - CurrentModule = module; - var moduleView = navigationControl.NavigateTo(module.Name); + _currentVM = moduleView.DataContext; - CurrentVM = moduleView.DataContext as PPCViewModel; + if (path.Length > 1) + { + var moduleNavigation = moduleView.FindChildOffline<NavigationControl>(); - if (path.Length > 1) + if (moduleNavigation != null) { - var moduleNavigation = moduleView.FindChildOffline<NavigationControl>(); - - if (moduleNavigation != null) + moduleNavigation.RegisterForLoadedOrNow(async (x, e) => { - moduleNavigation.RegisterForLoadedOrNow(async (x, e) => + foreach (var view in path.Skip(1)) { - var lastView = moduleNavigation.GetElement(path.Last()); - - if (lastView != null) - { - onNavigating?.Invoke(fromVM as PPCViewModel, lastView.DataContext as PPCViewModel); - } + await Task.Delay(100); + var v = moduleNavigation.NavigateTo(view); - foreach (var view in path.Skip(1)) + if (v != null) { - await Task.Delay(100); - - FrameworkElement v = null; - - v = moduleNavigation.NavigateTo(view, () => - { - if (v != null) - { - NotifyOnNavigated(fromVM, v.DataContext); - onNavigated?.Invoke(fromVM as PPCViewModel, v.DataContext as PPCViewModel); - NotifyAwaitingVMResults(fromVM as PPCViewModel, v.DataContext as PPCViewModel); - } - }); + _currentVM = v.DataContext; - NotifyOnBeforeNavigated(fromVM, v.DataContext); - - if (v != null) - { - CurrentVM = v.DataContext as PPCViewModel; - - if (view != path.Last()) - { - moduleNavigation = v.FindChildOffline<NavigationControl>(); - } - } - else + if (view != path.Last()) { - throw LogManager.Log(new ArgumentNullException("Could not navigate to " + fullPath)); + moduleNavigation = v.FindChildOffline<NavigationControl>(); } } - }); - } - else - { - onNavigating?.Invoke(fromVM as PPCViewModel, CurrentVM as PPCViewModel); - - NotifyOnBeforeNavigated(fromVM, CurrentVM); - - await Task.Delay(navigationControl.TransitionDuration.TimeSpan); - - NotifyOnNavigated(fromVM, CurrentVM); + else + { + throw LogManager.Log(new ArgumentNullException("Could not navigate to " + fullPath)); + } + } - onNavigated?.Invoke(fromVM as PPCViewModel, CurrentVM as PPCViewModel); - NotifyAwaitingVMResults(fromVM as PPCViewModel, CurrentVM as PPCViewModel); - } + NavigationCycleCompleted?.Invoke(fromVM, _currentVM); + }); } else { - NotifyOnBeforeNavigated(fromVM, CurrentVM); - - onNavigating?.Invoke(fromVM as PPCViewModel, CurrentVM as PPCViewModel); - - await Task.Delay(navigationControl.TransitionDuration.TimeSpan); - - NotifyOnNavigated(fromVM, CurrentVM); - - onNavigated?.Invoke(fromVM as PPCViewModel, CurrentVM as PPCViewModel); - NotifyAwaitingVMResults(fromVM as PPCViewModel, CurrentVM as PPCViewModel); + NavigationCycleCompleted?.Invoke(fromVM, _currentVM); } - - return true; - } - catch (Exception ex) - { - IsNavigating = false; - LogManager.Log(ex, $"Error navigating to '{fullPath}'."); - await _notificationProvider.ShowError($"Error navigating to '{fullPath}'."); - return false; } + + return true; } /// <summary> @@ -377,35 +267,46 @@ namespace Tango.PPC.UI.Navigation /// <param name="obj">The object.</param> /// <param name="pushToHistory">if set to <c>true</c> [push to history].</param> /// <returns></returns> - public async Task<TResult> NavigateForResult<TModule, TView, TResult, TObject>(TObject obj, bool pushToHistory = true) + public Task<TResult> NavigateForResult<TModule, TView, TResult, TObject>(TObject obj, bool pushToHistory = true) where TModule : IPPCModule { TaskCompletionSource<TResult> source = new TaskCompletionSource<TResult>(); - var fromVM = CurrentVM; + var fromVM = _currentVM; + Object toVM = null; + + + Action<Object, Object> handler = null; - await NavigateTo(typeof(TModule).Name + "." + typeof(TView).Name, pushToHistory, (from, to) => + handler = (from, to) => { - _awaitingVMResults.Add(new AwaitingVMResult() + if (toVM == null) + { + toVM = to; + if (toVM is INavigationResultProvider<TResult, TObject>) + { + (toVM as INavigationResultProvider<TResult, TObject>).OnNavigationObjectReceived(obj); + } + } + else { - FromVM = fromVM as PPCViewModel, - ToVM = to as PPCViewModel, - Action = () => + if (to == fromVM && from == toVM) { - if (to is INavigationResultProvider<TResult, TObject>) + if (from is INavigationResultProvider<TResult, TObject>) { - source.SetResult((to as INavigationResultProvider<TResult, TObject>).GetNavigationResult()); + source.SetResult((from as INavigationResultProvider<TResult, TObject>).GetNavigationResult()); } } - }); - if (to is INavigationResultProvider<TResult, TObject>) - { - (to as INavigationResultProvider<TResult, TObject>).OnNavigationObjectReceived(obj); + NavigationCycleCompleted -= handler; } - }); + }; + + NavigationCycleCompleted += handler; - return await source.Task; + NavigateTo<TModule>(typeof(TView).Name, pushToHistory); + + return source.Task; } /// <summary> @@ -419,13 +320,25 @@ namespace Tango.PPC.UI.Navigation /// <returns></returns> public Task<bool> NavigateWithObject<TModule, TView, TPass>(TPass obj, bool pushToHistory = true) where TModule : IPPCModule { - return NavigateTo(typeof(TModule).Name + "." + typeof(TView).Name, pushToHistory, (fromVM, toVM) => + TaskCompletionSource<bool> source = new TaskCompletionSource<bool>(); + + Action<Object, Object> handler = null; + + handler = (from, to) => { - if (toVM is INavigationObjectReceiver<TPass>) + if (to is INavigationObjectReceiver<TPass>) { - (toVM as INavigationObjectReceiver<TPass>).OnNavigatedToWithObject(obj); + (to as INavigationObjectReceiver<TPass>).OnNavigatedToWithObject(obj); } - }); + + NavigationCycleCompleted -= handler; + }; + + NavigationCycleCompleted += handler; + + NavigateTo<TModule>(typeof(TView).Name, pushToHistory); + + return source.Task; } private Task<bool> NavigateTo(Type moduleType, bool pushToHistory = true, params String[] viewPath) @@ -448,30 +361,6 @@ namespace Tango.PPC.UI.Navigation get { return _navigationHistory.Count > 0; } } - private bool _isBackEnabled; - /// <summary> - /// Gets a value indicating whether the back should be enabled. - /// </summary> - public bool IsBackEnabled - { - get { return _isBackEnabled; } - set { _isBackEnabled = value; RaisePropertyChangedAuto(); } - } - - private bool _isNavigating; - /// <summary> - /// Gets or sets a value indicating whether the navigation system is currently navigating. - /// </summary> - public bool IsNavigating - { - get { return _isNavigating; } - set - { - _isNavigating = value; - RaisePropertyChangedAuto(); - } - } - /// <summary> /// Navigates to the previous view if <see cref="P:Tango.PPC.Common.Navigation.INavigationManager.CanNavigateBack" /> is true. /// </summary> @@ -481,35 +370,25 @@ namespace Tango.PPC.UI.Navigation _navigating_back = true; - if (_navigationHistory.Count > 0) - { - String first = _navigationHistory.Pop(); - _preventHistory = true; + String first = _navigationHistory.Pop(); + _preventHistory = true; - if (await NavigateTo(first)) - { - RaisePropertyChanged(nameof(CanNavigateBack)); - _preventHistory = false; - _navigating_back = false; - return true; - } - else - { - _navigationHistory.Push(first); - _preventHistory = false; - _navigating_back = false; - RaisePropertyChanged(nameof(CanNavigateBack)); - return false; - } - } - else + + if (await NavigateTo(first)) { - await NavigateTo(NavigationView.HomeModule); RaisePropertyChanged(nameof(CanNavigateBack)); _preventHistory = false; _navigating_back = false; return true; } + else + { + _navigationHistory.Push(first); + _preventHistory = false; + _navigating_back = false; + RaisePropertyChanged(nameof(CanNavigateBack)); + return false; + } } /// <summary> @@ -541,48 +420,5 @@ namespace Tango.PPC.UI.Navigation RaisePropertyChanged(nameof(CanNavigateBack)); } - - private void NotifyOnBeforeNavigated(object fromVM, object toVM) - { - if (fromVM == toVM) return; - - if (fromVM is PPCViewModel) - { - (fromVM as PPCViewModel)?.OnBeforeNavigatedFrom(); - } - - if (toVM is PPCViewModel) - { - (toVM as PPCViewModel)?.OnBeforeNavigatedTo(); - } - } - - private void NotifyOnNavigated(object fromVM, object toVM) - { - IsNavigating = false; - - if (fromVM == toVM) return; - - if (fromVM is PPCViewModel) - { - (fromVM as PPCViewModel)?.OnNavigatedFrom(); - } - - if (toVM is PPCViewModel) - { - (toVM as PPCViewModel)?.OnNavigatedTo(); - (toVM as PPCViewModel)?.OnNavigatedTo(fromVM as PPCViewModel); - } - } - - private void NotifyAwaitingVMResults(PPCViewModel fromVM, PPCViewModel toVM) - { - var awaiter = _awaitingVMResults.SingleOrDefault(x => x.FromVM == toVM && x.ToVM == fromVM); - if (awaiter != null) - { - _awaitingVMResults.Remove(awaiter); - awaiter.Action(); - } - } } } |
