예제 #1
0
        public async Task UpdateNavigation(NavigationOperation <TViewModel> navigationOperation, INavigationInProgress navigationInProgress)
        {
            if (navigationOperation.Pushes.Count == 0 && navigationOperation.Pops.Count == 0)
            {
                return;
            }

            var controllersToPush = navigationOperation.Pushes.Select(x => new PushInformation <TViewModel>(_factoryAssociation[x.Screen], x.Instance)).ToList();

            foreach (var push in navigationOperation.Pushes)
            {
                await push.Instance.GetViewModel("");                 //TODO: add route here
            }

            if (navigationInProgress.IsCancelled)
            {
                Task.Run(async() =>
                {
                    // we wait 10s just in case, shouldn't put too much memory pressure on GC
                    await Task.Delay(10_000);

                    foreach (var push in navigationOperation.Pushes)
                    {
                        push.Instance.ViewModelInstance?.SafeDispose();
                    }
                }).ConfigureAwait(false);
                return;
            }

            navigationInProgress.Commit();

            CrossCurrentActivity.Current.Activity.RunOnUiThread(() => _navigationStack.ApplyActions(navigationOperation.Pops.Count, controllersToPush));
        }
        public INavigationOperation TryShowAsync(IViewModel viewModel, IDataContext context,
                                                 IViewModelPresenter parentPresenter)
        {
            if (!CanShowViewModel(viewModel, context, parentPresenter))
            {
                return(null);
            }
            var tcs       = new TaskCompletionSource <object>();
            var operation = new NavigationOperation(tcs.Task);

            context = context.ToNonReadOnly();
            context.AddOrUpdate(NavigationConstants.ViewModel, viewModel);
            var provider = viewModel.GetIocContainer(true).Get <INavigationProvider>();

            provider.CurrentNavigationTask.TryExecuteSynchronously(_ =>
            {
                try
                {
                    var task = provider.NavigateAsync(operation.ToOperationCallback(), context);
                    tcs.TrySetFromTask(task);
                }
                catch (Exception e)
                {
                    tcs.TrySetException(e);
                    throw;
                }
            });
            return(operation);
        }
예제 #3
0
        public virtual INavigationOperation TryShowAsync(IViewModel viewModel, IDataContext context,
                                                         IViewModelPresenter parentPresenter)
        {
            if (!MultiViewModel.ViewModelType.IsInstanceOfType(viewModel))
            {
                return(null);
            }
            bool data;

            if (context.TryGetData(NavigationConstants.SuppressTabNavigation, out data) && data)
            {
                return(null);
            }
            if (!CanShowViewModel(viewModel, context, parentPresenter))
            {
                return(null);
            }
            if (MultiViewModel.ItemsSource.Any(vm => vm == viewModel))
            {
                MultiViewModel.SelectedItem = viewModel;
            }
            else
            {
                MultiViewModel.AddViewModel(viewModel, true);
            }
            var operation = new NavigationOperation();

            CallbackManager.Register(OperationType.TabNavigation, viewModel, operation.ToOperationCallback(), context);
            return(operation);
        }
