internal UipTransition(UipNode node, string navigateValue, UipNode nextNode) { Verify.ArgumentNotNull(node, "node"); Verify.ArgumentNotNull(navigateValue, "navigateValue"); _node = node; _navigateValue = navigateValue; _nextNode = nextNode; }
/// <summary> /// Perform the navigation to the next UI node /// </summary> /// <param name="nextNode">The next UI node to navigate to.</param> /// <remarks> /// This process is slightly complicated by the fact that both the controller and /// the view can initiate a navigation inside their constructor and/or their initialization /// sequence (for example if they implement <see cref="ISupportInitialize"/>). /// </remarks> private void DoNavigate(UipNode nextNode) { if (nextNode != null) { UipNode prevNode = _currentNode; _currentNode = nextNode; // signal task started if (prevNode == null) { // the task has just started _raiseTaskStarted = true; RunningTasks.Add(this); } else { // tell the previous node that it is no longer current prevNode.ExitNode(); } // Tell the node that it is now the current node. This needs to happen // after calling ExitNode on the previous node, just in case the previous node // and the current node are actually the same node. _currentNode.EnterNode(); // Create the controller for the new current node. It is possible for // a controller to request navigation inside its constructor, and if this happens // the navigateValue variable will be set, and we will continue through this loop again. _currentController = _currentNode.GetOrCreateController(); // if (_navigateValue != null) { // if the controller navigated during its constructor, stop now without // creating the current view return; } // Create the view for the new current node. It is possible for a view to // request navigation inside its constructor, and if this happens the navigateValue // variable will be set, and we will continue through this loop again. _currentView = _currentNode.GetOrCreateView(); } }
private void NavigateHelper() { _inNavigateMethod = true; bool showModalView = false; try { UipNode nextNode = GetNextNode(); if (nextNode != null) { using (var viewTransition = ViewManager.BeginTransition(this)) { try { // We wait until now to register with the view manager so that all calls // to the view manager occur withing a BeginTransition/EndTransition pair if (!_registeredWithViewManager) { //_viewManager.BeginTask(this); _registeredWithViewManager = true; } do { // Perform the navigation. This call // can result in a recursive call back into this function, // hence the test using the <c>inNavigateMethod</c> variable. DoNavigate(nextNode); // If there was a recursive call to this function, then this // will return non-null. nextNode = GetNextNode(); } while (nextNode != null); if (!_endTaskRequested && _currentNode != null) { // Finished navigating to a new node, display the new view. if (_currentView != null) { if (_currentNode.IsViewModal) { // We can't block and show a modal view here // because the _inNavigateMethod member is set to // true and this will prevent any navigation from // within the modal view. For this reason set a variable // to remind us to show the modal view before leaving this // method. showModalView = true; } else { // It is possible for the view to navigate while it is // in the process of showing the view. It is a bit difficult // to handle this here, as there is cleanup to perform. This // code could all do with a good refactor, but for now the way // this is handled is by the loop in the Navigate method. viewTransition.ShowView(_currentView); } } } } catch (Exception ex) { Log.Error("Unexpected exception in transition: " + ex.Message, ex); throw; } } } if (_endTaskRequested) { using (_viewManager.BeginTransition(this)) { if (_currentNode != null) { _currentNode.ExitNode(); } } _currentNode = null; _currentController = null; _currentView = null; _navigateValue = null; _taskComplete = true; RunningTasks.Remove(this); _raiseTaskComplete = true; } } finally { _inNavigateMethod = false; } if (showModalView) { using (var transition = CurrentNode.GetViewDeck(createIfNecessary: true).BeginTransition(this)) { transition.ShowView(CurrentNode.View); } CurrentNode.GetModalWindow(createIfNecessary: true).ShowModal(false); } }