// Token: 0x06002A5E RID: 10846 RVA: 0x000C25A0 File Offset: 0x000C07A0 internal void _AddEventHandler(Delegate d) { PageFunctionBase pageFunctionBase = d.Target as PageFunctionBase; if (pageFunctionBase != null) { this.ParentPageFunctionId = pageFunctionBase.PageFunctionId; } this._returnHandler = Delegate.Combine(this._returnHandler, d); }
// Token: 0x06002A7A RID: 10874 RVA: 0x000C2724 File Offset: 0x000C0924 internal void RaiseTypedReturnEvent(PageFunctionBase b, RaiseTypedEventArgs args) { Delegate d = args.D; object o = args.O; if (d != null) { ReturnEventArgs <T> e = o as ReturnEventArgs <T>; ReturnEventHandler <T> returnEventHandler = d as ReturnEventHandler <T>; returnEventHandler(this, e); } }
internal void _AddEventHandler(Delegate d) { // This is where the parent-child relationship is established. If // PageFunction A attaches one of its methods to PageFunction B's // Return event, then A must be B's parent. PageFunctionBase parent = d.Target as PageFunctionBase; if (parent != null) { ParentPageFunctionId = parent.PageFunctionId; } _returnHandler = Delegate.Combine(_returnHandler, d); }
///<summary> /// Used to raise a strongly typed return event. Sealed since nobody should have the need to override as /// all derived types of this generic type will automatically get the strongly typed version from this /// generic version. ///</summary> internal void RaiseTypedReturnEvent(PageFunctionBase b, RaiseTypedEventArgs args) { Delegate d = args.D; object returnEventArgs = args.O; if (d != null) { ReturnEventArgs <T> ra = returnEventArgs as ReturnEventArgs <T>; Debug.Assert((returnEventArgs == null) || (ra != null)); ReturnEventHandler <T> eh = d as ReturnEventHandler <T>; Debug.Assert(eh != null); eh(this, ra); } }
internal void _Detach(PageFunctionBase pf) { if (pf._Return != null && pf._Saver == null) { ReturnEventSaverInfo[] list = null; Delegate[] delegates = null; delegates = (pf._Return).GetInvocationList(); list = _returnList = new ReturnEventSaverInfo[delegates.Length]; for (int i = 0; i < delegates.Length; i++) { Delegate returnDelegate = delegates[i]; bool bSamePf = false; if (returnDelegate.Target == pf) { // This is the Event Handler implemented by the same PF, use for NonGeneric handling. bSamePf = true; } MethodInfo m = returnDelegate.Method; ReturnEventSaverInfo info = new ReturnEventSaverInfo( returnDelegate.GetType().AssemblyQualifiedName, returnDelegate.Target.GetType().AssemblyQualifiedName, m.Name, bSamePf); list[i] = info; } // // only save if there were delegates already attached. // note that there will be cases where the Saver has already been pre-populated from a Load // but no delegates have been created yet ( as the PF hasn`t called finish as yet) // // By only storing the saver once there are delegates - we avoid the problem of // wiping out any newly restored saver pf._Saver = this; } pf._DetachEvents(); }
// Ctors ///////////////////////////////////////////////////////////////////// #region Ctors internal JournalEntryPageFunctionKeepAlive(JournalEntryGroupState jeGroupState, PageFunctionBase pageFunction) : base(jeGroupState, pageFunction) { Debug.Assert(pageFunction != null && pageFunction.KeepAlive); this._keepAlivePageFunction = pageFunction; }
// // This method is to get the journal entry index in the Journal List for the parent page // of this PageFunction. // // The parent page could be a PageFunction or a Non-PageFunction. // For the non PageFunction case, it could have a Uri or could not have a Uri. // // Case 1: The ParentPageFunction has been set, so just go back and look for it. // Case 2: The ParentPageFunction has NOT been set, so the parent must be most recent non-PF entry. // internal static int GetParentPageJournalIndex(NavigationService NavigationService, Journal journal, PageFunctionBase endingPF) { JournalEntryPageFunction pageFunctionEntry; JournalEntry journalEntry; for (int index = journal.CurrentIndex - 1; index >= 0; --index) { journalEntry = journal[index]; // Be sure that the navigation containers match if (journalEntry.NavigationServiceId != NavigationService.GuidId) continue; pageFunctionEntry = journalEntry as JournalEntryPageFunction; if (endingPF.ParentPageFunctionId == Guid.Empty) { // We are looking for a non-PageFunction if (pageFunctionEntry == null) { return index; // found! } } else { // we are looking for a PageFunction if ((pageFunctionEntry != null) && (pageFunctionEntry.PageFunctionId == endingPF.ParentPageFunctionId)) { return index; // found! } } } Debug.Assert(endingPF.ParentPageFunctionId == Guid.Empty, "Should have been able to find the parent if the ParentPageFunctionId was set. Are they in different NavigationServices? They shouldn't be."); return _NoParentPage; }
// Ctors ///////////////////////////////////////////////////////////////////// #region Ctors internal JournalEntryPageFunction(JournalEntryGroupState jeGroupState, PageFunctionBase pageFunction) : base(jeGroupState, null) { PageFunctionId = pageFunction.PageFunctionId; ParentPageFunctionId = pageFunction.ParentPageFunctionId; }
internal PageFunctionReturnInfo(PageFunctionBase finishingChildPageFunction, Uri source, NavigationMode navigationMode, JournalEntry journalEntry, object returnEventArgs) : base(source, navigationMode, journalEntry) { _returnEventArgs = returnEventArgs; _finishingChildPageFunction = finishingChildPageFunction; }
// Navigate to the Parent page. // Two cases: // Parent is a PageFunction: parentPF is not null. // Parent is a Non PageFunction: parentPF is null, // the valid info are parentIndex and ReturnEventArgs. // The kind of navigation depends on finishingChildPageFunction.RemoveFromJournal: // - True: then do journal navigation to the parent page (and no journal entry created // for the finishing PF) // - False: do new navigation to the parent page. private void NavigateToParentPage(PageFunctionBase finishingChildPageFunction, PageFunctionBase parentPF, object returnEventArgs, int parentIndex) { JournalEntry parentEntry = (JournalScope.Journal)[parentIndex]; if (parentPF != null) { // We shouldn't be navigating to a PageFunction that's UiLess at this stage. // By now it should have started another navigation it was delegating to a child PF. if (parentEntry.EntryType == JournalEntryType.UiLess) throw new InvalidOperationException(SR.Get(SRID.UiLessPageFunctionNotCallingOnReturn)); NavigateInfo navInfo = finishingChildPageFunction.RemoveFromJournal ? new NavigateInfo(parentEntry.Source, NavigationMode.Back, parentEntry) : new NavigateInfo(parentEntry.Source, NavigationMode.New); Navigate(parentPF, navInfo); return; } // Handle the NonPF parent page case. // Passing PageFunctionReturnInfo signals that the Return event should be raised for // the finishing child PF. PageFunctionReturnInfo pfRetInfo = finishingChildPageFunction.RemoveFromJournal ? new PageFunctionReturnInfo(finishingChildPageFunction, parentEntry.Source, NavigationMode.Back, parentEntry, returnEventArgs) : new PageFunctionReturnInfo(finishingChildPageFunction, parentEntry.Source, NavigationMode.New, null, returnEventArgs); if (parentEntry is JournalEntryUri) { this.Navigate(parentEntry.Source, pfRetInfo); } else if (parentEntry is JournalEntryKeepAlive) { object root = ((JournalEntryKeepAlive)parentEntry).KeepAliveRoot; this.Navigate(root, pfRetInfo); } else { Debug.Fail("Unhandled scenario: PageFunction returning to " + parentEntry.GetType().Name); } }
private void InitializeComponent(PageFunctionBase pageFunction) { // Need to explicitly add a call to InitializeComponent() for Page IComponentConnector iComponentConnector = pageFunction as IComponentConnector; if (iComponentConnector != null) { iComponentConnector.InitializeComponent(); } }
private void HandleFinish(PageFunctionBase endingPF, object ReturnEventArgs) { if (EventTrace.IsEnabled(EventTrace.Keyword.KeywordHosting, EventTrace.Level.Info)) { EventTrace.EventProvider.TraceEvent( EventTrace.Event.Wpf_NavigationPageFunctionReturn, EventTrace.Keyword.KeywordHosting, EventTrace.Level.Info, endingPF.ToString()); } // Debug.Assert(_navigateQueueItem == null, "There's a navigation pending - see kusumav for details"); // NOTE: It is not always that endingPF==_bp. A PF may end itself when its child ends. Then // HandleFinish() will be called for the grandparent PF while _bp is still the child PF. if (JournalScope == null) { throw new InvalidOperationException(SR.Get(SRID.WindowAlreadyClosed)); } Journal journal = JournalScope.Journal; PageFunctionBase parentPF = null; int parentIndex = JournalEntryPageFunction.GetParentPageJournalIndex(this, journal, endingPF); if (endingPF.RemoveFromJournal) { DoRemoveFromJournal(endingPF, parentIndex); } // If the parent page is a PF, resume it and let it know the child PF returned. // If it's not a PF, the Return event will be raised later on - see NavigateToParentPage(). if (parentIndex != _noParentPage) { JournalEntryPageFunction parentPfEntry = journal[parentIndex] as JournalEntryPageFunction; if (parentPfEntry != null) { parentPF = parentPfEntry.ResumePageFunction(); // Need to set the FinishHandler here because the PF's Return event handler // may decide to call OnReturn(). parentPF.FinishHandler = this.FinishHandler; FireChildPageFunctionReturnEvent(parentPF, endingPF, ReturnEventArgs); } } // if the parent requested a new child, don't navigate to the parent // if (_navigateQueueItem == null) { // Navigate to the Parent page. // Two cases: // Parent is a PageFunction: bParentIsPF is true, parentPF is not null. // Parent is a Non PageFunction: bParentIsPF is false, parentPF is null, // the valid info are parentIndex and ReturnEventArgs. // There may have been recursive calls into HandleFinish(). As we are unwinding here, // parentIndex may point to a journal entry that was already removed. If the parent PF // started a navigation (new or to its parent), we'd be in the 'else' case. But if that // navigation was canceled, _navigateQueueItem==null. One special case in which this // happens is when the entire "wizard" window is closed. Then NS is disposed. if (parentIndex != _noParentPage && parentIndex < journal.TotalCount && !IsDisposed) { NavigateToParentPage(endingPF, parentPF, ReturnEventArgs, parentIndex); } // } else { // The parent requested a navigation(usually to another child PF but could be a regular Xaml) // Update the parent's state in the journal // Special case: the parent PF has the RemoveFromJournal flag, and it returned to its parent. // Then parentIndex is not valid anymore. if (parentIndex < journal.TotalCount) { JournalEntryPageFunction entry = (JournalEntryPageFunction)journal[parentIndex]; entry.SaveState(parentPF); } // Return event handler should not be left attached. Debug.Assert(parentPF._Return == null); parentPF.FinishHandler = null; } }
internal void _Attach(Object caller, PageFunctionBase child) { ReturnEventSaverInfo[] list = null; list = _returnList; if (list != null) { Debug.Assert(caller != null, "Caller should not be null"); for (int i = 0; i < list.Length; i++) { // // if (string.Compare(_returnList[i]._targetTypeName, caller.GetType().AssemblyQualifiedName, StringComparison.Ordinal) != 0) { throw new NotSupportedException(SR.Get(SRID.ReturnEventHandlerMustBeOnParentPage)); } Delegate d; try { new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Assert(); // BlessedAssert d = Delegate.CreateDelegate( Type.GetType(_returnList[i]._delegateTypeName), caller, _returnList[i]._delegateMethodName); } catch (Exception ex) { throw new NotSupportedException(SR.Get(SRID.ReturnEventHandlerMustBeOnParentPage), ex); } finally { ReflectionPermission.RevertAssert(); } child._AddEventHandler(d); } } }
// Token: 0x060029FF RID: 10751 RVA: 0x000C1A81 File Offset: 0x000BFC81 internal PageFunctionReturnInfo(PageFunctionBase finishingChildPageFunction, Uri source, NavigationMode navigationMode, JournalEntry journalEntry, object returnEventArgs) : base(source, navigationMode, journalEntry) { this._returnEventArgs = returnEventArgs; this._finishingChildPageFunction = finishingChildPageFunction; }
// Ctors ///////////////////////////////////////////////////////////////////// #region Ctors // // Ctor of JournalEntryPageFunctionSaver // internal JournalEntryPageFunctionSaver(JournalEntryGroupState jeGroupState, PageFunctionBase pageFunction) : base(jeGroupState, pageFunction) { Debug.Assert(!pageFunction.KeepAlive); }
internal JournalEntryPageFunctionType(JournalEntryGroupState jeGroupState, PageFunctionBase pageFunction) : base(jeGroupState, pageFunction) { string typeName = pageFunction.GetType().AssemblyQualifiedName; this._typeName = new SecurityCriticalDataForSet<string>(typeName); }
// // This method will reattach the return handler to the parent page. // and then fire the return event on the child pagefunction. // private void FireChildPageFunctionReturnEvent(object parentElem, PageFunctionBase childPF, object ReturnEventArgs) { ReturnEventSaver saver = childPF._Saver; // get the endingPF's saved info if (saver != null) { saver._Attach(parentElem, childPF); // reattach the parent to the child // When the Return event handler is invoked on the parent element, the parent is not in the tree. // But developers need to access the NavigationService from the Return event handler (to be able to // start new navigation). To make this scenario straightforward, set the NavigationService property // before raising the Return event and clear it afterwards. See details of the scenario in Dev10 bug 451875. // Similar issue with Window.GetWindow()... Window window = null; DependencyObject dobj = parentElem as DependencyObject; if ((dobj != null) && (!dobj.IsSealed)) { dobj.SetValue(NavigationServiceProperty, this); var host = this.INavigatorHost as DependencyObject; if (host != null && (window = Window.GetWindow(host)) != null) { dobj.SetValue(Window.IWindowServiceProperty, window); } } // Event handler exception continuality: if exception occurs in Return event handler, we are going to stop loading // and stop at the child pagefunction and not returning to parent. try { childPF._OnFinish(ReturnEventArgs); // then call the endingPF to fire it's event } catch { DoStopLoading(true, false); throw; } finally { saver._Detach(childPF); // now detach the event handler since we're done if ((dobj != null) && (!dobj.IsSealed)) { dobj.ClearValue(NavigationServiceProperty); if (window != null) { dobj.ClearValue(Window.IWindowServiceProperty); } } } } }
// Ctors ///////////////////////////////////////////////////////////////////// #region Ctors internal JournalEntryPageFunctionUri(JournalEntryGroupState jeGroupState, PageFunctionBase pageFunction, Uri markupUri) : base(jeGroupState, pageFunction) { _markupUri = markupUri; }
/// <summary> /// Deletes everything in this NavigationService from the *first* instance of the /// finishing PageFunction on. /// </summary> private void DoRemoveFromJournal(PageFunctionBase finishingChildPageFunction, int parentEntryIndex/* = -1 */) { if (!finishingChildPageFunction.RemoveFromJournal) return; bool deleting = false; Journal journal = JournalScope.Journal; int journalEntryIndex = parentEntryIndex + 1; while (journalEntryIndex < journal.TotalCount) { if (!deleting) // we haven't found the first one yet { // is this the first one? JournalEntryPageFunction journalPageFunction = journal[journalEntryIndex] as JournalEntryPageFunction; deleting = (journalPageFunction != null) && (journalPageFunction.PageFunctionId == finishingChildPageFunction.PageFunctionId); } if (deleting) { journal.RemoveEntryInternal(journalEntryIndex); } else { journalEntryIndex++; } } if (deleting) { journal.UpdateView(); // RemoveEntryInternal() doesn't do this. } else { // If the PF is not found, it simply wasn't journaled, and it must be the // current page. if (object.ReferenceEquals(_bp, finishingChildPageFunction)) { Debug.Assert(parentEntryIndex < journal.CurrentIndex); journal.ClearForwardStack(); } else { Debug.Fail("Could not find the finishing PageFunction in the journal."); } } // When the next navigation occurs (back to parent or new), the current page // (finishingChildPageFunction or another PF started by it) should not be journaled. _doNotJournalCurrentContent = true; }