예제 #4
0
        public Task UpdateNavigation(NavigationOperation <SampleViewModel> navigationOperation, INavigationInProgress navigationInProgress)
        {
            Console.WriteLine($"\tOperations to apply: Pops={navigationOperation.Pops.Count}, Pushes={navigationOperation.Pushes.Count}");
            Console.WriteLine("");

            navigationInProgress.Commit();
            return(Task.CompletedTask);
        }
        public async Task UpdateNavigation(NavigationOperation <TViewModel> navigationOperation, INavigationInProgress navigationInProgress)
        {
            if (navigationOperation.Pushes.Count == 0 && navigationOperation.Pops.Count == 0)
            {
                return;
            }

            var controllersToPush = navigationOperation.Pushes.Select(x => new PushInformation <TViewModel>(_factoryAssociation[x.Screen], x.Instance));

            foreach (var push in navigationOperation.Pushes)
            {
                await push.Instance.GetViewModel("");                 //TODO: add route here
            }

            if (navigationInProgress.IsCancelled)
            {
                Task.Run(async() =>
                {
                    // we wait 10s just in case, shouldn't put too much memory pressure on GC
                    await Task.Delay(10_000);

                    foreach (var push in navigationOperation.Pushes)
                    {
                        push.Instance.ViewModelInstance?.SafeDispose();
                    }
                }).ConfigureAwait(false);
                return;
            }

            navigationInProgress.Commit();
            UIApplication.SharedApplication.InvokeOnMainThread(() =>
            {
                var callbackActionWaiter = new CallbackActionWaiter();
                callbackActionWaiter.WaitOne();
                _navigationStack.EnsureInitialized(_navigationController);

                _navigationStack.ApplyActions(navigationOperation.Pops.Count, controllersToPush, callbackActionWaiter);

                // lines below could be commented if we encounter issues with viewmodel disposing
                callbackActionWaiter.Add(() =>
                {
                    foreach (PopAction <TViewModel> pop in navigationOperation.Pops)
                    {
                        pop.Instance.ViewModelInstance?.DispatchSafeDispose();
                    }
                });

                Task.Run(async() =>
                {
                    // we wait 10s to let the time for navigation controller animations before disposing content
                    await Task.Delay(10_000);
                    UIApplication.SharedApplication.InvokeOnMainThread(callbackActionWaiter.ReleaseOne);
                });
            });
        }
예제 #6
0
 private void Journal_Navigated(object sender, JournalEventArgs args)
 {
     if (this._journalIsAddingHistoryPoint == false)
     {
         NavigationOperation navOp = this._currentNavigation;
         if (navOp == null || navOp.SuppressNotifications == false)
         {
             this.NavigateCore(args.Uri, args.NavigationMode, true /*suppressJournalAdd*/, false /*isRedirect*/);
         }
     }
 }
        /// <summary>
        /// StopLoading aborts asynchronous navigations that haven't been processed yet.
        /// The <see cref="NavigationStopped"/> event is raised only if the navigation was actually aborted - if navigation is
        /// too far along to be canceled, then navigation may still complete and the <see cref="Navigated"/> event
        /// will be raised.
        /// </summary>
        /// <value></value>
        public void StopLoading()
        {
            NavigationOperation navOp = this._currentNavigation;

            if (navOp != null)
            {
                this.RaiseNavigationStopped(null, navOp.Uri);

                // Release current context
                this._currentNavigation = null;
            }
        }
        private void ContentLoader_BeginLoad_Callback(IAsyncResult result)
        {
            DependencyObject content = null;
            Uri uriBeingLoaded       = null;

            try
            {
                NavigationOperation asyncNavigationOperationCompleted = result.AsyncState as NavigationOperation;

                NavigationOperation navOp = this._currentNavigation;
                if (navOp == null || navOp.Uri != asyncNavigationOperationCompleted.Uri)
                {
                    // We already fired NavigationStopped in NavigateCore(), so just return without doing anything
                    return;
                }

                uriBeingLoaded = navOp.UriBeforeMapping;

                content = this._contentLoader.EndLoad(result) as DependencyObject;

                // If the content is anything but a UserControl, we should throw.
                // We support UserControls as they are a typical thing created in designers such as Blend,
                // but for a full experience one would use Page to get to things like NavigationContext,
                // NavigationService, Title, etc.
                if (!(content is UserControl))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture,
                                                                      Resource.NavigationService_ContentIsNotAUserControl,
                                                                      content == null ? "null" : content.GetType().ToString(),
                                                                      "System.Windows.Controls.UserControl"));
                }

                // Content loader was successful, so complete navigation

                // Create a new navigation context
                JournalEntry.SetNavigationContext(content, new NavigationContext(UriParsingHelper.InternalUriParseQueryStringToDictionary(asyncNavigationOperationCompleted.Uri, true /* decodeResults */)));
                content.SetValue(NavigationServiceProperty, this);

                // Complete navigation operation
                this.CompleteNavigation(content);
            }
            catch (Exception ex)
            {
                if (this.RaiseNavigationFailed(uriBeingLoaded, ex))
                {
                    throw;
                }
            }
        }
        public INavigationOperation TryShowAsync(IViewModel viewModel, IDataContext context, IViewModelPresenter parentPresenter)
        {
            if (viewModel == this)
            {
                return(null);
            }

            var operation = new NavigationOperation();
            var callback  = operation.ToOperationCallback();

            //Saving callback to view model state that will allow us to execute it even after app save\restore cycle.
            _callbackManager.Register(NavigationType, viewModel, callback, context);
            OnShowViewModel(viewModel);
            return(operation);
        }
