コード例 #1
0
        /// <summary>
        ///     Save the current <see cref="SessionState" />.  Any <see cref="Frame" /> instances
        ///     registered with <see cref="RegisterFrame" /> will also preserve their current
        ///     navigation stack, which in turn gives their active <see cref="Page" /> an opportunity
        ///     to save its state.
        /// </summary>
        /// <returns>An asynchronous task that reflects when session state has been saved.</returns>
        public static async Task SaveAsync()
        {
            try
            {
                // Save the navigation state for all registered frames
                foreach (var weakFrameReference in RegisteredFrames)
                {
                    Frame frame;
                    if (weakFrameReference.TryGetTarget(out frame))
                    {
                        SaveFrameNavigationState(frame);
                    }
                }

                // Serialize the session state synchronously to avoid asynchronous access to shared state
                var sessionData = ToolkitServiceProvider.Get <ISerializer>().Serialize(SessionState);

                // Get an output stream for the SessionState file and write the state asynchronously
                var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(SessionStateFilename, CreationCollisionOption.ReplaceExisting);

                using (var fileStream = await file.OpenStreamForWriteAsync())
                {
                    sessionData.Seek(0, SeekOrigin.Begin);
                    await sessionData.CopyToAsync(fileStream);
                }
            }
            catch (Exception e)
            {
                Tracer.Error(e.Flatten(true));
                throw new SuspensionManagerException(e);
            }
        }
コード例 #2
0
        /// <summary>
        ///     Restores previously saved <see cref="SessionState" />.  Any <see cref="Frame" /> instances
        ///     registered with <see cref="RegisterFrame" /> will also restore their prior navigation
        ///     state, which in turn gives their active <see cref="Page" /> an opportunity restore its
        ///     state.
        /// </summary>
        /// <param name="sessionBaseKey">
        ///     An optional key that identifies the type of session.
        ///     This can be used to distinguish between multiple application launch scenarios.
        /// </param>
        /// <returns>
        ///     An asynchronous task that reflects when session state has been read.  The
        ///     content of <see cref="SessionState" /> should not be relied upon until this task
        ///     completes.
        /// </returns>
        public static async Task RestoreAsync(string sessionBaseKey = null)
        {
            SessionState = new Dictionary <string, object>();

            try
            {
                // Get the input stream for the SessionState file
                var file = await ApplicationData.Current.LocalFolder.GetFileAsync(SessionStateFilename);

                using (var inStream = await file.OpenSequentialReadAsync())
                {
                    // Deserialize the Session State
                    SessionState = (Dictionary <string, object>)ToolkitServiceProvider.Get <ISerializer>().Deserialize(inStream.AsStreamForRead());
                }

                // Restore any registered frames to their saved state
                foreach (var weakFrameReference in RegisteredFrames)
                {
                    Frame frame;
                    if (weakFrameReference.TryGetTarget(out frame) &&
                        (string)frame.GetValue(FrameSessionBaseKeyProperty) == sessionBaseKey)
                    {
                        frame.ClearValue(FrameSessionStateProperty);
                        RestoreFrameNavigationState(frame);
                    }
                }
            }
            catch (Exception e)
            {
                Tracer.Error(e.Flatten(true));
                throw new SuspensionManagerException(e);
            }
        }
コード例 #3
0
 protected virtual void SaveState()
 {
     if (_presenter == null && !_presenterActivated)
     {
         _presenter          = ToolkitServiceProvider.Get <IViewModelPresenter>() as IRestorableViewModelPresenter;
         _presenterActivated = true;
     }
     _presenter?.SaveState();
 }
