/// <summary> /// Disassociates a <see cref="Frame"/> previously registered by <see cref="RegisterFrame"/> /// from <see cref="SessionState"/>. Any navigation state previously captured will be /// removed. /// </summary> /// <param name="frame">An instance whose navigation history should no longer be /// managed.</param> public static void UnregisterFrame(Frame frame) { // Remove session state and remove the frame from the list of frames whose navigation // state will be saved (along with any weak references that are no longer reachable) SessionState.Remove((String)frame.GetValue(FrameSessionStateKeyProperty)); _registeredFrames.RemoveAll((weakFrameReference) => { Frame testFrame; return !weakFrameReference.TryGetTarget(out testFrame) || testFrame == frame; }); }
/// <summary> /// Provides storage for session state associated with the specified <see cref="Frame"/>. /// Frames that have been previously registered with <see cref="RegisterFrame"/> have /// their session state saved and restored automatically as a part of the global /// <see cref="SessionState"/>. Frames that are not registered have transient state /// that can still be useful when restoring pages that have been discarded from the /// navigation cache. /// </summary> /// <remarks>Apps may choose to rely on <see cref="LayoutAwarePage"/> to manage /// page-specific state instead of working with frame session state directly.</remarks> /// <param name="frame">The instance for which session state is desired.</param> /// <returns>A collection of state subject to the same serialization mechanism as /// <see cref="SessionState"/>.</returns> public static Dictionary<String, Object> SessionStateForFrame(Frame frame) { var frameState = (Dictionary<String, Object>)frame.GetValue(FrameSessionStateProperty); if (frameState == null) { var frameSessionKey = (String)frame.GetValue(FrameSessionStateKeyProperty); if (frameSessionKey != null) { // Registered frames reflect the corresponding session state if (!_sessionState.ContainsKey(frameSessionKey)) { _sessionState[frameSessionKey] = new Dictionary<String, Object>(); } frameState = (Dictionary<String, Object>)_sessionState[frameSessionKey]; } else { // Frames that aren't registered have transient state frameState = new Dictionary<String, Object>(); } frame.SetValue(FrameSessionStateProperty, frameState); } return frameState; }
/// <summary> /// Registers a <see cref="Frame"/> instance to allow its navigation history to be saved to /// and restored from <see cref="SessionState"/>. Frames should be registered once /// immediately after creation if they will participate in session state management. Upon /// registration if state has already been restored for the specified key /// the navigation history will immediately be restored. Subsequent invocations of /// <see cref="RestoreAsync"/> will also restore navigation history. /// </summary> /// <param name="frame">An instance whose navigation history should be managed by /// <see cref="SuspensionManager"/></param> /// <param name="sessionStateKey">A unique key into <see cref="SessionState"/> used to /// store navigation-related information.</param> public static void RegisterFrame(Frame frame, String sessionStateKey) { if (frame.GetValue(FrameSessionStateKeyProperty) != null) { throw new InvalidOperationException("Frames can only be registered to one session state key"); } if (frame.GetValue(FrameSessionStateProperty) != null) { throw new InvalidOperationException("Frames must be either be registered before accessing frame session state, or not registered at all"); } // Use a dependency property to associate the session key with a frame, and keep a list of frames whose // navigation state should be managed frame.SetValue(FrameSessionStateKeyProperty, sessionStateKey); _registeredFrames.Add(new WeakReference<Frame>(frame)); // Check to see if navigation state can be restored RestoreFrameNavigationState(frame); }