예제 #10
0
        private void StopLoadingCore(bool fromRedirect)
        {
            NavigationOperation navOp = this._currentNavigation;

            if (navOp != null)
            {
                if (!fromRedirect)
                {
                    // We don't want to call CancelLoad for redirects
                    this.ContentLoader.CancelLoad(navOp.AsyncResult);
                }

                this.RaiseNavigationStopped(null, navOp.Uri);

                // Release current context
                this._currentNavigation = null;
            }
        }
예제 #11
0
        private bool NavigateCore_StartNavigation(Uri uri, NavigationMode mode, bool suppressJournalAdd, Uri mergedUriAfterMapping, Uri mergedUri, bool isFragmentNavigationOnly)
        {
            this._currentNavigation = new NavigationOperation(mergedUriAfterMapping, mergedUri, uri, mode, suppressJournalAdd);

            if (isFragmentNavigationOnly)
            {
                // If we're navigating only to a fragment (e.g. "#frag2") then the Uri to journal should be that merged with the base uri
                if (UriParsingHelper.InternalUriIsFragment(uri))
                {
                    this._currentNavigation.UriForJournal = mergedUri;
                }
                this.Host.Dispatcher.BeginInvoke(() => this.CompleteNavigation(null));
                return(true);
            }

            this.UpdateNavigationCacheModeAlwaysPages();

            string uriAllButFragment = UriParsingHelper.InternalUriGetAllButFragment(uri);
            Page   reusedPage        = null;

            if (this._cacheRequiredPages.ContainsKey(uriAllButFragment))
            {
                reusedPage = this._cacheRequiredPages[uriAllButFragment];
            }
            else if (this.Cache.Contains(uriAllButFragment))
            {
                reusedPage = this.Cache[uriAllButFragment];
            }

            // If a page was found in either cache and that page hasn't yet changed its NavigationCacheMode to Disabled,
            // then navigation is done, otherwise open up new content
            if (reusedPage != null && reusedPage.NavigationCacheMode != NavigationCacheMode.Disabled)
            {
                this.Host.Dispatcher.BeginInvoke(() => this.CompleteNavigation(reusedPage));
            }
            else
            {
                this._currentNavigation.AsyncResult = this._contentLoader.BeginLoad(mergedUriAfterMapping, this._currentSourceAfterMapping, this.ContentLoader_BeginLoad_Callback, this._currentNavigation);
            }

            return(true);
        }
예제 #12
0
        protected Mock <IEditorWrapperViewModel> SetupEditableWrapper(bool result,
                                                                      Action <IViewModel> wrapCallback = null)
        {
            var wrapper = new Mock <IEditorWrapperViewModel>();

            WrapperManagerMock
            .Setup(provider => provider.Wrap(It.IsAny <IViewModel>(), typeof(IEditorWrapperViewModel), It.IsAny <IDataContext>()))
            .Returns <IViewModel, Type, IDataContext>((vm, t, context) =>
            {
                if (wrapCallback != null)
                {
                    wrapCallback(vm);
                }
                return(wrapper.Object);
            });
            var operation = new NavigationOperation();

            operation.SetResult(OperationResult.CreateResult(OperationType.PageNavigation, wrapper, result));
            ViewModelPresenterMock.Setup(presenter => presenter.ShowAsync(wrapper.Object, It.IsAny <IDataContext>()))
            .Returns(() => operation);
            return(wrapper);
        }