コード例 #4
0
        protected virtual void InitializeRootPage(IViewModel viewModel, IDataContext context)
        {
            var mainPage       = (Page)ViewManager.GetOrCreateView(viewModel, true, context);
            var navigationPage = mainPage as NavigationPage;

            if (WrapToNavigationPage)
            {
                navigationPage = CreateNavigationPage(mainPage);
            }

            var isRoot = navigationPage == null || ReferenceEquals(mainPage, navigationPage);

            if (navigationPage != null)
            {
                INavigationService navigationService;
                if (!ToolkitServiceProvider.TryGet(out navigationService))
                {
                    navigationService = CreateNavigationService();
                    ToolkitServiceProvider.IocContainer.BindToConstant(navigationService);
                }

                //Activating navigation provider if need
                INavigationProvider provider;
                ToolkitServiceProvider.TryGet(out provider);

                navigationService.UpdateRootPage(navigationPage, viewModel);
                mainPage = navigationPage;
            }
            Application.Current.MainPage = mainPage;

            EventHandler <Page, CancelEventArgs> handler = OnBackButtonPressed;

            XamarinFormsToolkitExtensions.BackButtonPressed -= handler;

            var mode = NavigationMode.New;

            if (isRoot)
            {
                XamarinFormsToolkitExtensions.BackButtonPressed += handler;

                if (viewModel.Settings.State.Contains(IsRootConstant))
                {
                    mode = NavigationMode.Refresh;
                }
                else
                {
                    viewModel.Settings.State.AddOrUpdate(IsRootConstant, null);
                }
                viewModel.Settings.Metadata.AddOrUpdate(ViewModelConstants.CanCloseHandler, CanCloseRootViewModel);
                NavigationDispatcher.OnNavigated(new NavigationContext(NavigationType.Page, mode, null, viewModel, this, context));
            }
            else
            {
                mainPage.SetNavigationParameter(NavigationProvider.GenerateNavigationParameter(viewModel));
                ToolkitServiceProvider.Get <INavigationProvider>().Restore(context);
            }
        }
コード例 #5
0
        protected T Get <T>()
        {
            var viewModel = DataContext as IViewModel;

            if (viewModel == null)
            {
                return(ToolkitServiceProvider.Get <T>());
            }
            return(viewModel.GetIocContainer(true).Get <T>());
        }
コード例 #6
0
        protected virtual object GetView([NotNull] IViewMappingItem viewMapping, [NotNull] IDataContext context)
        {
            object viewObj = ToolkitServiceProvider.Get(viewMapping.ViewType);

            if (ApplicationSettings.ViewManagerDisposeView)
            {
                ToolkitServiceProvider.AttachedValueProvider.SetValue(viewObj, ViewManagerCreatorPath, null);
            }
            if (Tracer.TraceInformation)
            {
                Tracer.Info("The view {0} for the view-model {1} was created.", viewObj.GetType(), viewMapping.ViewModelType);
            }
            return(viewObj);
        }
コード例 #7
0
        public override void OnDestroy(Action baseOnDestroy)
        {
            if (Tracer.TraceInformation)
            {
                Tracer.Info($"OnDestroy activity({Target})");
            }
            ToolkitServiceProvider.EventAggregator.Unsubscribe(this);
            Destroyed?.Invoke(Target, EventArgs.Empty);
            _view.ClearBindingsRecursively(true, true, AndroidToolkitExtensions.AggressiveViewCleanup);
            _view = null;

            if (_metadata != null)
            {
                _metadata.Clear();
                _metadata = null;
            }

            MenuTemplate.Clear(_menu);
            _menu = null;

            if (_menuInflater != null)
            {
                _menuInflater.Dispose();
                _menuInflater = null;
            }
            if (_layoutInflater != null)
            {
                _layoutInflater.Dispose();
                _layoutInflater = null;
            }
            ToolkitServiceProvider.Get <INavigationService>().OnDestroyActivity(Target, NavigationContext);
            base.OnDestroy(baseOnDestroy);
            ThreadPool.QueueUserWorkItem(state => AndroidToolkitExtensions.CleanupWeakReferences(true));
            AndroidToolkitExtensions.SetCurrentActivity(Target, true);
            Target.ClearBindings(false, true);
            OptionsItemSelected  = null;
            ActivityResult       = null;
            ConfigurationChanged = null;
            PostCreate           = null;
            BackPressing         = null;
            Created           = null;
            Started           = null;
            Paused            = null;
            SaveInstanceState = null;
            Stoped            = null;
            Restarted         = null;
            Resume            = null;
            Destroyed         = null;
        }
コード例 #8
0
        private static void MvvmApplicationOnInitialized(object sender, EventArgs eventArgs)
        {
            ToolkitServiceProvider.Initialized -= MvvmApplicationOnInitialized;
            IViewModelPresenter presenter;

            if (ToolkitServiceProvider.TryGet(out presenter))
            {
                var windowPresenter = presenter.DynamicPresenters.OfType <DynamicViewModelWindowPresenter>().FirstOrDefault();
                if (windowPresenter == null)
                {
                    windowPresenter = ToolkitServiceProvider.Get <DynamicViewModelWindowPresenter>();
                    presenter.DynamicPresenters.Add(windowPresenter);
                }
                windowPresenter.RegisterMediatorFactory <WindowViewMediator, IWindowView>();
            }
        }
