/// <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); } }
/// <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); } }
protected virtual void SaveState() { if (_presenter == null && !_presenterActivated) { _presenter = ToolkitServiceProvider.Get <IViewModelPresenter>() as IRestorableViewModelPresenter; _presenterActivated = true; } _presenter?.SaveState(); }
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); } }
protected T Get <T>() { var viewModel = DataContext as IViewModel; if (viewModel == null) { return(ToolkitServiceProvider.Get <T>()); } return(viewModel.GetIocContainer(true).Get <T>()); }
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); }
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; }
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>(); } }
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); }
protected virtual INavigationService CreateNavigationService(Frame frame) { return(new FrameNavigationService(frame, ToolkitServiceProvider.Get <IViewModelProvider>())); }
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); } } } }