예제 #13
0
        public INavigationOperation TryShowAsync(IViewModel viewModel, IDataContext context,
                                                 IViewModelPresenter parentPresenter)
        {
            var viewMediator = TryCreateWindowViewMediator(viewModel, context);

            if (viewMediator == null)
            {
                return(null);
            }
            var tcs       = new TaskCompletionSource <object>();
            var operation = new NavigationOperation(tcs.Task);

            if (_currentTask == null)
            {
                Show(viewMediator, operation, context, tcs);
            }
            else
            {
                _currentTask.TryExecuteSynchronously(_ => Show(viewMediator, operation, context, tcs));
            }
            return(operation);
        }
        public void Navigate(NavigationOperation operation)
        {
            switch (operation)
            {
            case NavigationOperation.NavigateBack:
                this.Driver.Navigate().Back();

                break;

            case NavigationOperation.NavigateForward:
                this.Driver.Navigate().Forward();

                break;

            case NavigationOperation.Reload:
                this.Driver.Navigate().Refresh();

                break;

            default:
                throw new InvalidOperationException($"The navigation operation '{operation}' is invalid.");
            }
        }
예제 #15
0
        public virtual INavigationOperation TryShowAsync(IViewModel viewModel, IDataContext context,
                                                         IViewModelPresenter parentPresenter)
        {
            Should.NotBeNull(viewModel, "viewModel");
            if (ReferenceEquals(viewModel, _multiViewModel))
            {
                return(null);
            }
            bool data;

            if (context.TryGetData(NavigationConstants.SuppressTabNavigation, out data) && data)
            {
                return(null);
            }
            if (!CanShowViewModel(viewModel, context, parentPresenter))
            {
                return(null);
            }
            MultiViewModel.AddViewModel(viewModel, true);
            var operation = new NavigationOperation();

            CallbackManager.Register(OperationType.TabNavigation, viewModel, operation.ToOperationCallback(), context);
            return(operation);
        }
 public virtual INavigationOperation TryShowAsync(IViewModel viewModel, IDataContext context,
     IViewModelPresenter parentPresenter)
 {
     Should.NotBeNull(viewModel, "viewModel");
     bool data;
     if (context.TryGetData(NavigationConstants.SuppressTabNavigation, out data) && data)
         return null;
     if (!CanShowViewModel(viewModel, context, parentPresenter))
         return null;
     MultiViewModel.AddViewModel(viewModel, true);
     var operation = new NavigationOperation();
     CallbackManager.Register(OperationType.TabNavigation, viewModel, operation.ToOperationCallback(), context);
     return operation;
 }
 public INavigationOperation TryShowAsync(IViewModel viewModel, IDataContext context,
     IViewModelPresenter parentPresenter)
 {
     if (!CanShowViewModel(viewModel, context, parentPresenter))
         return null;
     var tcs = new TaskCompletionSource<object>();
     var operation = new NavigationOperation(tcs.Task);
     context = context.ToNonReadOnly();
     context.AddOrUpdate(NavigationConstants.ViewModel, viewModel);
     var provider = viewModel.GetIocContainer(true).Get<INavigationProvider>();
     provider.CurrentNavigationTask.TryExecuteSynchronously(_ =>
     {
         try
         {
             var task = provider.NavigateAsync(operation.ToOperationCallback(), context);
             tcs.TrySetFromTask(task);
         }
         catch (Exception e)
         {
             tcs.TrySetException(e);
             throw;
         }
     });
     return operation;
 }
        /// <summary>
        /// StopLoading aborts asynchronous navigations that haven't been processed yet.
        /// The <see cref="NavigationStopped"/> event is raised only if the navigation was actually aborted - if navigation is
        /// too far along to be canceled, then navigation may still complete and the <see cref="Navigated"/> event
        /// will be raised.
        /// </summary>
        /// <value></value>
        public void StopLoading()
        {
            NavigationOperation navOp = this._currentNavigation;
            if (navOp != null)
            {
                this.RaiseNavigationStopped(null, navOp.Uri);

                // Release current context
                this._currentNavigation = null;
            }
        }
        private void CompleteNavigation(DependencyObject content)
        {
            Uri uri = null;
            string pageTitle = null;
            Page existingContentPage = this._host.Content as Page;
            Page newContentPage = content as Page;

            pageTitle = JournalEntry.GetName(content ?? this._host.Content as DependencyObject);

            NavigationOperation navOp = this._currentNavigation;
            this._currentNavigation = null;
            if (navOp != null)
            {
                // Set uri
                uri = navOp.UriBeforeMapping;

                this.UpdateNavigationCacheModeAlwaysPages();

                // Used to suppress navigation notifications.
                navOp.SuppressNotifications = true;

                this.CurrentSource = navOp.UriForJournal;
                this._source = navOp.UriBeforeMapping;
                this._currentSourceAfterMapping = navOp.Uri;
                this.Host.UpdateSourceFromNavigationService(navOp.UriForJournal);
                this.Host.CurrentSource = this.CurrentSource;

                // Check if this is a 'New' operation
                if (navOp.Mode == NavigationMode.New && navOp.Uri != null && navOp.SuppressJournalAdd == false)
                {
                    try
                    {
                        this._journalIsAddingHistoryPoint = true;
                        JournalEntry je = new JournalEntry(pageTitle ?? uri.OriginalString, navOp.UriForJournal);
                        this.Journal.AddHistoryPoint(je);
                    }
                    finally
                    {
                        this._journalIsAddingHistoryPoint = false;
                    }
                }

                this.Host.CanGoBack = this.CanGoBack;
                this.Host.CanGoForward = this.CanGoForward;

                navOp.SuppressNotifications = false;
            }

            if (this.Journal.UseNavigationState && HtmlPage.IsEnabled)
            {
                HtmlPage.Document.SetProperty("title", pageTitle ?? uri.OriginalString);
            }
            if (content == null)
            {
                // We're navigating to a fragment in the current page, so for WPF compatibility, fire FragmentNavigation THEN Navigated

                this.RaiseFragmentNavigation(UriParsingHelper.InternalUriGetFragment(navOp.Uri));
                this.RaiseNavigated(content, uri, existingContentPage, newContentPage);
            }
            else
            {
                // We're navigating to a fragment in the new content, so let the host load content, then for WPF compatibility,
                // fire Navigated THEN FragmentNavigation
                this.Host.Content = content;
                this.RaiseNavigated(content, uri, existingContentPage, newContentPage);
                string fragment = UriParsingHelper.InternalUriGetFragment(navOp.Uri);
                if (!String.IsNullOrEmpty(fragment))
                {
                    this.RaiseFragmentNavigation(fragment);
                }
            }
        }
        private bool NavigateCore_StartNavigation(Uri uri, NavigationMode mode, bool suppressJournalAdd, Uri mergedUriAfterMapping, Uri mergedUri, bool isFragmentNavigationOnly)
        {
            this._currentNavigation = new NavigationOperation(mergedUriAfterMapping, mergedUri, uri, mode, suppressJournalAdd);

            if (isFragmentNavigationOnly)
            {
                // If we're navigating only to a fragment (e.g. "#frag2") then the Uri to journal should be that merged with the base uri
                if (UriParsingHelper.InternalUriIsFragment(uri))
                {
                    this._currentNavigation.UriForJournal = mergedUri;
                }
                this.Host.Dispatcher.BeginInvoke(() => this.CompleteNavigation(null));
                return true;
            }

            string uriAllButFragment = UriParsingHelper.InternalUriGetAllButFragment(uri);
            Page reusedPage = null;

            if (this._cacheRequiredPages.ContainsKey(uriAllButFragment))
            {
                reusedPage = this._cacheRequiredPages[uriAllButFragment];
            }
            else if (this.Cache.Contains(uriAllButFragment))
            {
                reusedPage = this.Cache[uriAllButFragment];
            }

            // If a page was found in either cache and that page hasn't yet changed its NavigationCacheMode to Disabled,
            // then navigation is done, otherwise open up new content
            if (reusedPage != null && reusedPage.NavigationCacheMode != NavigationCacheMode.Disabled)
            {
                this.Host.Dispatcher.BeginInvoke(() => this.CompleteNavigation(reusedPage));
            }
            else
            {
                this._contentLoader.BeginLoad(mergedUriAfterMapping, this.ContentLoader_BeginLoad_Callback, this._currentNavigation);
            }

            return true;
        }
        public INavigationOperation TryShowAsync(IViewModel viewModel, IDataContext context, IViewModelPresenter parentPresenter)
        {
            if (viewModel == this)
                return null;

            var operation = new NavigationOperation();
            var callback = operation.ToOperationCallback();
            //Saving callback to view model state that will allow us to execute it even after app save\restore cycle.
            _callbackManager.Register(NavigationType, viewModel, callback, context);
            OnShowViewModel(viewModel);
            return operation;
        }
 public virtual INavigationOperation TryShowAsync(IViewModel viewModel, IDataContext context,
     IViewModelPresenter parentPresenter)
 {
     Should.NotBeNull(viewModel, nameof(viewModel));
     if (ReferenceEquals(viewModel, _multiViewModel))
         return null;
     bool data;
     if (context.TryGetData(NavigationConstants.SuppressTabNavigation, out data) && data)
         return null;
     if (!CanShowViewModel(viewModel, context, parentPresenter))
         return null;
     if (MultiViewModel.ItemsSource.Contains(viewModel))
         MultiViewModel.SelectedItem = viewModel;
     else
         MultiViewModel.AddViewModel(viewModel, true);
     var operation = new NavigationOperation();
     CallbackManager.Register(OperationType.TabNavigation, viewModel, operation.ToOperationCallback(), context);
     return operation;
 }