コード例 #9
0
        protected virtual UIViewController GetViewControllerInternal([NotNull] string restorationIdentifier, [NotNull] Type type,
                                                                     [NotNull] NSCoder coder, [NotNull] IDataContext context)
        {
            UIViewController controller = null;
            Func <Type, NSCoder, IDataContext, UIViewController> factory = ViewControllerFactory;

            if (factory != null)
            {
                controller = factory(type, coder, context);
            }
            if (controller == null)
            {
                if (type == typeof(MvvmNavigationController))
                {
                    controller = new MvvmNavigationController();
                }
                else
                {
                    controller = (UIViewController)ToolkitServiceProvider.Get(type);
                }
            }
            controller.RestorationIdentifier = restorationIdentifier;
            return(controller);
        }
コード例 #10
0
 protected virtual INavigationService CreateNavigationService(Frame frame)
 {
     return(new FrameNavigationService(frame, ToolkitServiceProvider.Get <IViewModelProvider>()));
 }
コード例 #11
0
        public virtual void OnNewIntent(Intent intent, Action <Intent> baseOnNewIntent)
        {
            baseOnNewIntent(intent);
            //note android doesn't support reorder activity by instance it will reorder it using type, we need to manually change view model if need
            var  oldViewModel = DataContext as IViewModel;
            Guid id;

            if (oldViewModel != null && Guid.TryParse(intent.GetStringExtra(IntentViewModelIdKey), out id))
            {
                var newViewModel = ToolkitServiceProvider.ViewModelProvider.TryGetViewModelById(id);
                if (newViewModel != null && !ReferenceEquals(newViewModel, oldViewModel))
                {
                    var navigationDispatcher = ToolkitServiceProvider.Get <INavigationDispatcher>();
                    var openedViewModels     = navigationDispatcher.GetOpenedViewModels(NavigationType.Page).ToList();
                    var viewModels           = openedViewModels
                                               .Select(info => info.ViewModel)
                                               .Where(vm => vm.GetCurrentView <object>()?.GetType() == Target.GetType())
                                               .ToList();

                    var from = viewModels.IndexOf(newViewModel);
                    var to   = viewModels.IndexOf(oldViewModel);

                    if (from < 0 || to < 0)
                    {
                        return;
                    }

                    for (int i = to; i > from; i--)
                    {
                        var viewModel   = viewModels[i];
                        var currentView = viewModels[i - 1].GetCurrentView <object>();
                        if (currentView != null)
                        {
                            ToolkitServiceProvider.ViewManager.InitializeViewAsync(viewModel, currentView);
                            var activity = currentView as Activity;
                            if (activity != null)
                            {
                                var newIntent = new Intent(activity.Intent);
                                newIntent.PutExtra(NavigationService.IntentParameterKey, NavigationProvider.GenerateNavigationParameter(viewModel));
                                activity.Intent = newIntent;
                            }
                        }
                    }
                    var newParameter = intent.GetStringExtra(NavigationService.IntentParameterKey);
                    var oldParameter = Target.Intent.GetStringExtra(NavigationService.IntentParameterKey);
                    if (newParameter != null && !string.Equals(newParameter, oldParameter))
                    {
                        var newIntent = new Intent(Target.Intent);
                        newIntent.PutExtra(NavigationService.IntentParameterKey, newParameter);
                        Target.Intent = newIntent;
                    }
                    ToolkitServiceProvider.ViewManager.InitializeViewAsync(newViewModel, Target);

                    int freeIndex = -1;
                    for (int i = 0; i < openedViewModels.Count; i++)
                    {
                        var viewModelInfo = openedViewModels[i];
                        if (freeIndex == -1 && ReferenceEquals(viewModelInfo.ViewModel, newViewModel))
                        {
                            ++i;
                            freeIndex = i;
                            openedViewModels.Insert(i, null);
                            continue;
                        }
                        if (freeIndex != -1 && viewModelInfo.ViewModel.GetCurrentView <object>()?.GetType() == Target.GetType())
                        {
                            openedViewModels[freeIndex] = viewModelInfo;
                            openedViewModels[i]         = null;
                            freeIndex = i;
                        }
                    }
                    if (freeIndex != -1)
                    {
                        openedViewModels.RemoveAt(freeIndex);
                        navigationDispatcher.UpdateOpenedViewModels(NavigationType.Page, openedViewModels);
                    }
                }
            }
        }