/// <summary> /// /// </summary> /// <param name="parameters"></param> /// <param name="updateStack"></param> /// <param name="postProcess"></param> private void DoInternalNavigate(IViewParameters parameters, Func <bool> updateStack, Action <object> postProcess) { // プラグインコンテキスト var pluginContext = new ForwadingPluginContext(); // 遷移元画面遷移イベント ViewForwardFrom(CurrentView, pluginContext); // 前状態 var previousViewId = CurrentViewId; var previousView = CurrentView; // スタック更新 var restore = updateStack(); // イベント var args = new ViewForwardEventArgs(CurrentViewId, previousViewId, previousView, parameters ?? EmptyParameters, restore); // ナビゲーターイベント if (Forwarding != null) { Forwarding(this, args); } // 遷移先画面遷移イベント ViewForwardTo(CurrentView, args, CurrentRestoreParameter, pluginContext); // 復帰情報クリア CurrentRestoreParameter = null; // 後処理 postProcess(previousView); }
/// <summary> /// /// </summary> /// <param name="level"></param> /// <param name="parameters"></param> private void InternalPop(int level, IViewParameters parameters) { if ((level < 1) || (level > stacked.Count - 1)) { throw new ArgumentOutOfRangeException("level"); } if (!ConfirmNavigate(true)) { return; } InternalNavigate(parameters, () => { // 前画面破棄 ViewClose(CurrentView); // 中間スタック破棄 for (var i = stacked.Count - 2; i >= stacked.Count - level; i--) { ViewClose(stacked[i].View); DisposeView(stacked[i].View); } stacked.RemoveRange(stacked.Count - level, level); return(true); }, DisposeView); }
/// <summary> /// /// </summary> /// <param name="id"></param> /// <param name="parameters"></param> private void InternalForward(object id, IViewParameters parameters) { if (!ConfirmNavigate(true)) { return; } ViewInfo info; if (!idToViewType.TryGetValue(id, out info)) { return; } InternalNavigate(parameters, () => { // 前画面破棄 ViewClose(CurrentView); if (CurrentView != null) { stacked.RemoveAt(stacked.Count - 1); } // 新規スタック stacked.Add(new StackInfo(info, CreateView(info.Type))); return(false); }, DisposeView); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="viewId">遷移先ビューID</param> /// <param name="previousViewId">遷移元ビューID</param> /// <param name="previousView">遷移もとビューインスタンス</param> /// <param name="parameters">パラメータ</param> /// <param name="isRestore">復帰遷移判定</param> public ViewForwardEventArgs(object viewId, object previousViewId, object previousView, IViewParameters parameters, bool isRestore) { ViewId = viewId; PreviousViewId = previousViewId; PreviousView = previousView; Parameters = parameters; IsRestore = isRestore; }
/// <summary> /// /// </summary> /// <param name="id"></param> /// <param name="parameters"></param> private void InternalPush(object id, IViewParameters parameters) { if (!ConfirmNavigate(false)) { return; } ViewInfo info; if (!idToViewType.TryGetValue(id, out info)) { return; } // グループ判定 var exist = false; var first = -1; var last = -1; if ((info.Domain != null) && !Equals(CurrentViewDomain, info.Domain)) { first = stacked.FindIndex(x => Equals(x.ViewInfo.Domain, info.Domain)); if (first >= 0) { last = stacked.FindLastIndex(x => Equals(x.ViewInfo.Domain, info.Domain)); exist = stacked.Skip(first).Take(last - first + 1).Any(x => Equals(x.ViewInfo.Id, info.Id)); } } InternalNavigate(parameters, () => { // 前画面デアクティブ CurrentRestoreParameter = ViewDeactive(CurrentView); if (first >= 0) { // スタック入れ替え var temp = new StackInfo[last - first + 1]; stacked.CopyTo(first, temp, 0, temp.Length); for (var i = 0; i < stacked.Count - last - 1; i++) { stacked[i + first] = stacked[i + last + 1]; } for (var i = 0; i < temp.Length; i++) { stacked[stacked.Count - temp.Length + i] = temp[i]; } } if (!exist) { // 新規スタック stacked.Add(new StackInfo(info, CreateView(info.Type))); } return(false); }, previousView => { }); }
/// <summary> /// /// </summary> /// <param name="parameters"></param> /// <param name="updateStack"></param> /// <param name="postProcess"></param> private void InternalNavigate(IViewParameters parameters, Func <bool> updateStack, Action <object> postProcess) { if (provider.IsAsync) { provider.BeginInvoke((Action)(() => DoInternalNavigate(parameters, updateStack, postProcess))); } else { DoInternalNavigate(parameters, updateStack, postProcess); } }
/// <summary> /// ビューへの通知 /// </summary> /// <param name="msg">メッセージ</param> /// <param name="parameters">パラメータ</param> /// <returns>通知正否</returns> public bool Notify(object msg, IViewParameters parameters) { var support = provider.ResolveEventTarget(CurrentView) as IViewNotifySupport; if (support == null) { return(false); } support.OnViewNotify(this, new ViewNotifyEventArgs(msg, parameters ?? EmptyParameters)); return(true); }
/// <summary> /// /// </summary> /// <param name="id"></param> /// <param name="level"></param> /// <param name="parameters"></param> private void InternalPopAndForward(object id, int level, IViewParameters parameters) { if ((level < 1) || (level > stacked.Count)) { throw new ArgumentOutOfRangeException("level"); } if (!ConfirmNavigate(true)) { return; } ViewInfo info; if (!idToViewType.TryGetValue(id, out info)) { return; } InternalNavigate(parameters, () => { // 前画面破棄 ViewClose(CurrentView); // 中間スタック破棄 for (var i = stacked.Count - 2; i >= stacked.Count - level; i--) { ViewClose(stacked[i].View); DisposeView(stacked[i].View); } stacked.RemoveRange(stacked.Count - level, level); // 新規スタック stacked.Add(new StackInfo(info, CreateView(info.Type))); return(false); }, DisposeView); }
/// <summary> /// スタック型画面遷移(ポップフォワード) /// </summary> /// <param name="id">画面ID</param> /// <param name="level">ポップ数</param> /// <param name="parameters">パラメータ</param> public void PopAndForward(object id, int level, IViewParameters parameters) { InternalPopAndForward(id, level, parameters); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="msg">メッセージ</param> /// <param name="paramters">パラメータ</param> public ViewNotifyEventArgs(object msg, IViewParameters paramters) { Msg = msg; Paramters = paramters; }
/// <summary> /// スタック型画面遷移(ポップ) /// </summary> /// <param name="level">ポップ数</param> /// <param name="parameters">パラメータ</param> public void Pop(int level, IViewParameters parameters) { InternalPop(level, parameters); }
/// <summary> /// スタック型画面遷移(ポップ) /// </summary> /// <param name="parameters">パラメータ</param> public void Pop(IViewParameters parameters) { InternalPop(1, parameters); }
/// <summary> /// スタック型画面遷移(プッシュ) /// </summary> /// <param name="id">画面ID</param> /// <param name="parameters">パラメータ</param> public void Push(object id, IViewParameters parameters) { InternalPush(id, parameters); }
/// <summary> /// 画面遷移 /// </summary> /// <param name="id">画面ID</param> /// <param name="parameters">パラメータ</param> public void Forward(object id, IViewParameters parameters) { InternalForward(id, parameters); }
/// <summary> /// スタック型画面遷移(ポップフォワード) /// </summary> /// <param name="id">画面ID</param> /// <param name="parameters">パラメータ</param> public void PopAndForward(object id, IViewParameters parameters) { InternalPopAndForward(id, stacked.Count, parameters); }