예제 #23
0
            public bool Restore(Type targetType, object target, Dictionary <Type, object> items, ICollection <IViewModel> viewModels, string awaiterResultType, IOperationResult result)
            {
                var field = targetType.GetFieldEx(Name, MemberFlags.NonPublic | MemberFlags.Public | MemberFlags.Instance);

                if (field == null)
                {
                    TraceError(null, targetType);
                    return(false);
                }
                switch (FieldType)
                {
                case BuilderField:
                    var type         = Type.GetType(TypeName, true);
                    var createMethod = type.GetMethodEx("Create", MemberFlags.NonPublic | MemberFlags.Public | MemberFlags.Static);
                    var startMethod  = type.GetMethodEx("Start", MemberFlags.NonPublic | MemberFlags.Public | MemberFlags.Instance);
                    if (createMethod == null || startMethod == null || !startMethod.IsGenericMethodDefinition)
                    {
                        ((IAsyncStateMachine)target).MoveNext();
                        return(true);
                    }
                    var builder = createMethod.Invoke(null, Empty.Array <object>());
                    field.SetValueEx(target, builder);
                    startMethod.MakeGenericMethod(typeof(IAsyncStateMachine))
                    .Invoke(builder, new[] { target });
                    break;

                case AwaiterField:
                    var awaiterType = typeof(SerializableAwaiter <>).MakeGenericType(Type.GetType(awaiterResultType, true));
                    var instance    = Activator.CreateInstance(awaiterType, result);
                    field.SetValueEx(target, instance);
                    break;

                case AsyncOperationField:
                    var opType     = typeof(AsyncOperation <>).MakeGenericType(Type.GetType(awaiterResultType, true));
                    var opInstance = (IAsyncOperation)Activator.CreateInstance(opType);
                    AsyncOperation <object> .TrySetResult(opInstance, result);

                    field.SetValueEx(target, opInstance);
                    break;

                case AnonymousClass:
                    var    anonType = Type.GetType(TypeName, true);
                    object anonClass;
                    if (!items.TryGetValue(anonType, out anonClass))
                    {
                        anonClass = ServiceProvider.GetOrCreate(anonType);
                        foreach (var snapshot in Snapshots)
                        {
                            snapshot.Restore(anonType, anonClass, items, viewModels, awaiterResultType, result);
                        }
                        items[anonType] = anonClass;
                    }
                    field.SetValueEx(target, anonClass);
                    break;

                case NavigationOperationField:
                    var operation = new NavigationOperation();
                    operation.SetResult(OperationResult.Convert <bool>(result));
                    field.SetValueEx(target, operation);
                    break;

                case NonSerializableField:
                    object service;
                    if (State == null)
                    {
                        var serviceType = Type.GetType(TypeName, true);
                        if (!items.TryGetValue(serviceType, out service))
                        {
                            if (field.Name.Contains("CachedAnonymousMethodDelegate"))
                            {
                                service = field.GetValueEx <object>(target);
                            }
                            else if (!ServiceProvider.TryGet(serviceType, out service))
                            {
                                service = field.GetValueEx <object>(target);
                                TraceError(field, targetType);
                            }
                            items[serviceType] = service;
                        }
                    }
                    else
                    {
                        var restoreValueState = ApplicationSettings.RestoreValueState;
                        service = restoreValueState == null ? State : restoreValueState(State, items, viewModels);
                    }
                    field.SetValueEx(target, service);
                    break;

                case SerializableField:
                    field.SetValueEx(target, IsType ? Type.GetType((string)State, false) : State);
                    break;

                case ViewModelField:
                    var viewModel = FindViewModel(viewModels);
                    if (viewModel == null)
                    {
                        TraceError(field, targetType);
                        return(false);
                    }
                    field.SetValueEx(target, viewModel);
                    break;
                }
                return(true);
            }
