private void RegisterPage(Guid storyboardId, [NotNull] StoryboardPageInfo pageInfo) { if (pageInfo == null) { throw new ArgumentNullException(nameof(pageInfo)); } if (pageInfo.View == null) { throw new ArgumentException($"{nameof(pageInfo.View)} is null"); } if (pageInfo.ViewModel == null) { throw new ArgumentException($"{nameof(pageInfo.ViewModel)} is null"); } var pageInstanceInfo = new InnerStoryboardPageInfo { IsStartPage = pageInfo.IsStartPage, PageId = pageInfo.PageId, StoryboardId = storyboardId, PageUniqueId = Guid.NewGuid() }; var creationInfo = new PageCreationInfo { ViewModel = pageInfo.ViewModel, View = pageInfo.View }; RegisteredPages[pageInstanceInfo] = creationInfo; }
protected virtual async Task RemovePageAsync(InnerStoryboardPageInfo pageInfo, Storyboard storyboard) { Journal.Remove(pageInfo); //start pages always in memory if (CachedPages.ContainsKey(pageInfo.PageUniqueId) && !pageInfo.IsStartPage) { CachedPages.Remove(pageInfo.PageUniqueId); if (storyboard?.ActivePage != null) { var previousPage = storyboard.ActivePage; var viewModel = previousPage.ViewModel; // can close called early viewModel.PageBackRequested -= ViewModelOnPageBackRequested; viewModel.PageCanceled -= ViewModelOnPageCanceled; viewModel.PageCompleted -= ViewModelOnPageCompleted; viewModel.PageTransitionRequested -= ViewModelOnPageTransitionRequested; await viewModel.CloseAsync().ConfigureAwait(true); storyboard.ActivePage = null; viewModel.Dispose(); } } if (PageContexts.ContainsKey(pageInfo.PageUniqueId)) { PageContexts.Remove(pageInfo.PageUniqueId); } //todo maybe add isShared flag? if (pageInfo.IsStartPage && StartPageContexts.ContainsKey(pageInfo.PageUniqueId)) { PageContexts[pageInfo.PageUniqueId] = StartPageContexts[pageInfo.PageUniqueId]; } }
private IStoryboardPageView CreatePageView([NotNull] InnerStoryboardPageInfo pageInfo) { if (!RegisteredPages.ContainsKey(pageInfo)) { throw new InvalidOperationException($"Page creation info with pageTypeId {pageInfo.PageId} not registered"); } var pageCreationInfo = RegisteredPages[pageInfo]; var view = PageCreator.CreateView(pageCreationInfo.View); var viewModel = PageCreator.CreateViewModel(pageCreationInfo.ViewModel); viewModel.PageId = pageInfo.PageId; viewModel.StoryboardId = pageInfo.StoryboardId; viewModel.PageBackRequested += ViewModelOnPageBackRequested; viewModel.PageCanceled += ViewModelOnPageCanceled; viewModel.PageCompleted += ViewModelOnPageCompleted; viewModel.PageTransitionRequested += ViewModelOnPageTransitionRequested; view.ViewModel = viewModel; CachedPages.Add(pageInfo.PageUniqueId, view); return(view); }
protected virtual async Task <TransitionResult> OpenPageAsync( [NotNull] InnerStoryboardPageInfo pageInfo, [CanBeNull] IStoryboardPageContext pageContext = null, bool addToJournal = true) { if (!Storyboards.ContainsKey(pageInfo.StoryboardId)) { throw new InvalidOperationException($"Storyboard {pageInfo.StoryboardId} does not registered"); } var tcs = new TaskCompletionSource <TransitionResult>(); await Invoker.InvokeAsync(async() => { try { var storyboard = Storyboards[pageInfo.StoryboardId]; if (ActiveStoryboard?.ActivePage != null) { var previousPage = ActiveStoryboard.ActivePage; var viewModel = previousPage.ViewModel; var canLeave = await viewModel.CanLeaveAsync().ConfigureAwait(true); if (!canLeave) { tcs.SetResult(TransitionResult.CanceledByUser); return; } await viewModel.LeaveAsync().ConfigureAwait(true); } var storyboardsWasChanged = ActiveStoryboard == null || ActiveStoryboard.StoryboardId != storyboard.StoryboardId; ActiveInnerStoryboardPageInfo = pageInfo; ActiveStoryboard = storyboard; if (storyboardsWasChanged) { ActiveStoryboardChanged?.Invoke(this, pageInfo.StoryboardId); } if (CachedPages.ContainsKey(pageInfo.PageUniqueId)) { var page = CachedPages[pageInfo.PageUniqueId]; storyboard.ActivePage = page; PageContexts.TryGetValue(pageInfo.PageUniqueId, out var restoredPageContext); StartPagesOpenningStat.TryGetValue(pageInfo.PageUniqueId, out var wasPageOpenned); if (wasPageOpenned) { await page.ViewModel.ReturnAsync(pageContext ?? restoredPageContext).ConfigureAwait(true); } else { await page.ViewModel.OpenAsync(pageContext ?? restoredPageContext).ConfigureAwait(true); StartPagesOpenningStat[pageInfo.PageUniqueId] = true; } } else { var view = CreatePageView(pageInfo); storyboard.ActivePage = view; await view.ViewModel.OpenAsync(pageContext).ConfigureAwait(true); PageContexts[pageInfo.PageUniqueId] = pageContext; } if (addToJournal) { Journal.AddLast(pageInfo); } tcs.SetResult(TransitionResult.Completed); CanBackChanged?.Invoke(this, EventArgs.Empty); } catch (Exception e) { ExceptionOccured?.Invoke(this, e); tcs.SetResult(TransitionResult.Failed); } }).ConfigureAwait(false); return(await tcs.Task.ConfigureAwait(false)); }