예제 #24
0
        private void CompleteNavigation(DependencyObject content)
        {
            Uri    uri                 = null;
            string pageTitle           = null;
            Page   existingContentPage = this._host.Content as Page;
            Page   newContentPage      = content as Page;

            pageTitle = JournalEntry.GetName(content ?? this._host.Content as DependencyObject);

            NavigationOperation navOp = this._currentNavigation;

            this._currentNavigation = null;
            if (navOp != null)
            {
                // Set uri
                uri = navOp.UriBeforeMapping;

                // Used to suppress navigation notifications.
                navOp.SuppressNotifications = true;

                if (this.CurrentSource == navOp.UriForJournal)
                {
                    // Do not record the navigation in the journal when moving to the same URI whether this
                    // is a redirection or not.
                    navOp.SuppressJournalAdd = true;
                }
                this.CurrentSource = navOp.UriForJournal;
                this._source       = navOp.UriBeforeMapping;
                this._currentSourceAfterMapping = navOp.Uri;
                this.Host.UpdateSourceFromNavigationService(navOp.UriForJournal);
                this.Host.CurrentSource = this.CurrentSource;

                // Check if this is a 'New' operation
                if (navOp.Mode == NavigationMode.New && navOp.Uri != null && navOp.SuppressJournalAdd == false)
                {
                    try
                    {
                        this._journalIsAddingHistoryPoint = true;
                        JournalEntry je = new JournalEntry(pageTitle ?? uri.OriginalString, navOp.UriForJournal);
                        this.Journal.AddHistoryPoint(je);
                    }
                    finally
                    {
                        this._journalIsAddingHistoryPoint = false;
                    }
                }

                this.Host.CanGoBack    = this.CanGoBack;
                this.Host.CanGoForward = this.CanGoForward;

                navOp.SuppressNotifications = false;
            }

            if (this.Journal.UseNavigationState && HtmlPage.IsEnabled)
            {
                HtmlPage.Document.SetProperty("title", pageTitle ?? (uri == null ? string.Empty : uri.OriginalString));
            }
            if (content == null)
            {
                // We're navigating to a fragment in the current page, so for WPF compatibility, fire FragmentNavigation THEN Navigated
                if (navOp != null)
                {
                    this.RaiseFragmentNavigation(UriParsingHelper.InternalUriGetFragment(navOp.Uri));
                    this.RaiseNavigated(content, uri, existingContentPage, newContentPage);
                }
            }
            else
            {
                // We're navigating to a fragment in the new content, so let the host load content, then for WPF compatibility,
                // fire Navigated THEN FragmentNavigation
                this.Host.Content = content;
                this.RaiseNavigated(content, uri, existingContentPage, newContentPage);
                string fragment = navOp == null ? null : UriParsingHelper.InternalUriGetFragment(navOp.Uri);
                if (!String.IsNullOrEmpty(fragment))
                {
                    this.RaiseFragmentNavigation(fragment);
                }
            }
        }
        public INavigationOperation TryShowAsync(IViewModel viewModel, IDataContext context,
            IViewModelPresenter parentPresenter)
        {
            var viewMediator = TryCreateWindowViewMediator(viewModel, context);
            if (viewMediator == null)
                return null;
            var tcs = new TaskCompletionSource<object>();
            var operation = new NavigationOperation(tcs.Task);

            if (_currentTask == null)
                Show(viewMediator, operation, context, tcs);
            else
                _currentTask.TryExecuteSynchronously(_ => Show(viewMediator, operation, context, tcs));
            return operation;
        }