Frame.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / Frame.cs / 1305600 / Frame.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: 
//      Frame is a ContentControl with navigation and journaling capabilities, much like NavigationWindow. 
//      It can use its own journal ("island frame") or its prent's, if available.
// 
// History:
//  ??        ??            Created
//  11/14/05: [....]       "Island Frame" implementation: Frame can have its own Journal/JournalNavigationScope.
// 
//---------------------------------------------------------------------------
 
using System; 
using System.Net;
using System.Collections; 
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Windows.Threading; 
using System.Security;
 
using System.Windows; 
using System.Windows.Input;
using System.Windows.Automation.Peers; 
using System.Windows.Media;
using System.Windows.Navigation;
using System.Windows.Markup;
 
using MS.Internal;
using MS.Internal.AppModel; 
using MS.Internal.Utility; 
using MS.Internal.KnownBoxes;
using MS.Utility; 
using MS.Internal.Controls;
using System.Collections.Generic;

using SecurityHelper=MS.Internal.PresentationFramework.SecurityHelper; 

 
namespace System.Windows.Navigation 
{
    ///  
    /// Journaling options for Frame
    /// 
    [Serializable]
    public enum JournalOwnership 
    {
        ///  
        /// Whether or not this Frame will create and use its own journal depends on its parent. 
        /// If the Frame is hosted by another Frame or a NavigationWindow, it behaves as though
        /// UseParentJournal was set. If it is not hosted by a Frame or NavigationWindow or all 
        /// containing frames have the UsesParentJournal setting, this frame will use its own journal.
        /// Once a frame creates its own journal, switching to Automatic has no effect.
        /// 
        Automatic = 0, 

        ///  
        /// The Frame has its own Journal which operates independent of the hosting container’s 
        /// journal (if it has one).
        ///  
        OwnsJournal,

        /// 
        /// The Frame’s journal entries are merged into the hosting container’s journal, if available. 
        /// Otherwise navigations in this frame are not journaled.
        ///  
        UsesParentJournal 
    };
 
    /// 
    /// 
    public enum NavigationUIVisibility
    { 
        /// 
        /// The navigation UI is visible when Frame has its own journal. 
        ///  
        Automatic = 0,
        ///  
        /// 
        Visible,
        /// 
        ///  
        Hidden
    }; 
} 

namespace System.Windows.Controls 
{
    /// 
    /// Frame control is an area that is used for loading a tree of elements.
    /// It uses the application navigation model to populate its content. 
    /// Hence its content model is dictated solely by the NavigationService it aggregates which has
    /// a Uri property that points to the Uri of the page that is to be loaded into the Frame. 
    /// There is also a Content property that returns the root element of the Framework tree being loaded from the Uri. 
    /// It is also possible to create a tree for the Frames content programmatically and set the Content property to it.
    ///  
    [DefaultProperty("Source"), DefaultEvent("Navigated")]
    [Localizability(LocalizationCategory.Ignore)]
#if OLD_AUTOMATION
    [Automation(AccessibilityControlType = "Window")] 
#endif
    [ContentProperty] 
    [TemplatePart(Name = "PART_FrameCP", Type = typeof(ContentPresenter))] 
    public class Frame : ContentControl, INavigator, INavigatorImpl, IJournalNavigationScopeHost, IDownloader, IJournalState, IAddChild, IUriContext
    { 

        #region Constructors

        ///  
        ///     Default constructor
        ///  
        ///  
        ///     Automatic determination of current Dispatcher. Use alternative constructor
        ///     that accepts a Dispatcher for best performance. 
        /// 
        public Frame() : base()
        {
            Init(); 
        }
 
        static Frame() 
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Frame), new FrameworkPropertyMetadata(typeof(Frame))); 
            _dType = DependencyObjectType.FromSystemTypeInternal(typeof(Frame));

            ContentProperty.OverrideMetadata(
                    typeof(Frame), 
                    new FrameworkPropertyMetadata(
                            null, 
                            new CoerceValueCallback(CoerceContent))); 

            KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(Frame), new FrameworkPropertyMetadata(KeyboardNavigationMode.Local)); 
            KeyboardNavigation.ControlTabNavigationProperty.OverrideMetadata(typeof(Frame), new FrameworkPropertyMetadata(KeyboardNavigationMode.Once));

            NavigationService.NavigationServiceProperty.OverrideMetadata(
                    typeof(Frame), 
                    new FrameworkPropertyMetadata(new PropertyChangedCallback(OnParentNavigationServiceChanged)));
        } 
 
        private static object CoerceContent(DependencyObject d, object value)
        { 
            // whenever content changes, defer the change until the Navigate comes in
            Frame f = (Frame) d;

            if (f._navigationService.Content == value) 
            {
                return value; 
            } 

            f.Navigate(value); 
            return DependencyProperty.UnsetValue;
        }

        ///  
        /// Initialize
        ///  
        private void Init() 
        {
            InheritanceBehavior = InheritanceBehavior.SkipToAppNow; 
            ContentIsNotLogical = true;
            _navigationService = new NavigationService(this);
            _navigationService.BPReady += new BPReadyEventHandler(_OnBPReady);
        } 

        #endregion 
 
        #region IUriContext implementation
        ///  
        ///     Accessor for the base uri of the frame
        /// 
        Uri IUriContext.BaseUri
        { 
            get
            { 
                return  BaseUri; 
            }
            set 
            {
                BaseUri = value;
            }
        } 

        ///  
        ///    Implementation for BaseUri 
        /// 
        protected virtual Uri BaseUri 
        {
            get
            {
                return (Uri)GetValue(BaseUriHelper.BaseUriProperty); 
            }
            set 
            { 
                SetValue(BaseUriHelper.BaseUriProperty, value);
            } 
        }

        #endregion IUriContext implementation
 
        #region IDownloader implementation
        NavigationService IDownloader.Downloader 
        { 
            get { return _navigationService; }
        } 

        /// 
        ///     Rasied when Content is rendered and ready for user interaction.
        ///  
        public event EventHandler ContentRendered;
 
        ///  
        ///     This override fires the ContentRendered event.
        ///  
        /// 
        protected virtual void OnContentRendered(EventArgs args)
        {
            // After the content is rendered we want to check if there is an element that needs to be focused 
            // If there is - set focus to it
            DependencyObject doContent = Content as DependencyObject; 
            if (doContent != null) 
            {
                IInputElement focusedElement = FocusManager.GetFocusedElement(doContent) as IInputElement; 
                if (focusedElement != null)
                    focusedElement.Focus();
            }
 
            if (ContentRendered != null)
            { 
                ContentRendered(this, args); 
            }
        } 
        #endregion IDownloader implementation

        #region Properties
        ///  
        ///
        ///  
        public static readonly DependencyProperty SourceProperty = 
                DependencyProperty.Register(
                        "Source", 
                        typeof(Uri),
                        typeof(Frame),
                        new FrameworkPropertyMetadata(
                                (Uri) null, 
                                // The Journal flag tells the parser not to re-assign the property
                                // when doing journal navigation. See ParserContext.SkipJournaledProperties. 
                                FrameworkPropertyMetadataOptions.Journal, 
                                new PropertyChangedCallback(OnSourcePropertyChanged),
                                new CoerceValueCallback(CoerceSource))); 

        private static object CoerceSource(DependencyObject d, object value)
        {
            Frame frame = (Frame)d; 

            // If the Source property is coerced from NavService as a result of navigation, not from other 
            // source, e.g, SetValue, DataBinding, Style..., we should use NavService.Source. 
            if (frame._sourceUpdatedFromNavService)
            { 
                Invariant.Assert(frame._navigationService != null, "_navigationService should never be null here");
                // Turn this Assert on after fix the issue that NavService.Source is not absolute for SiteOfOrigin.
                //Invariant.Assert(frame._navigationService.Source != null ? !frame._navigationService.Source.IsAbsoluteUri : true, "NavService's Source should always be relative");
                return frame._navigationService.Source; 
            }
 
            return value; 
        }
 
        /// 
        ///    Called when SourceProperty is invalidated on 'd'
        /// 
        /// 
        /// Critical as it access the base uri through GetUriToNavigate
        /// TreatAsSafe since it does not disclose this 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private static void OnSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            Frame frame = (Frame)d;

            // Don't navigate if the Source value change is from NavService as a result of a navigation happening. 
            if (! frame._sourceUpdatedFromNavService)
            { 
                // We used to unhook first visual child here. 
                // Since we enabled styling for Frame. We're relying on Content property and ContentPresenter in Frame's style
                // to add/remove content from VisualTree. 
                Uri uriToNavigate = BindUriHelper.GetUriToNavigate(frame, ((IUriContext)frame).BaseUri, (Uri)e.NewValue);

                // Calling the internal Navigate from Frame and NavWin's Source DP's property changed callbacks
                // We would not set value back in this case. 
                frame._navigationService.Navigate(uriToNavigate, null, false, true/* navigateOnSourceChanged */);
            } 
        } 

        // This method is called from NavService whenever the NavService's Source value is updated. 
        // The INavigator uses this to update its SourceProperty.
        // It indicates whether the NavService's Source value is as a result of
        // calling Navigate API directly or from GoBack/GoForward, journal navigation, a cancellation
        void INavigatorImpl.OnSourceUpdatedFromNavService(bool journalOrCancel) 
        {
            try 
            { 
                _sourceUpdatedFromNavService = true;
                SetCurrentValueInternal(SourceProperty, _navigationService.Source); 
            }
            finally
            {
                _sourceUpdatedFromNavService = false; 
            }
        } 
 
        /// 
        /// URI to navigate to. 
        /// 
        [Bindable(true), CustomCategory("Navigation")]
        public Uri Source
        { 
            get { return (Uri) GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); } 
        } 

        ///  
        ///     The DependencyProperty for the CanGoBack property.
        ///     Flags:              None
        ///     Default Value:      false
        ///     Readonly:           true 
        /// 
        public static readonly DependencyProperty CanGoBackProperty = 
            JournalNavigationScope.CanGoBackProperty.AddOwner(typeof(Frame)); 

        ///  
        ///     The DependencyProperty for the CanGoForward property.
        ///     Flags:              None
        ///     Default Value:      false
        ///     Readonly:           true 
        /// 
        public static readonly DependencyProperty CanGoForwardProperty = 
            JournalNavigationScope.CanGoForwardProperty.AddOwner(typeof(Frame)); 

        ///  
        /// List of back journal entries. Available only when the frame owns its own journal.
        /// 
        public static readonly DependencyProperty BackStackProperty =
            JournalNavigationScope.BackStackProperty.AddOwner(typeof(Frame)); 

        ///  
        /// List of back journal entries. Available only when the frame owns its own journal. 
        /// 
        public static readonly DependencyProperty ForwardStackProperty = 
            JournalNavigationScope.ForwardStackProperty.AddOwner(typeof(Frame));

        /// 
        ///  
        public static readonly DependencyProperty NavigationUIVisibilityProperty =
            DependencyProperty.Register( 
                "NavigationUIVisibility", typeof(NavigationUIVisibility), typeof(Frame), 
                new PropertyMetadata(NavigationUIVisibility.Automatic));
 
        /// 
        /// 
        public NavigationUIVisibility NavigationUIVisibility
        { 
            get { return (NavigationUIVisibility)GetValue(NavigationUIVisibilityProperty); }
            set { SetValue(NavigationUIVisibilityProperty, value); } 
        } 

        ///  
        /// DependencyProperty for SandboxExternalContent property.
        /// 
        public static readonly DependencyProperty SandboxExternalContentProperty =
                DependencyProperty.Register( 
                        "SandboxExternalContent",
                        typeof(bool), 
                        typeof(Frame), 
                        new FrameworkPropertyMetadata(BooleanBoxes.FalseBox,
                                new PropertyChangedCallback(OnSandboxExternalContentPropertyChanged), new CoerceValueCallback(CoerceSandBoxExternalContentValue))); 

        /// 
        /// If set to true, the navigated content is isolated.
        ///  
        public bool SandboxExternalContent
        { 
            get { return (bool) GetValue(SandboxExternalContentProperty); } 
            set
            { 
                // This feature is disabled in partial trust due to a P3P violation
                bool fSandBox = (bool)value;
                SecurityHelper.ThrowExceptionIfSettingTrueInPartialTrust(ref fSandBox);
                SetValue(SandboxExternalContentProperty, fSandBox); 
            }
        } 
 
        /// 
        ///    Called when SandboxExternalContentProperty is invalidated on 'd'.  If the value becomes 
        ///    true, then the frame is refreshed to sandbox any content.
        /// 
        private static void OnSandboxExternalContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            Frame frame = (Frame)d;
            // we do not want an individual to be able to set this property to true 
            // in partial trust 
            // This feature is disabled in partial trust due to a P3P violation
            bool fSandBox = (bool)e.NewValue; 
            SecurityHelper.ThrowExceptionIfSettingTrueInPartialTrust(ref fSandBox);
            if (fSandBox && !(bool)e.OldValue)
            {
                frame.NavigationService.Refresh(); 
            }
        } 
 
        private static object CoerceSandBoxExternalContentValue(DependencyObject d, object value)
        { 
            // we do not want an individual to be able to set this property to true
            // in partial trust
            // This feature is disabled in partial trust due to a P3P violation
            bool fSandBox = (bool)value; 
            SecurityHelper.ThrowExceptionIfSettingTrueInPartialTrust(ref fSandBox);
            return fSandBox; 
        } 

        // 
        // JournalOwnership

        /// 
        /// DependencyProperty for the JournalOwnership property 
        /// 
        public static readonly DependencyProperty JournalOwnershipProperty = 
                DependencyProperty.Register( 
                    "JournalOwnership", typeof(JournalOwnership), typeof(Frame),
                    new FrameworkPropertyMetadata( 
                        JournalOwnership.Automatic,
                        new PropertyChangedCallback(OnJournalOwnershipPropertyChanged),
                        new CoerceValueCallback(CoerceJournalOwnership)),
                    new ValidateValueCallback(ValidateJournalOwnershipValue)); 

        private static bool ValidateJournalOwnershipValue(object value) 
        { 
            JournalOwnership jo = (JournalOwnership)value;
            return jo == JournalOwnership.Automatic || jo == JournalOwnership.UsesParentJournal 
                || jo == JournalOwnership.OwnsJournal;
        }

        private static void OnJournalOwnershipPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            ((Frame)d).OnJournalOwnershipPropertyChanged((JournalOwnership)e.NewValue); 
        } 

        private void OnJournalOwnershipPropertyChanged(JournalOwnership newValue) 
        {
            // NavigationService.InvalidateJournalNavigationScope() will be called (recursively)
            // when making an ownership change and will throw if there is a navigation in progress.
 
            switch (_journalOwnership/*previous value*/)
            { 
                case JournalOwnership.Automatic: 
                    switch (newValue)
                    { 
                        case JournalOwnership.OwnsJournal:
                            SwitchToOwnJournal();
                            break;
                        case JournalOwnership.UsesParentJournal: 
                            SwitchToParentJournal();
                            break; 
                    } 
                    break;
                case JournalOwnership.OwnsJournal: 
                    Debug.Assert(_ownJournalScope != null);
                    switch (newValue)
                    {
                        case JournalOwnership.Automatic: 
                            Debug.Fail("UsesOwnJournal->Automatic transition should be blocked by CoerceJournalOwnership().");
                            break; 
                        case JournalOwnership.UsesParentJournal: 
                            SwitchToParentJournal();
                            break; 
                    }
                    break;
                case JournalOwnership.UsesParentJournal:
                    Debug.Assert(_ownJournalScope == null); 
                    switch (newValue)
                    { 
                        case JournalOwnership.Automatic: 
                            // The effective journal ownership is not going to change unless the
                            // frame is reparented (or, more unlikely, the parent's journal becomes 
                            // unavailable). This invalidation is done only so that the next
                            // navigation causes a switch to UsesParentJournal, to be consistent
                            // with the initial transition from Automatic.
                            _navigationService.InvalidateJournalNavigationScope(); 
                            break;
                        case JournalOwnership.OwnsJournal: 
                            SwitchToOwnJournal(); 
                            break;
                    } 
                    break;
            }

            _journalOwnership = newValue; 
        }
 
        private static object CoerceJournalOwnership(DependencyObject d, object newValue) 
        {
            JournalOwnership prevValue = ((Frame)d)._journalOwnership; 
            // Switching from OwnsJournal to Automatic is not defined to have any useful effect.
            // (Even if reparented, Frame will not relinquish its own journal to start using its new
            // parent's one.) But in order to be able to maintain some stronger invariants, this transition
            // is blocked here. 
            if (prevValue == JournalOwnership.OwnsJournal && (JournalOwnership)newValue == JournalOwnership.Automatic)
            { 
                return JournalOwnership.OwnsJournal; 
            }
            return newValue; 
        }

        /// 
        /// Journal ownership setting for this frame 
        /// 
        public JournalOwnership JournalOwnership 
        { 
            get
            { 
                Debug.Assert(_journalOwnership == (JournalOwnership)GetValue(JournalOwnershipProperty));
                return _journalOwnership;
            }
            set 
            {
                if (value != _journalOwnership) 
                { 
                    SetValue(JournalOwnershipProperty, value);
                } 
            }
        }

        ///  
        /// Frame's associated NavigationService.
        ///  
        public NavigationService NavigationService 
        {
            get 
            {
                VerifyAccess();
                return _navigationService;
            } 
        }
 
        #endregion 

        //----------------------------------------------------- 
        //
        //  Protected Methods
        //
        //----------------------------------------------------- 
        #region Protected Methods
 
        ///  
        /// Creates AutomationPeer ()
        ///  
        protected override AutomationPeer OnCreateAutomationPeer()
        {
            return new FrameAutomationPeer(this);
        } 

        ///  
        ///  Add an object child to this control 
        /// 
        protected override void AddChild(object value) 
        {
            throw new InvalidOperationException(SR.Get(SRID.FrameNoAddChild));
        }
 
        /// 
        ///  Add a text string to this control 
        ///  
        protected override void AddText(string text)
        { 
            XamlSerializerUtil.ThrowIfNonWhiteSpaceInAddText(text, this);
        }
        #endregion
 
        #region Event Handlers
 
        private void _OnBPReady(Object o, BPReadyEventArgs e) 
        {
            // update content property 
            SetCurrentValueInternal(ContentProperty, e.Content);

            // Need to refresh everytime the child changed
            InvalidateMeasure(); 

            // We post a dispatcher work item to fire ContentRendered 
            // only if this is Loaded in the tree.  If not, we will 
            // post it from the LoadedHandler.  This guarantees that
            // we don't fire ContentRendered on a subtree that is not 
            // connected to a PresentationSource
            if (IsLoaded == true)
            {
                PostContentRendered(); 
            }
            else 
            { 
                // _postContentRenderedFromLoadedHandler == true means
                // that we deferred to the Loaded event to PostConetentRendered 
                // for the previous content change and Loaded has not fired yet.
                // Thus we don't want to hook up another event handler
                if (_postContentRenderedFromLoadedHandler == false)
                { 
                    this.Loaded += new RoutedEventHandler(LoadedHandler);
                    _postContentRenderedFromLoadedHandler = true; 
                } 
            }
        } 

        private void LoadedHandler(object sender, RoutedEventArgs args)
        {
            if (_postContentRenderedFromLoadedHandler == true) 
            {
                PostContentRendered(); 
                _postContentRenderedFromLoadedHandler = false; 
                this.Loaded -= new RoutedEventHandler(LoadedHandler);
            } 
        }

        ///  Keep this method in [....] with Window.PostContentRendered(). 
        private void PostContentRendered() 
        {
            // Post the firing of ContentRendered as Input priority work item so 
            // that ContentRendered will be fired after render query empties. 
            if (_contentRenderedCallback != null)
            { 
                // Content was changed again before the previous rendering completed (or at least
                // before the Dispatcher got to Input priority callbacks).
                _contentRenderedCallback.Abort();
            } 
            _contentRenderedCallback = Dispatcher.BeginInvoke(DispatcherPriority.Input,
                                   (DispatcherOperationCallback) delegate (object unused) 
                                   { 
                                       _contentRenderedCallback = null;
                                       OnContentRendered(EventArgs.Empty); 
                                       return null;
                                   },
                                   this);
        } 

        private void OnQueryGoBack(object sender, CanExecuteRoutedEventArgs e) 
        { 
            Debug.Assert(sender == this && _ownJournalScope != null);
            e.CanExecute = _ownJournalScope.CanGoBack; 
            e.Handled = true;
        }
        private void OnGoBack(object sender, ExecutedRoutedEventArgs e)
        { 
            Debug.Assert(sender == this && _ownJournalScope != null);
            _ownJournalScope.GoBack(); 
            e.Handled = true; 
        }
 
        private void OnQueryGoForward(object sender, CanExecuteRoutedEventArgs e)
        {
            Debug.Assert(sender == this && _ownJournalScope != null);
            e.CanExecute = _ownJournalScope.CanGoForward; 
            e.Handled = true;
        } 
        private void OnGoForward(object sender, ExecutedRoutedEventArgs e) 
        {
            Debug.Assert(sender == this && _ownJournalScope != null); 
            _ownJournalScope.GoForward();
            e.Handled = true;
        }
 
        private void OnNavigateJournal(object sender, ExecutedRoutedEventArgs e)
        { 
            Debug.Assert(sender == this && _ownJournalScope != null); 

            // The following checks are needed because anyone could send the NavigateJournal command. 
            FrameworkElement journalEntryUIElem = e.Parameter as FrameworkElement;
            if (journalEntryUIElem != null)
            {
                JournalEntry je = journalEntryUIElem.DataContext as JournalEntry; 
                if (je != null)
                { 
                    if (_ownJournalScope.NavigateToEntry(je)) 
                    {
                        e.Handled = true; 
                    }
                }
            }
        } 

        private void OnQueryRefresh(object sender, CanExecuteRoutedEventArgs e) 
        { 
            Debug.Assert(sender == this && _ownJournalScope != null);
            e.CanExecute = Content != null; 
        }
        private void OnRefresh(object sender, ExecutedRoutedEventArgs e)
        {
            Debug.Assert(sender == this && _ownJournalScope != null); 
            _navigationService.Refresh();
            e.Handled = true; 
        } 

        private void OnBrowseStop(object sender, ExecutedRoutedEventArgs e) 
        {
            Debug.Assert(sender == this && _ownJournalScope != null);
            _ownJournalScope.StopLoading();
            e.Handled = true; 
        }
 
        #endregion 

        #region Event Management 

        /// 
        ///     When a Frame-content's event bubbling up Visual tree, we need to adjust
        /// the source of the event to the frame itself. 
        /// 
        ///  
        ///     Routed Event Args 
        /// 
        ///  
        ///     Returns new source. (Current Frame object)
        /// 
        internal override object AdjustEventSource(RoutedEventArgs e)
        { 
            e.Source=this;
            return this; 
        } 

        #endregion 

        #region Overiding ContentControl implementation
        /// 
        ///    Return text representing this Frame 
        /// 
        internal override string GetPlainText() 
        { 
            if (this.Source != null)
            { 
                return Source.ToString();
            }
            else
            { 
                return String.Empty;
            } 
        } 

        ///  
        /// This method is used by TypeDescriptor to determine if this property should
        /// be serialized.
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)] 
        public override bool ShouldSerializeContent()
        { 
            // When uri of NavigationService is valid and can be used to 
            // relaod, we do not serialize content
            Invariant.Assert(_navigationService != null, "_navigationService should never be null here"); 
            return ( !_navigationService.CanReloadFromUri && Content != null);
        }

        #endregion Overding ContentControl implementation 

 
        #region NavigationService support 

        private static void OnParentNavigationServiceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            Debug.Assert(d as Frame != null && ((Frame)d).NavigationService != null);
            ((Frame) d).NavigationService.OnParentNavigationServiceChanged();
        } 

        ///  
        /// Called when the template's visual tree is created. 
        /// 
        public override void OnApplyTemplate() 
        {
            base.OnApplyTemplate();

            // Get the root element of the style 
            Visual v = TemplateChild;
            if (v != null) 
            { 
                NavigationService.VisualTreeAvailable(v);
            } 
        }

        #region INavigatorImpl members
 
        // Note: OnSourceUpdatedFromNavService is next to the other Source-related members of Frame.
 
        Visual INavigatorImpl.FindRootViewer() 
        {
            return NavigationHelper.FindRootViewer(this, "PART_FrameCP"); 
        }

        #endregion INavigatorImpl
 
        #endregion NavigationService support
 
        #region INavigator implementation 

        JournalNavigationScope INavigator.GetJournal(bool create) 
        {
            return GetJournal(create);
        }
 
        /// 
        ///  
        ///  
        private JournalNavigationScope GetJournal(bool create)
        { 
            Invariant.Assert(_ownJournalScope != null ^ _journalOwnership != JournalOwnership.OwnsJournal);

            if (_ownJournalScope != null)
                return _ownJournalScope; 

            JournalNavigationScope jns = GetParentJournal(create); 
            if (jns != null) 
            {
                SetCurrentValueInternal(JournalOwnershipProperty, JournalOwnership.UsesParentJournal); 
                return jns;
            }

            if (create && _journalOwnership == JournalOwnership.Automatic) 
            {
                SetCurrentValueInternal(JournalOwnershipProperty, JournalOwnership.OwnsJournal); 
            } 
            return _ownJournalScope;
        } 

        /// 
        /// True when the frame has its own journal and there is a navigable entry in the forward stack.
        /// If the frame doesn't own a journal, its parent or corresponding NavigationService may be 
        /// able to navigate it forward.
        ///  
        public bool CanGoForward 
        {
            get 
            {
                bool canGoFwd = _ownJournalScope != null && _ownJournalScope.CanGoForward;
                Debug.Assert(canGoFwd == (bool)GetValue(CanGoForwardProperty));
                return canGoFwd; 
            }
        } 
 
        /// 
        /// True when the frame has its own journal and there is a navigable entry in the back stack. 
        /// If the frame doesn't own a journal, its parent or corresponding NavigationService may be
        /// able to navigate it back.
        /// 
        public bool CanGoBack 
        {
            get 
            { 
                bool canGoBack = _ownJournalScope != null && _ownJournalScope.CanGoBack;
                Debug.Assert(canGoBack == (bool)GetValue(CanGoBackProperty)); 
                return canGoBack;
            }
        }
 
        /// 
        /// Adds a new journal entry to NavigationWindow's back history. 
        ///  
        ///  The custom content state (or view state) to be encapsulated in the
        /// journal entry. If null, IProvideCustomContentState.GetContentState() will be called on 
        /// the NavigationWindow.Content or Frame.Content object.
        /// 
        public void AddBackEntry(CustomContentState state)
        { 
            VerifyAccess();
            _navigationService.AddBackEntry(state); 
        } 

        ///  
        /// Removes the first JournalEntry from the frame's back stack.
        /// 
        ///  The frame doesn't own a journal. 
        public JournalEntry RemoveBackEntry() 
        {
            if (_ownJournalScope == null) 
                throw new InvalidOperationException(SR.Get(SRID.InvalidOperation_NoJournal)); 
            return _ownJournalScope.RemoveBackEntry();
        } 

        /// 
        /// Navigates to the Uri and downloads the content. Whether the navigation is
        /// performed synchronously or asynchronously depends on the current default navigation behavior. 
        /// 
        /// URI of the application or content being navigated to. 
        /// bool indicating whether the navigation was successfully started or not 
        public bool Navigate(Uri source)
        { 
            VerifyAccess();
            return _navigationService.Navigate(source);
        }
 
        //
        //  INavigator.Navigate 
        // 
        /// 
        /// This method navigates this Frame to the given Uri. 
        /// 
        /// The URI to be navigated to.
        /// enables the develeoper to supply an extra object, that will be returned in the NavigationEventArgs of the Navigated event. The extra data enables the developer
        /// to identify the source of the navigation, in the presence of 
        /// multiple navigations.
        ///  
        /// bool indicating whether the navigation was successfully started or not 
        public bool Navigate(Uri source, Object extraData)
        { 
            VerifyAccess();
            return _navigationService.Navigate(source, extraData);
        }
 
        /// 
        /// Navigates synchronously to an existing element tree. 
        ///  
        /// Root of the element tree being navigated to.
        /// bool indicating whether the navigation was successfully started or not 
        public bool Navigate(Object content)
        {
            VerifyAccess();
            return _navigationService.Navigate(content); 
        }
 
        // 
        //  INavigator.Navigate(object)
        // 
        /// 
        /// This method synchronously navigates this Frame to the
        /// given Element.
        ///  
        /// The Element to be navigated to.
        /// enables the develeoper to supply an extra object, that will be returned in the NavigationEventArgs of the Navigated event. The extra data enables the developer 
        /// to identify the source of the navigation, in the presence of 
        /// multiple navigations.
        ///  
        /// bool indicating whether the navigation was successfully started or not
        public bool Navigate(Object content, Object extraData)
        {
            VerifyAccess(); 
            return _navigationService.Navigate(content, extraData);
        } 
 
        /// 
        /// Navigates the frame to the next journal entry. The operation is available only when 
        /// the frame has its own journal. If not, try navigating the parent or the corresponding
        /// NavigationService.
        /// 
        ///  The frame doesn't own a journal.  
        ///  There is no forward journal entry to go to. 
        public void GoForward() 
        { 
            if (_ownJournalScope == null)
                throw new InvalidOperationException(SR.Get(SRID.InvalidOperation_NoJournal)); 
            _ownJournalScope.GoForward();
        }

        ///  
        /// Navigates the frame to the previous journal entry. The operation is available only when
        /// the frame has its own journal. If not, try navigating the parent or the corresponding 
        /// NavigationService. 
        /// 
        ///  The frame doesn't own a journal.  
        ///  There is no back journal entry to go to. 
        public void GoBack()
        {
            if(_ownJournalScope == null) 
                throw new InvalidOperationException(SR.Get(SRID.InvalidOperation_NoJournal));
            _ownJournalScope.GoBack(); 
        } 

        ///  
        /// StopLoading aborts asynchronous navigations that haven't been processed yet or that are
        /// still being downloaded. SopLoading does not abort parsing of the downloaded streams.
        /// The NavigationStopped event is fired only if the navigation was aborted.
        ///  
        public void StopLoading()
        { 
            VerifyAccess(); 
            _navigationService.StopLoading();
        } 

        /// 
        /// Reloads the current content.
        ///  
        public void Refresh()
        { 
            VerifyAccess(); 
            _navigationService.Refresh();
        } 

        /// 
        /// Uri for the current page. Getting this property always
        /// returns the URI of the content thats currently displayed. 
        /// regardless of whether a navigation is in progress or not.
        ///  
        ///  
        public Uri CurrentSource
        { 
            get
            {
                return _navigationService.CurrentSource;
            } 
        }
 
        ///  
        /// List of back journal entries. Available only when the frame has its own journal.
        ///  
        public IEnumerable BackStack
        {
            get
            { 
                IEnumerable backStack = _ownJournalScope == null ? null : _ownJournalScope.BackStack;
                Debug.Assert(backStack == GetValue(BackStackProperty)); 
                return backStack; 
            }
        } 
        /// 
        /// List of forward journal entries. Available only when the frame has its own journal.
        /// 
        public IEnumerable ForwardStack 
        {
            get 
            { 
                IEnumerable fwdStack = _ownJournalScope == null ? null : _ownJournalScope.ForwardStack;
                Debug.Assert(fwdStack == GetValue(ForwardStackProperty)); 
                return fwdStack;
            }
        }
 
        /// 
        /// Raised just before a navigation takes place. This event is fired for frame 
        /// navigations as well as top-level page navigations, so may fire multiple times 
        /// during the download of a page.
        /// The NavigatingCancelEventArgs contain the uri or root element of the content 
        /// being navigated to and an enum value that indicates the type of navigation.
        /// Canceling this event prevents the application from navigating.
        /// Note: An application hosted in the browser cannot prevent navigation away from
        /// the application by canceling this event. 
        /// Note: In the PDC build, if an application hosts the WebOC, this event is not raised
        /// for navigations within the WebOC. 
        ///  
        public event NavigatingCancelEventHandler Navigating
        { 
            add
            {
                _navigationService.Navigating += value;
            } 
            remove
            { 
                _navigationService.Navigating -= value; 
            }
        } 

        /// 
        /// Raised at periodic intervals while a navigation is taking place.
        /// The NavigationProgressEventArgs tell how many total bytes need to be downloaded and 
        /// how many have been sent at the moment the event is fired. This event can be used to provide
        /// a progress indicator to the user. 
        ///  
        public event NavigationProgressEventHandler NavigationProgress
        { 
            add
            {
                _navigationService.NavigationProgress += value;
            } 
            remove
            { 
                _navigationService.NavigationProgress -= value; 
            }
        } 

        /// 
        /// Raised an error is encountered during a navigation.
        /// The NavigationFailedEventArgs contains 
        /// the exception that was thrown. By default Handled property is set to false,
        /// which allows the exception to be rethrown. 
        /// The event handler can prevent exception from throwing 
        /// to the user by setting the Handled property to true
        ///  
        public event NavigationFailedEventHandler NavigationFailed
        {
            add
            { 
                _navigationService.NavigationFailed += value;
            } 
            remove 
            {
                _navigationService.NavigationFailed -= value; 
            }
        }

        ///  
        /// Raised after navigation the target has been found and the download has begun. This event
        /// is fired for frame navigations as well as top-level page navigations, so may fire 
        /// multiple times during the download of a page. 
        /// For an asynchronous navigation, this event indicates that a partial element tree
        /// has been handed to the parser, but more bits are still coming. 
        /// For a synchronous navigation, this event indicates the entire tree has been
        /// handed to the parser.
        /// The NavigationEventArgs contain the uri or root element of the content being navigated to.
        /// This event is informational only, and cannot be canceled. 
        /// 
        public event NavigatedEventHandler Navigated 
        { 
            add
            { 
                _navigationService.Navigated += value;
            }
            remove
            { 
                _navigationService.Navigated -= value;
            } 
        } 

        // 
        //  INavigator.LoadCompleted
        //
        /// 
        /// Raised after the entire page, including all images and frames, has been downloaded 
        /// and parsed. This is the event to handle to stop spinning the globe. The developer
        /// should check the IsNavigationInitiator property on the NavigationEventArgs to determine 
        /// whether to stop spinning the globe. 
        /// The NavigationEventArgs contain the uri or root element of the content being navigated to,
        /// and a IsNavigationInitiator property that indicates whether this is a new navigation 
        /// initiated by this Frame, or whether this navigation is being propagated down
        /// from a higher level navigation taking place in a containing window or frame.
        /// This event is informational only, and cannot be canceled.
        ///  
        public event LoadCompletedEventHandler LoadCompleted
        { 
            add 
            {
                _navigationService.LoadCompleted += value; 
            }
            remove
            {
                _navigationService.LoadCompleted -= value; 
            }
        } 
 
        /// 
        /// Raised when a navigation or download has been interrupted because the user clicked 
        /// the Stop button, or the Stop method was invoked.
        /// The NavigationEventArgs contain the uri or root element of the content being navigated to.
        /// This event is informational only, and cannot be canceled.
        ///  
        public event NavigationStoppedEventHandler NavigationStopped
        { 
            add 
            {
                _navigationService.NavigationStopped += value; 
            }
            remove
            {
                _navigationService.NavigationStopped -= value; 
            }
        } 
 
        /// 
        /// Raised when a navigation uri contains a fragment.  This event is fired before the element is scrolled 
        /// into view and allows the listener to respond to the fragment in a custom way.
        /// 
        public event FragmentNavigationEventHandler FragmentNavigation
        { 
            add
            { 
                _navigationService.FragmentNavigation += value; 
            }
            remove 
            {
                _navigationService.FragmentNavigation -= value;
            }
        } 

        #endregion INavigator implementation 
 
        #region IJournalNavigationScopeHost Members
 
        void IJournalNavigationScopeHost.VerifyContextAndObjectState()
        {
            VerifyAccess();
        } 

        void IJournalNavigationScopeHost.OnJournalAvailable() 
        { 
            // BackStackProperty & ForwardStackProperty should be set by JournalNavigationScope.
            Debug.Assert(GetValue(BackStackProperty) == _ownJournalScope.BackStack); 
        }

        bool IJournalNavigationScopeHost.GoBackOverride()
        { 
            return false; // not overriding here
        } 
        bool IJournalNavigationScopeHost.GoForwardOverride() 
        {
            return false; 
        }

        #endregion
 
        #region IJournalState Members
 
        ///  
        /// When Frame's parent container navigates away and if its content is not keep-alive,
        /// the frame's current page needs to be remembered. In addition, if the frame has its own 
        /// journal, it has to be preserved too. Class FramePersistState captures this "metajournaling"
        /// state. It will become part of the journal entry created for the navigation in the parent
        /// container (stored within a DataStreams instance).
        ///  
        [Serializable]
        private class FramePersistState : CustomJournalStateInternal 
        { 
            internal JournalEntry JournalEntry;
            internal Guid NavSvcGuid; 
            internal JournalOwnership JournalOwnership;
            internal Journal Journal;

            internal override void PrepareForSerialization() 
            {
                if (JournalEntry != null) 
                { 
                    if (JournalEntry.IsAlive()) // not serializable
                    { 
                        JournalEntry = null;
                        // Only the NavigationService GUID will be restored.
                        // See related case and explanation in Frame.GetJournalState().
                    } 
                    else
                    { 
                        Debug.Assert(JournalEntry.GetType().IsSerializable); 
                    }
                } 
                if (Journal != null)
                {
                    Journal.PruneKeepAliveEntries();
                } 
            }
        }; 
 
        CustomJournalStateInternal IJournalState.GetJournalState(JournalReason journalReason)
        { 
            if (journalReason != JournalReason.NewContentNavigation)
            {
                return null;
            } 

            FramePersistState state = new FramePersistState(); 
 
            // Save a JournalEntry for the current content.
            state.JournalEntry = _navigationService.MakeJournalEntry(JournalReason.NewContentNavigation); 
            // The current Content may be null or may not want to be journaled (=> JournalEntry=null).
            // But we still need to save and then restore the NS GUID - there may be other JEs keyed
            // by this GUID value.
            // i. There is a somewhat similar case in ApplicationProxyInternal._GetSaveHistoryBytesDelegate(). 
            state.NavSvcGuid = _navigationService.GuidId;
 
            state.JournalOwnership = _journalOwnership; 
            if (_ownJournalScope != null)
            { 
                Debug.Assert(_journalOwnership == JournalOwnership.OwnsJournal);
                // No need to make a copy here because this Frame object will be discarded.
                // (Supposedly the parent container is navigating away.)
                state.Journal = _ownJournalScope.Journal; 
            }
 
            return state; 
        }
 
        void IJournalState.RestoreJournalState(CustomJournalStateInternal cjs)
        {
            FramePersistState state = (FramePersistState)cjs;
 
            _navigationService.GuidId = state.NavSvcGuid;
 
            // Because the JournalOwnershipProperty doesn't have the FrameworkPropertyMetadataOptions.Journal 
            // flag, the parser will always set the value specified in markup, which may be different from
            // state.JournalOwnership. So, at this point JournalOwnership is not necessarily Automatic 
            // (the default).
            JournalOwnership = state.JournalOwnership;
            if(_journalOwnership == JournalOwnership.OwnsJournal)
            { 
                Invariant.Assert(state.Journal != null);
                _ownJournalScope.Journal = state.Journal; 
            } 

            if(state.JournalEntry != null) 
            {
                state.JournalEntry.Navigate(this, NavigationMode.Back);
            }
        } 
        #endregion IJournalState
 
        //------------------------------------------------------ 
        //
        //  Internal Methods 
        //
        //-----------------------------------------------------
        #region Internal Methods
 
        internal override void OnPreApplyTemplate()
        { 
            base.OnPreApplyTemplate(); 

            if (_ownJournalScope != null) 
            {
                // This causes the Journal instance to be created. BackStackProperty and ForwardStackProperty
                // should be set before the navigation chrome data-binds to them but after any Journal is
                // restored from FramePersistState. 
                _ownJournalScope.EnsureJournal();
            } 
        } 

        // Invalidate resources on the frame content if the content isn't 
        // reachable via the visual/logical tree
        internal override void OnThemeChanged()
        {
            // If the frame does not have a template generated tree then its 
            // content is not reachable via a tree walk.
            DependencyObject d; 
            if (!HasTemplateGeneratedSubTree && (d = Content as DependencyObject) != null) 
            {
                FrameworkElement fe; 
                FrameworkContentElement fce;
                Helper.DowncastToFEorFCE(d, out fe, out fce, false);

                if (fe != null || fce != null) 
                {
                    TreeWalkHelper.InvalidateOnResourcesChange(fe, fce, ResourcesChangeInfo.ThemeChangeInfo); 
                } 
            }
        } 

        #endregion Internal Methods

        //------------------------------------------------------ 
        //
        //  Private Methods 
        // 
        //------------------------------------------------------
        #region Private Methods 

        private JournalNavigationScope GetParentJournal(bool create)
        {
            JournalNavigationScope jns = null; 
            NavigationService parentNS = _navigationService.ParentNavigationService;
            if (parentNS != null) 
            { 
                jns = parentNS.INavigatorHost.GetJournal(create);
            } 
            return jns;
        }

        ///  Does not update the JournalOwnershipProperty.  
        private void SwitchToOwnJournal()
        { 
            Debug.Assert(_ownJournalScope == null ^ _journalOwnership == JournalOwnership.OwnsJournal); 
            if (_ownJournalScope == null)
            { 
                // Entries created for this frame in the parent's journal have to be removed.
                JournalNavigationScope parentJns = GetParentJournal(false/*don't create*/);
                if (parentJns != null)
                { 
                    parentJns.Journal.RemoveEntries(_navigationService.GuidId);
                } 
 
                _ownJournalScope = new JournalNavigationScope(this);
                _navigationService.InvalidateJournalNavigationScope(); 

                // BackStackProperty & ForwardStackProperty should become available immediately if
                // OwnsJournal is set *after* Frame is already loaded.
                // See comment in OnPreApplyTemplate(). 
                if (IsLoaded)
                { 
                    _ownJournalScope.EnsureJournal(); 
                }
 
                AddCommandBinding(new CommandBinding(NavigationCommands.BrowseBack, OnGoBack, OnQueryGoBack));
                AddCommandBinding(new CommandBinding(NavigationCommands.BrowseForward, OnGoForward, OnQueryGoForward));
                AddCommandBinding(new CommandBinding(NavigationCommands.NavigateJournal, OnNavigateJournal));
                AddCommandBinding(new CommandBinding(NavigationCommands.Refresh, OnRefresh, OnQueryRefresh)); 
                AddCommandBinding(new CommandBinding(NavigationCommands.BrowseStop, OnBrowseStop));
            } 
            _journalOwnership = JournalOwnership.OwnsJournal; 
        }
 
        ///  Does not update the JournalOwnershipProperty. 
        private void SwitchToParentJournal()
        {
            Debug.Assert(_ownJournalScope == null ^ _journalOwnership == JournalOwnership.OwnsJournal); 
            if (_ownJournalScope != null)
            { 
                _ownJournalScope = null; 
                _navigationService.InvalidateJournalNavigationScope();
 
                JournalNavigationScope.ClearDPValues(this);

                foreach (CommandBinding cb in _commandBindings)
                { 
                    base.CommandBindings.Remove(cb);
                } 
                _commandBindings = null; 
            }
            _journalOwnership = JournalOwnership.UsesParentJournal; 
        }

        private void AddCommandBinding(CommandBinding b)
        { 
            base.CommandBindings.Add(b);
 
            // Store the CommandBinding reference so that it can be removed in case the frame loses 
            // its JournalNavigationScope.
            if (_commandBindings == null) 
            {
                _commandBindings = new List(6);
            }
            _commandBindings.Add(b); 
        }
 
        #endregion Private Methods 

        //----------------------------------------------------- 
        //
        //  Private Fields
        //
        //------------------------------------------------------ 
        #region Private Fields
 
        private bool                _postContentRenderedFromLoadedHandler = false; 
        private DispatcherOperation _contentRenderedCallback;
        private NavigationService    _navigationService; 
        private bool               _sourceUpdatedFromNavService;

        ///  All changes should be made via the JournalOwnership property setter. 
        private JournalOwnership _journalOwnership = JournalOwnership.Automatic; 
        private JournalNavigationScope  _ownJournalScope;
        private List    _commandBindings; 
 
        #endregion Private Fields
 
        #region DTypeThemeStyleKey

        // Returns the DependencyObjectType for the registered ThemeStyleKey's default
        // value. Controls will override this method to return approriate types. 
        internal override DependencyObjectType DTypeThemeStyleKey
        { 
            get { return _dType; } 
        }
 
        private static DependencyObjectType _dType;

        #endregion DTypeThemeStyleKey
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: 
//      Frame is a ContentControl with navigation and journaling capabilities, much like NavigationWindow. 
//      It can use its own journal ("island frame") or its prent's, if available.
// 
// History:
//  ??        ??            Created
//  11/14/05: [....]       "Island Frame" implementation: Frame can have its own Journal/JournalNavigationScope.
// 
//---------------------------------------------------------------------------
 
using System; 
using System.Net;
using System.Collections; 
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Windows.Threading; 
using System.Security;
 
using System.Windows; 
using System.Windows.Input;
using System.Windows.Automation.Peers; 
using System.Windows.Media;
using System.Windows.Navigation;
using System.Windows.Markup;
 
using MS.Internal;
using MS.Internal.AppModel; 
using MS.Internal.Utility; 
using MS.Internal.KnownBoxes;
using MS.Utility; 
using MS.Internal.Controls;
using System.Collections.Generic;

using SecurityHelper=MS.Internal.PresentationFramework.SecurityHelper; 

 
namespace System.Windows.Navigation 
{
    ///  
    /// Journaling options for Frame
    /// 
    [Serializable]
    public enum JournalOwnership 
    {
        ///  
        /// Whether or not this Frame will create and use its own journal depends on its parent. 
        /// If the Frame is hosted by another Frame or a NavigationWindow, it behaves as though
        /// UseParentJournal was set. If it is not hosted by a Frame or NavigationWindow or all 
        /// containing frames have the UsesParentJournal setting, this frame will use its own journal.
        /// Once a frame creates its own journal, switching to Automatic has no effect.
        /// 
        Automatic = 0, 

        ///  
        /// The Frame has its own Journal which operates independent of the hosting container’s 
        /// journal (if it has one).
        ///  
        OwnsJournal,

        /// 
        /// The Frame’s journal entries are merged into the hosting container’s journal, if available. 
        /// Otherwise navigations in this frame are not journaled.
        ///  
        UsesParentJournal 
    };
 
    /// 
    /// 
    public enum NavigationUIVisibility
    { 
        /// 
        /// The navigation UI is visible when Frame has its own journal. 
        ///  
        Automatic = 0,
        ///  
        /// 
        Visible,
        /// 
        ///  
        Hidden
    }; 
} 

namespace System.Windows.Controls 
{
    /// 
    /// Frame control is an area that is used for loading a tree of elements.
    /// It uses the application navigation model to populate its content. 
    /// Hence its content model is dictated solely by the NavigationService it aggregates which has
    /// a Uri property that points to the Uri of the page that is to be loaded into the Frame. 
    /// There is also a Content property that returns the root element of the Framework tree being loaded from the Uri. 
    /// It is also possible to create a tree for the Frames content programmatically and set the Content property to it.
    ///  
    [DefaultProperty("Source"), DefaultEvent("Navigated")]
    [Localizability(LocalizationCategory.Ignore)]
#if OLD_AUTOMATION
    [Automation(AccessibilityControlType = "Window")] 
#endif
    [ContentProperty] 
    [TemplatePart(Name = "PART_FrameCP", Type = typeof(ContentPresenter))] 
    public class Frame : ContentControl, INavigator, INavigatorImpl, IJournalNavigationScopeHost, IDownloader, IJournalState, IAddChild, IUriContext
    { 

        #region Constructors

        ///  
        ///     Default constructor
        ///  
        ///  
        ///     Automatic determination of current Dispatcher. Use alternative constructor
        ///     that accepts a Dispatcher for best performance. 
        /// 
        public Frame() : base()
        {
            Init(); 
        }
 
        static Frame() 
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Frame), new FrameworkPropertyMetadata(typeof(Frame))); 
            _dType = DependencyObjectType.FromSystemTypeInternal(typeof(Frame));

            ContentProperty.OverrideMetadata(
                    typeof(Frame), 
                    new FrameworkPropertyMetadata(
                            null, 
                            new CoerceValueCallback(CoerceContent))); 

            KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(Frame), new FrameworkPropertyMetadata(KeyboardNavigationMode.Local)); 
            KeyboardNavigation.ControlTabNavigationProperty.OverrideMetadata(typeof(Frame), new FrameworkPropertyMetadata(KeyboardNavigationMode.Once));

            NavigationService.NavigationServiceProperty.OverrideMetadata(
                    typeof(Frame), 
                    new FrameworkPropertyMetadata(new PropertyChangedCallback(OnParentNavigationServiceChanged)));
        } 
 
        private static object CoerceContent(DependencyObject d, object value)
        { 
            // whenever content changes, defer the change until the Navigate comes in
            Frame f = (Frame) d;

            if (f._navigationService.Content == value) 
            {
                return value; 
            } 

            f.Navigate(value); 
            return DependencyProperty.UnsetValue;
        }

        ///  
        /// Initialize
        ///  
        private void Init() 
        {
            InheritanceBehavior = InheritanceBehavior.SkipToAppNow; 
            ContentIsNotLogical = true;
            _navigationService = new NavigationService(this);
            _navigationService.BPReady += new BPReadyEventHandler(_OnBPReady);
        } 

        #endregion 
 
        #region IUriContext implementation
        ///  
        ///     Accessor for the base uri of the frame
        /// 
        Uri IUriContext.BaseUri
        { 
            get
            { 
                return  BaseUri; 
            }
            set 
            {
                BaseUri = value;
            }
        } 

        ///  
        ///    Implementation for BaseUri 
        /// 
        protected virtual Uri BaseUri 
        {
            get
            {
                return (Uri)GetValue(BaseUriHelper.BaseUriProperty); 
            }
            set 
            { 
                SetValue(BaseUriHelper.BaseUriProperty, value);
            } 
        }

        #endregion IUriContext implementation
 
        #region IDownloader implementation
        NavigationService IDownloader.Downloader 
        { 
            get { return _navigationService; }
        } 

        /// 
        ///     Rasied when Content is rendered and ready for user interaction.
        ///  
        public event EventHandler ContentRendered;
 
        ///  
        ///     This override fires the ContentRendered event.
        ///  
        /// 
        protected virtual void OnContentRendered(EventArgs args)
        {
            // After the content is rendered we want to check if there is an element that needs to be focused 
            // If there is - set focus to it
            DependencyObject doContent = Content as DependencyObject; 
            if (doContent != null) 
            {
                IInputElement focusedElement = FocusManager.GetFocusedElement(doContent) as IInputElement; 
                if (focusedElement != null)
                    focusedElement.Focus();
            }
 
            if (ContentRendered != null)
            { 
                ContentRendered(this, args); 
            }
        } 
        #endregion IDownloader implementation

        #region Properties
        ///  
        ///
        ///  
        public static readonly DependencyProperty SourceProperty = 
                DependencyProperty.Register(
                        "Source", 
                        typeof(Uri),
                        typeof(Frame),
                        new FrameworkPropertyMetadata(
                                (Uri) null, 
                                // The Journal flag tells the parser not to re-assign the property
                                // when doing journal navigation. See ParserContext.SkipJournaledProperties. 
                                FrameworkPropertyMetadataOptions.Journal, 
                                new PropertyChangedCallback(OnSourcePropertyChanged),
                                new CoerceValueCallback(CoerceSource))); 

        private static object CoerceSource(DependencyObject d, object value)
        {
            Frame frame = (Frame)d; 

            // If the Source property is coerced from NavService as a result of navigation, not from other 
            // source, e.g, SetValue, DataBinding, Style..., we should use NavService.Source. 
            if (frame._sourceUpdatedFromNavService)
            { 
                Invariant.Assert(frame._navigationService != null, "_navigationService should never be null here");
                // Turn this Assert on after fix the issue that NavService.Source is not absolute for SiteOfOrigin.
                //Invariant.Assert(frame._navigationService.Source != null ? !frame._navigationService.Source.IsAbsoluteUri : true, "NavService's Source should always be relative");
                return frame._navigationService.Source; 
            }
 
            return value; 
        }
 
        /// 
        ///    Called when SourceProperty is invalidated on 'd'
        /// 
        /// 
        /// Critical as it access the base uri through GetUriToNavigate
        /// TreatAsSafe since it does not disclose this 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private static void OnSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            Frame frame = (Frame)d;

            // Don't navigate if the Source value change is from NavService as a result of a navigation happening. 
            if (! frame._sourceUpdatedFromNavService)
            { 
                // We used to unhook first visual child here. 
                // Since we enabled styling for Frame. We're relying on Content property and ContentPresenter in Frame's style
                // to add/remove content from VisualTree. 
                Uri uriToNavigate = BindUriHelper.GetUriToNavigate(frame, ((IUriContext)frame).BaseUri, (Uri)e.NewValue);

                // Calling the internal Navigate from Frame and NavWin's Source DP's property changed callbacks
                // We would not set value back in this case. 
                frame._navigationService.Navigate(uriToNavigate, null, false, true/* navigateOnSourceChanged */);
            } 
        } 

        // This method is called from NavService whenever the NavService's Source value is updated. 
        // The INavigator uses this to update its SourceProperty.
        // It indicates whether the NavService's Source value is as a result of
        // calling Navigate API directly or from GoBack/GoForward, journal navigation, a cancellation
        void INavigatorImpl.OnSourceUpdatedFromNavService(bool journalOrCancel) 
        {
            try 
            { 
                _sourceUpdatedFromNavService = true;
                SetCurrentValueInternal(SourceProperty, _navigationService.Source); 
            }
            finally
            {
                _sourceUpdatedFromNavService = false; 
            }
        } 
 
        /// 
        /// URI to navigate to. 
        /// 
        [Bindable(true), CustomCategory("Navigation")]
        public Uri Source
        { 
            get { return (Uri) GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); } 
        } 

        ///  
        ///     The DependencyProperty for the CanGoBack property.
        ///     Flags:              None
        ///     Default Value:      false
        ///     Readonly:           true 
        /// 
        public static readonly DependencyProperty CanGoBackProperty = 
            JournalNavigationScope.CanGoBackProperty.AddOwner(typeof(Frame)); 

        ///  
        ///     The DependencyProperty for the CanGoForward property.
        ///     Flags:              None
        ///     Default Value:      false
        ///     Readonly:           true 
        /// 
        public static readonly DependencyProperty CanGoForwardProperty = 
            JournalNavigationScope.CanGoForwardProperty.AddOwner(typeof(Frame)); 

        ///  
        /// List of back journal entries. Available only when the frame owns its own journal.
        /// 
        public static readonly DependencyProperty BackStackProperty =
            JournalNavigationScope.BackStackProperty.AddOwner(typeof(Frame)); 

        ///  
        /// List of back journal entries. Available only when the frame owns its own journal. 
        /// 
        public static readonly DependencyProperty ForwardStackProperty = 
            JournalNavigationScope.ForwardStackProperty.AddOwner(typeof(Frame));

        /// 
        ///  
        public static readonly DependencyProperty NavigationUIVisibilityProperty =
            DependencyProperty.Register( 
                "NavigationUIVisibility", typeof(NavigationUIVisibility), typeof(Frame), 
                new PropertyMetadata(NavigationUIVisibility.Automatic));
 
        /// 
        /// 
        public NavigationUIVisibility NavigationUIVisibility
        { 
            get { return (NavigationUIVisibility)GetValue(NavigationUIVisibilityProperty); }
            set { SetValue(NavigationUIVisibilityProperty, value); } 
        } 

        ///  
        /// DependencyProperty for SandboxExternalContent property.
        /// 
        public static readonly DependencyProperty SandboxExternalContentProperty =
                DependencyProperty.Register( 
                        "SandboxExternalContent",
                        typeof(bool), 
                        typeof(Frame), 
                        new FrameworkPropertyMetadata(BooleanBoxes.FalseBox,
                                new PropertyChangedCallback(OnSandboxExternalContentPropertyChanged), new CoerceValueCallback(CoerceSandBoxExternalContentValue))); 

        /// 
        /// If set to true, the navigated content is isolated.
        ///  
        public bool SandboxExternalContent
        { 
            get { return (bool) GetValue(SandboxExternalContentProperty); } 
            set
            { 
                // This feature is disabled in partial trust due to a P3P violation
                bool fSandBox = (bool)value;
                SecurityHelper.ThrowExceptionIfSettingTrueInPartialTrust(ref fSandBox);
                SetValue(SandboxExternalContentProperty, fSandBox); 
            }
        } 
 
        /// 
        ///    Called when SandboxExternalContentProperty is invalidated on 'd'.  If the value becomes 
        ///    true, then the frame is refreshed to sandbox any content.
        /// 
        private static void OnSandboxExternalContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        { 
            Frame frame = (Frame)d;
            // we do not want an individual to be able to set this property to true 
            // in partial trust 
            // This feature is disabled in partial trust due to a P3P violation
            bool fSandBox = (bool)e.NewValue; 
            SecurityHelper.ThrowExceptionIfSettingTrueInPartialTrust(ref fSandBox);
            if (fSandBox && !(bool)e.OldValue)
            {
                frame.NavigationService.Refresh(); 
            }
        } 
 
        private static object CoerceSandBoxExternalContentValue(DependencyObject d, object value)
        { 
            // we do not want an individual to be able to set this property to true
            // in partial trust
            // This feature is disabled in partial trust due to a P3P violation
            bool fSandBox = (bool)value; 
            SecurityHelper.ThrowExceptionIfSettingTrueInPartialTrust(ref fSandBox);
            return fSandBox; 
        } 

        // 
        // JournalOwnership

        /// 
        /// DependencyProperty for the JournalOwnership property 
        /// 
        public static readonly DependencyProperty JournalOwnershipProperty = 
                DependencyProperty.Register( 
                    "JournalOwnership", typeof(JournalOwnership), typeof(Frame),
                    new FrameworkPropertyMetadata( 
                        JournalOwnership.Automatic,
                        new PropertyChangedCallback(OnJournalOwnershipPropertyChanged),
                        new CoerceValueCallback(CoerceJournalOwnership)),
                    new ValidateValueCallback(ValidateJournalOwnershipValue)); 

        private static bool ValidateJournalOwnershipValue(object value) 
        { 
            JournalOwnership jo = (JournalOwnership)value;
            return jo == JournalOwnership.Automatic || jo == JournalOwnership.UsesParentJournal 
                || jo == JournalOwnership.OwnsJournal;
        }

        private static void OnJournalOwnershipPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            ((Frame)d).OnJournalOwnershipPropertyChanged((JournalOwnership)e.NewValue); 
        } 

        private void OnJournalOwnershipPropertyChanged(JournalOwnership newValue) 
        {
            // NavigationService.InvalidateJournalNavigationScope() will be called (recursively)
            // when making an ownership change and will throw if there is a navigation in progress.
 
            switch (_journalOwnership/*previous value*/)
            { 
                case JournalOwnership.Automatic: 
                    switch (newValue)
                    { 
                        case JournalOwnership.OwnsJournal:
                            SwitchToOwnJournal();
                            break;
                        case JournalOwnership.UsesParentJournal: 
                            SwitchToParentJournal();
                            break; 
                    } 
                    break;
                case JournalOwnership.OwnsJournal: 
                    Debug.Assert(_ownJournalScope != null);
                    switch (newValue)
                    {
                        case JournalOwnership.Automatic: 
                            Debug.Fail("UsesOwnJournal->Automatic transition should be blocked by CoerceJournalOwnership().");
                            break; 
                        case JournalOwnership.UsesParentJournal: 
                            SwitchToParentJournal();
                            break; 
                    }
                    break;
                case JournalOwnership.UsesParentJournal:
                    Debug.Assert(_ownJournalScope == null); 
                    switch (newValue)
                    { 
                        case JournalOwnership.Automatic: 
                            // The effective journal ownership is not going to change unless the
                            // frame is reparented (or, more unlikely, the parent's journal becomes 
                            // unavailable). This invalidation is done only so that the next
                            // navigation causes a switch to UsesParentJournal, to be consistent
                            // with the initial transition from Automatic.
                            _navigationService.InvalidateJournalNavigationScope(); 
                            break;
                        case JournalOwnership.OwnsJournal: 
                            SwitchToOwnJournal(); 
                            break;
                    } 
                    break;
            }

            _journalOwnership = newValue; 
        }
 
        private static object CoerceJournalOwnership(DependencyObject d, object newValue) 
        {
            JournalOwnership prevValue = ((Frame)d)._journalOwnership; 
            // Switching from OwnsJournal to Automatic is not defined to have any useful effect.
            // (Even if reparented, Frame will not relinquish its own journal to start using its new
            // parent's one.) But in order to be able to maintain some stronger invariants, this transition
            // is blocked here. 
            if (prevValue == JournalOwnership.OwnsJournal && (JournalOwnership)newValue == JournalOwnership.Automatic)
            { 
                return JournalOwnership.OwnsJournal; 
            }
            return newValue; 
        }

        /// 
        /// Journal ownership setting for this frame 
        /// 
        public JournalOwnership JournalOwnership 
        { 
            get
            { 
                Debug.Assert(_journalOwnership == (JournalOwnership)GetValue(JournalOwnershipProperty));
                return _journalOwnership;
            }
            set 
            {
                if (value != _journalOwnership) 
                { 
                    SetValue(JournalOwnershipProperty, value);
                } 
            }
        }

        ///  
        /// Frame's associated NavigationService.
        ///  
        public NavigationService NavigationService 
        {
            get 
            {
                VerifyAccess();
                return _navigationService;
            } 
        }
 
        #endregion 

        //----------------------------------------------------- 
        //
        //  Protected Methods
        //
        //----------------------------------------------------- 
        #region Protected Methods
 
        ///  
        /// Creates AutomationPeer ()
        ///  
        protected override AutomationPeer OnCreateAutomationPeer()
        {
            return new FrameAutomationPeer(this);
        } 

        ///  
        ///  Add an object child to this control 
        /// 
        protected override void AddChild(object value) 
        {
            throw new InvalidOperationException(SR.Get(SRID.FrameNoAddChild));
        }
 
        /// 
        ///  Add a text string to this control 
        ///  
        protected override void AddText(string text)
        { 
            XamlSerializerUtil.ThrowIfNonWhiteSpaceInAddText(text, this);
        }
        #endregion
 
        #region Event Handlers
 
        private void _OnBPReady(Object o, BPReadyEventArgs e) 
        {
            // update content property 
            SetCurrentValueInternal(ContentProperty, e.Content);

            // Need to refresh everytime the child changed
            InvalidateMeasure(); 

            // We post a dispatcher work item to fire ContentRendered 
            // only if this is Loaded in the tree.  If not, we will 
            // post it from the LoadedHandler.  This guarantees that
            // we don't fire ContentRendered on a subtree that is not 
            // connected to a PresentationSource
            if (IsLoaded == true)
            {
                PostContentRendered(); 
            }
            else 
            { 
                // _postContentRenderedFromLoadedHandler == true means
                // that we deferred to the Loaded event to PostConetentRendered 
                // for the previous content change and Loaded has not fired yet.
                // Thus we don't want to hook up another event handler
                if (_postContentRenderedFromLoadedHandler == false)
                { 
                    this.Loaded += new RoutedEventHandler(LoadedHandler);
                    _postContentRenderedFromLoadedHandler = true; 
                } 
            }
        } 

        private void LoadedHandler(object sender, RoutedEventArgs args)
        {
            if (_postContentRenderedFromLoadedHandler == true) 
            {
                PostContentRendered(); 
                _postContentRenderedFromLoadedHandler = false; 
                this.Loaded -= new RoutedEventHandler(LoadedHandler);
            } 
        }

        ///  Keep this method in [....] with Window.PostContentRendered(). 
        private void PostContentRendered() 
        {
            // Post the firing of ContentRendered as Input priority work item so 
            // that ContentRendered will be fired after render query empties. 
            if (_contentRenderedCallback != null)
            { 
                // Content was changed again before the previous rendering completed (or at least
                // before the Dispatcher got to Input priority callbacks).
                _contentRenderedCallback.Abort();
            } 
            _contentRenderedCallback = Dispatcher.BeginInvoke(DispatcherPriority.Input,
                                   (DispatcherOperationCallback) delegate (object unused) 
                                   { 
                                       _contentRenderedCallback = null;
                                       OnContentRendered(EventArgs.Empty); 
                                       return null;
                                   },
                                   this);
        } 

        private void OnQueryGoBack(object sender, CanExecuteRoutedEventArgs e) 
        { 
            Debug.Assert(sender == this && _ownJournalScope != null);
            e.CanExecute = _ownJournalScope.CanGoBack; 
            e.Handled = true;
        }
        private void OnGoBack(object sender, ExecutedRoutedEventArgs e)
        { 
            Debug.Assert(sender == this && _ownJournalScope != null);
            _ownJournalScope.GoBack(); 
            e.Handled = true; 
        }
 
        private void OnQueryGoForward(object sender, CanExecuteRoutedEventArgs e)
        {
            Debug.Assert(sender == this && _ownJournalScope != null);
            e.CanExecute = _ownJournalScope.CanGoForward; 
            e.Handled = true;
        } 
        private void OnGoForward(object sender, ExecutedRoutedEventArgs e) 
        {
            Debug.Assert(sender == this && _ownJournalScope != null); 
            _ownJournalScope.GoForward();
            e.Handled = true;
        }
 
        private void OnNavigateJournal(object sender, ExecutedRoutedEventArgs e)
        { 
            Debug.Assert(sender == this && _ownJournalScope != null); 

            // The following checks are needed because anyone could send the NavigateJournal command. 
            FrameworkElement journalEntryUIElem = e.Parameter as FrameworkElement;
            if (journalEntryUIElem != null)
            {
                JournalEntry je = journalEntryUIElem.DataContext as JournalEntry; 
                if (je != null)
                { 
                    if (_ownJournalScope.NavigateToEntry(je)) 
                    {
                        e.Handled = true; 
                    }
                }
            }
        } 

        private void OnQueryRefresh(object sender, CanExecuteRoutedEventArgs e) 
        { 
            Debug.Assert(sender == this && _ownJournalScope != null);
            e.CanExecute = Content != null; 
        }
        private void OnRefresh(object sender, ExecutedRoutedEventArgs e)
        {
            Debug.Assert(sender == this && _ownJournalScope != null); 
            _navigationService.Refresh();
            e.Handled = true; 
        } 

        private void OnBrowseStop(object sender, ExecutedRoutedEventArgs e) 
        {
            Debug.Assert(sender == this && _ownJournalScope != null);
            _ownJournalScope.StopLoading();
            e.Handled = true; 
        }
 
        #endregion 

        #region Event Management 

        /// 
        ///     When a Frame-content's event bubbling up Visual tree, we need to adjust
        /// the source of the event to the frame itself. 
        /// 
        ///  
        ///     Routed Event Args 
        /// 
        ///  
        ///     Returns new source. (Current Frame object)
        /// 
        internal override object AdjustEventSource(RoutedEventArgs e)
        { 
            e.Source=this;
            return this; 
        } 

        #endregion 

        #region Overiding ContentControl implementation
        /// 
        ///    Return text representing this Frame 
        /// 
        internal override string GetPlainText() 
        { 
            if (this.Source != null)
            { 
                return Source.ToString();
            }
            else
            { 
                return String.Empty;
            } 
        } 

        ///  
        /// This method is used by TypeDescriptor to determine if this property should
        /// be serialized.
        /// 
        [EditorBrowsable(EditorBrowsableState.Never)] 
        public override bool ShouldSerializeContent()
        { 
            // When uri of NavigationService is valid and can be used to 
            // relaod, we do not serialize content
            Invariant.Assert(_navigationService != null, "_navigationService should never be null here"); 
            return ( !_navigationService.CanReloadFromUri && Content != null);
        }

        #endregion Overding ContentControl implementation 

 
        #region NavigationService support 

        private static void OnParentNavigationServiceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
        {
            Debug.Assert(d as Frame != null && ((Frame)d).NavigationService != null);
            ((Frame) d).NavigationService.OnParentNavigationServiceChanged();
        } 

        ///  
        /// Called when the template's visual tree is created. 
        /// 
        public override void OnApplyTemplate() 
        {
            base.OnApplyTemplate();

            // Get the root element of the style 
            Visual v = TemplateChild;
            if (v != null) 
            { 
                NavigationService.VisualTreeAvailable(v);
            } 
        }

        #region INavigatorImpl members
 
        // Note: OnSourceUpdatedFromNavService is next to the other Source-related members of Frame.
 
        Visual INavigatorImpl.FindRootViewer() 
        {
            return NavigationHelper.FindRootViewer(this, "PART_FrameCP"); 
        }

        #endregion INavigatorImpl
 
        #endregion NavigationService support
 
        #region INavigator implementation 

        JournalNavigationScope INavigator.GetJournal(bool create) 
        {
            return GetJournal(create);
        }
 
        /// 
        ///  
        ///  
        private JournalNavigationScope GetJournal(bool create)
        { 
            Invariant.Assert(_ownJournalScope != null ^ _journalOwnership != JournalOwnership.OwnsJournal);

            if (_ownJournalScope != null)
                return _ownJournalScope; 

            JournalNavigationScope jns = GetParentJournal(create); 
            if (jns != null) 
            {
                SetCurrentValueInternal(JournalOwnershipProperty, JournalOwnership.UsesParentJournal); 
                return jns;
            }

            if (create && _journalOwnership == JournalOwnership.Automatic) 
            {
                SetCurrentValueInternal(JournalOwnershipProperty, JournalOwnership.OwnsJournal); 
            } 
            return _ownJournalScope;
        } 

        /// 
        /// True when the frame has its own journal and there is a navigable entry in the forward stack.
        /// If the frame doesn't own a journal, its parent or corresponding NavigationService may be 
        /// able to navigate it forward.
        ///  
        public bool CanGoForward 
        {
            get 
            {
                bool canGoFwd = _ownJournalScope != null && _ownJournalScope.CanGoForward;
                Debug.Assert(canGoFwd == (bool)GetValue(CanGoForwardProperty));
                return canGoFwd; 
            }
        } 
 
        /// 
        /// True when the frame has its own journal and there is a navigable entry in the back stack. 
        /// If the frame doesn't own a journal, its parent or corresponding NavigationService may be
        /// able to navigate it back.
        /// 
        public bool CanGoBack 
        {
            get 
            { 
                bool canGoBack = _ownJournalScope != null && _ownJournalScope.CanGoBack;
                Debug.Assert(canGoBack == (bool)GetValue(CanGoBackProperty)); 
                return canGoBack;
            }
        }
 
        /// 
        /// Adds a new journal entry to NavigationWindow's back history. 
        ///  
        ///  The custom content state (or view state) to be encapsulated in the
        /// journal entry. If null, IProvideCustomContentState.GetContentState() will be called on 
        /// the NavigationWindow.Content or Frame.Content object.
        /// 
        public void AddBackEntry(CustomContentState state)
        { 
            VerifyAccess();
            _navigationService.AddBackEntry(state); 
        } 

        ///  
        /// Removes the first JournalEntry from the frame's back stack.
        /// 
        ///  The frame doesn't own a journal. 
        public JournalEntry RemoveBackEntry() 
        {
            if (_ownJournalScope == null) 
                throw new InvalidOperationException(SR.Get(SRID.InvalidOperation_NoJournal)); 
            return _ownJournalScope.RemoveBackEntry();
        } 

        /// 
        /// Navigates to the Uri and downloads the content. Whether the navigation is
        /// performed synchronously or asynchronously depends on the current default navigation behavior. 
        /// 
        /// URI of the application or content being navigated to. 
        /// bool indicating whether the navigation was successfully started or not 
        public bool Navigate(Uri source)
        { 
            VerifyAccess();
            return _navigationService.Navigate(source);
        }
 
        //
        //  INavigator.Navigate 
        // 
        /// 
        /// This method navigates this Frame to the given Uri. 
        /// 
        /// The URI to be navigated to.
        /// enables the develeoper to supply an extra object, that will be returned in the NavigationEventArgs of the Navigated event. The extra data enables the developer
        /// to identify the source of the navigation, in the presence of 
        /// multiple navigations.
        ///  
        /// bool indicating whether the navigation was successfully started or not 
        public bool Navigate(Uri source, Object extraData)
        { 
            VerifyAccess();
            return _navigationService.Navigate(source, extraData);
        }
 
        /// 
        /// Navigates synchronously to an existing element tree. 
        ///  
        /// Root of the element tree being navigated to.
        /// bool indicating whether the navigation was successfully started or not 
        public bool Navigate(Object content)
        {
            VerifyAccess();
            return _navigationService.Navigate(content); 
        }
 
        // 
        //  INavigator.Navigate(object)
        // 
        /// 
        /// This method synchronously navigates this Frame to the
        /// given Element.
        ///  
        /// The Element to be navigated to.
        /// enables the develeoper to supply an extra object, that will be returned in the NavigationEventArgs of the Navigated event. The extra data enables the developer 
        /// to identify the source of the navigation, in the presence of 
        /// multiple navigations.
        ///  
        /// bool indicating whether the navigation was successfully started or not
        public bool Navigate(Object content, Object extraData)
        {
            VerifyAccess(); 
            return _navigationService.Navigate(content, extraData);
        } 
 
        /// 
        /// Navigates the frame to the next journal entry. The operation is available only when 
        /// the frame has its own journal. If not, try navigating the parent or the corresponding
        /// NavigationService.
        /// 
        ///  The frame doesn't own a journal.  
        ///  There is no forward journal entry to go to. 
        public void GoForward() 
        { 
            if (_ownJournalScope == null)
                throw new InvalidOperationException(SR.Get(SRID.InvalidOperation_NoJournal)); 
            _ownJournalScope.GoForward();
        }

        ///  
        /// Navigates the frame to the previous journal entry. The operation is available only when
        /// the frame has its own journal. If not, try navigating the parent or the corresponding 
        /// NavigationService. 
        /// 
        ///  The frame doesn't own a journal.  
        ///  There is no back journal entry to go to. 
        public void GoBack()
        {
            if(_ownJournalScope == null) 
                throw new InvalidOperationException(SR.Get(SRID.InvalidOperation_NoJournal));
            _ownJournalScope.GoBack(); 
        } 

        ///  
        /// StopLoading aborts asynchronous navigations that haven't been processed yet or that are
        /// still being downloaded. SopLoading does not abort parsing of the downloaded streams.
        /// The NavigationStopped event is fired only if the navigation was aborted.
        ///  
        public void StopLoading()
        { 
            VerifyAccess(); 
            _navigationService.StopLoading();
        } 

        /// 
        /// Reloads the current content.
        ///  
        public void Refresh()
        { 
            VerifyAccess(); 
            _navigationService.Refresh();
        } 

        /// 
        /// Uri for the current page. Getting this property always
        /// returns the URI of the content thats currently displayed. 
        /// regardless of whether a navigation is in progress or not.
        ///  
        ///  
        public Uri CurrentSource
        { 
            get
            {
                return _navigationService.CurrentSource;
            } 
        }
 
        ///  
        /// List of back journal entries. Available only when the frame has its own journal.
        ///  
        public IEnumerable BackStack
        {
            get
            { 
                IEnumerable backStack = _ownJournalScope == null ? null : _ownJournalScope.BackStack;
                Debug.Assert(backStack == GetValue(BackStackProperty)); 
                return backStack; 
            }
        } 
        /// 
        /// List of forward journal entries. Available only when the frame has its own journal.
        /// 
        public IEnumerable ForwardStack 
        {
            get 
            { 
                IEnumerable fwdStack = _ownJournalScope == null ? null : _ownJournalScope.ForwardStack;
                Debug.Assert(fwdStack == GetValue(ForwardStackProperty)); 
                return fwdStack;
            }
        }
 
        /// 
        /// Raised just before a navigation takes place. This event is fired for frame 
        /// navigations as well as top-level page navigations, so may fire multiple times 
        /// during the download of a page.
        /// The NavigatingCancelEventArgs contain the uri or root element of the content 
        /// being navigated to and an enum value that indicates the type of navigation.
        /// Canceling this event prevents the application from navigating.
        /// Note: An application hosted in the browser cannot prevent navigation away from
        /// the application by canceling this event. 
        /// Note: In the PDC build, if an application hosts the WebOC, this event is not raised
        /// for navigations within the WebOC. 
        ///  
        public event NavigatingCancelEventHandler Navigating
        { 
            add
            {
                _navigationService.Navigating += value;
            } 
            remove
            { 
                _navigationService.Navigating -= value; 
            }
        } 

        /// 
        /// Raised at periodic intervals while a navigation is taking place.
        /// The NavigationProgressEventArgs tell how many total bytes need to be downloaded and 
        /// how many have been sent at the moment the event is fired. This event can be used to provide
        /// a progress indicator to the user. 
        ///  
        public event NavigationProgressEventHandler NavigationProgress
        { 
            add
            {
                _navigationService.NavigationProgress += value;
            } 
            remove
            { 
                _navigationService.NavigationProgress -= value; 
            }
        } 

        /// 
        /// Raised an error is encountered during a navigation.
        /// The NavigationFailedEventArgs contains 
        /// the exception that was thrown. By default Handled property is set to false,
        /// which allows the exception to be rethrown. 
        /// The event handler can prevent exception from throwing 
        /// to the user by setting the Handled property to true
        ///  
        public event NavigationFailedEventHandler NavigationFailed
        {
            add
            { 
                _navigationService.NavigationFailed += value;
            } 
            remove 
            {
                _navigationService.NavigationFailed -= value; 
            }
        }

        ///  
        /// Raised after navigation the target has been found and the download has begun. This event
        /// is fired for frame navigations as well as top-level page navigations, so may fire 
        /// multiple times during the download of a page. 
        /// For an asynchronous navigation, this event indicates that a partial element tree
        /// has been handed to the parser, but more bits are still coming. 
        /// For a synchronous navigation, this event indicates the entire tree has been
        /// handed to the parser.
        /// The NavigationEventArgs contain the uri or root element of the content being navigated to.
        /// This event is informational only, and cannot be canceled. 
        /// 
        public event NavigatedEventHandler Navigated 
        { 
            add
            { 
                _navigationService.Navigated += value;
            }
            remove
            { 
                _navigationService.Navigated -= value;
            } 
        } 

        // 
        //  INavigator.LoadCompleted
        //
        /// 
        /// Raised after the entire page, including all images and frames, has been downloaded 
        /// and parsed. This is the event to handle to stop spinning the globe. The developer
        /// should check the IsNavigationInitiator property on the NavigationEventArgs to determine 
        /// whether to stop spinning the globe. 
        /// The NavigationEventArgs contain the uri or root element of the content being navigated to,
        /// and a IsNavigationInitiator property that indicates whether this is a new navigation 
        /// initiated by this Frame, or whether this navigation is being propagated down
        /// from a higher level navigation taking place in a containing window or frame.
        /// This event is informational only, and cannot be canceled.
        ///  
        public event LoadCompletedEventHandler LoadCompleted
        { 
            add 
            {
                _navigationService.LoadCompleted += value; 
            }
            remove
            {
                _navigationService.LoadCompleted -= value; 
            }
        } 
 
        /// 
        /// Raised when a navigation or download has been interrupted because the user clicked 
        /// the Stop button, or the Stop method was invoked.
        /// The NavigationEventArgs contain the uri or root element of the content being navigated to.
        /// This event is informational only, and cannot be canceled.
        ///  
        public event NavigationStoppedEventHandler NavigationStopped
        { 
            add 
            {
                _navigationService.NavigationStopped += value; 
            }
            remove
            {
                _navigationService.NavigationStopped -= value; 
            }
        } 
 
        /// 
        /// Raised when a navigation uri contains a fragment.  This event is fired before the element is scrolled 
        /// into view and allows the listener to respond to the fragment in a custom way.
        /// 
        public event FragmentNavigationEventHandler FragmentNavigation
        { 
            add
            { 
                _navigationService.FragmentNavigation += value; 
            }
            remove 
            {
                _navigationService.FragmentNavigation -= value;
            }
        } 

        #endregion INavigator implementation 
 
        #region IJournalNavigationScopeHost Members
 
        void IJournalNavigationScopeHost.VerifyContextAndObjectState()
        {
            VerifyAccess();
        } 

        void IJournalNavigationScopeHost.OnJournalAvailable() 
        { 
            // BackStackProperty & ForwardStackProperty should be set by JournalNavigationScope.
            Debug.Assert(GetValue(BackStackProperty) == _ownJournalScope.BackStack); 
        }

        bool IJournalNavigationScopeHost.GoBackOverride()
        { 
            return false; // not overriding here
        } 
        bool IJournalNavigationScopeHost.GoForwardOverride() 
        {
            return false; 
        }

        #endregion
 
        #region IJournalState Members
 
        ///  
        /// When Frame's parent container navigates away and if its content is not keep-alive,
        /// the frame's current page needs to be remembered. In addition, if the frame has its own 
        /// journal, it has to be preserved too. Class FramePersistState captures this "metajournaling"
        /// state. It will become part of the journal entry created for the navigation in the parent
        /// container (stored within a DataStreams instance).
        ///  
        [Serializable]
        private class FramePersistState : CustomJournalStateInternal 
        { 
            internal JournalEntry JournalEntry;
            internal Guid NavSvcGuid; 
            internal JournalOwnership JournalOwnership;
            internal Journal Journal;

            internal override void PrepareForSerialization() 
            {
                if (JournalEntry != null) 
                { 
                    if (JournalEntry.IsAlive()) // not serializable
                    { 
                        JournalEntry = null;
                        // Only the NavigationService GUID will be restored.
                        // See related case and explanation in Frame.GetJournalState().
                    } 
                    else
                    { 
                        Debug.Assert(JournalEntry.GetType().IsSerializable); 
                    }
                } 
                if (Journal != null)
                {
                    Journal.PruneKeepAliveEntries();
                } 
            }
        }; 
 
        CustomJournalStateInternal IJournalState.GetJournalState(JournalReason journalReason)
        { 
            if (journalReason != JournalReason.NewContentNavigation)
            {
                return null;
            } 

            FramePersistState state = new FramePersistState(); 
 
            // Save a JournalEntry for the current content.
            state.JournalEntry = _navigationService.MakeJournalEntry(JournalReason.NewContentNavigation); 
            // The current Content may be null or may not want to be journaled (=> JournalEntry=null).
            // But we still need to save and then restore the NS GUID - there may be other JEs keyed
            // by this GUID value.
            // i. There is a somewhat similar case in ApplicationProxyInternal._GetSaveHistoryBytesDelegate(). 
            state.NavSvcGuid = _navigationService.GuidId;
 
            state.JournalOwnership = _journalOwnership; 
            if (_ownJournalScope != null)
            { 
                Debug.Assert(_journalOwnership == JournalOwnership.OwnsJournal);
                // No need to make a copy here because this Frame object will be discarded.
                // (Supposedly the parent container is navigating away.)
                state.Journal = _ownJournalScope.Journal; 
            }
 
            return state; 
        }
 
        void IJournalState.RestoreJournalState(CustomJournalStateInternal cjs)
        {
            FramePersistState state = (FramePersistState)cjs;
 
            _navigationService.GuidId = state.NavSvcGuid;
 
            // Because the JournalOwnershipProperty doesn't have the FrameworkPropertyMetadataOptions.Journal 
            // flag, the parser will always set the value specified in markup, which may be different from
            // state.JournalOwnership. So, at this point JournalOwnership is not necessarily Automatic 
            // (the default).
            JournalOwnership = state.JournalOwnership;
            if(_journalOwnership == JournalOwnership.OwnsJournal)
            { 
                Invariant.Assert(state.Journal != null);
                _ownJournalScope.Journal = state.Journal; 
            } 

            if(state.JournalEntry != null) 
            {
                state.JournalEntry.Navigate(this, NavigationMode.Back);
            }
        } 
        #endregion IJournalState
 
        //------------------------------------------------------ 
        //
        //  Internal Methods 
        //
        //-----------------------------------------------------
        #region Internal Methods
 
        internal override void OnPreApplyTemplate()
        { 
            base.OnPreApplyTemplate(); 

            if (_ownJournalScope != null) 
            {
                // This causes the Journal instance to be created. BackStackProperty and ForwardStackProperty
                // should be set before the navigation chrome data-binds to them but after any Journal is
                // restored from FramePersistState. 
                _ownJournalScope.EnsureJournal();
            } 
        } 

        // Invalidate resources on the frame content if the content isn't 
        // reachable via the visual/logical tree
        internal override void OnThemeChanged()
        {
            // If the frame does not have a template generated tree then its 
            // content is not reachable via a tree walk.
            DependencyObject d; 
            if (!HasTemplateGeneratedSubTree && (d = Content as DependencyObject) != null) 
            {
                FrameworkElement fe; 
                FrameworkContentElement fce;
                Helper.DowncastToFEorFCE(d, out fe, out fce, false);

                if (fe != null || fce != null) 
                {
                    TreeWalkHelper.InvalidateOnResourcesChange(fe, fce, ResourcesChangeInfo.ThemeChangeInfo); 
                } 
            }
        } 

        #endregion Internal Methods

        //------------------------------------------------------ 
        //
        //  Private Methods 
        // 
        //------------------------------------------------------
        #region Private Methods 

        private JournalNavigationScope GetParentJournal(bool create)
        {
            JournalNavigationScope jns = null; 
            NavigationService parentNS = _navigationService.ParentNavigationService;
            if (parentNS != null) 
            { 
                jns = parentNS.INavigatorHost.GetJournal(create);
            } 
            return jns;
        }

        ///  Does not update the JournalOwnershipProperty.  
        private void SwitchToOwnJournal()
        { 
            Debug.Assert(_ownJournalScope == null ^ _journalOwnership == JournalOwnership.OwnsJournal); 
            if (_ownJournalScope == null)
            { 
                // Entries created for this frame in the parent's journal have to be removed.
                JournalNavigationScope parentJns = GetParentJournal(false/*don't create*/);
                if (parentJns != null)
                { 
                    parentJns.Journal.RemoveEntries(_navigationService.GuidId);
                } 
 
                _ownJournalScope = new JournalNavigationScope(this);
                _navigationService.InvalidateJournalNavigationScope(); 

                // BackStackProperty & ForwardStackProperty should become available immediately if
                // OwnsJournal is set *after* Frame is already loaded.
                // See comment in OnPreApplyTemplate(). 
                if (IsLoaded)
                { 
                    _ownJournalScope.EnsureJournal(); 
                }
 
                AddCommandBinding(new CommandBinding(NavigationCommands.BrowseBack, OnGoBack, OnQueryGoBack));
                AddCommandBinding(new CommandBinding(NavigationCommands.BrowseForward, OnGoForward, OnQueryGoForward));
                AddCommandBinding(new CommandBinding(NavigationCommands.NavigateJournal, OnNavigateJournal));
                AddCommandBinding(new CommandBinding(NavigationCommands.Refresh, OnRefresh, OnQueryRefresh)); 
                AddCommandBinding(new CommandBinding(NavigationCommands.BrowseStop, OnBrowseStop));
            } 
            _journalOwnership = JournalOwnership.OwnsJournal; 
        }
 
        ///  Does not update the JournalOwnershipProperty. 
        private void SwitchToParentJournal()
        {
            Debug.Assert(_ownJournalScope == null ^ _journalOwnership == JournalOwnership.OwnsJournal); 
            if (_ownJournalScope != null)
            { 
                _ownJournalScope = null; 
                _navigationService.InvalidateJournalNavigationScope();
 
                JournalNavigationScope.ClearDPValues(this);

                foreach (CommandBinding cb in _commandBindings)
                { 
                    base.CommandBindings.Remove(cb);
                } 
                _commandBindings = null; 
            }
            _journalOwnership = JournalOwnership.UsesParentJournal; 
        }

        private void AddCommandBinding(CommandBinding b)
        { 
            base.CommandBindings.Add(b);
 
            // Store the CommandBinding reference so that it can be removed in case the frame loses 
            // its JournalNavigationScope.
            if (_commandBindings == null) 
            {
                _commandBindings = new List(6);
            }
            _commandBindings.Add(b); 
        }
 
        #endregion Private Methods 

        //----------------------------------------------------- 
        //
        //  Private Fields
        //
        //------------------------------------------------------ 
        #region Private Fields
 
        private bool                _postContentRenderedFromLoadedHandler = false; 
        private DispatcherOperation _contentRenderedCallback;
        private NavigationService    _navigationService; 
        private bool               _sourceUpdatedFromNavService;

        ///  All changes should be made via the JournalOwnership property setter. 
        private JournalOwnership _journalOwnership = JournalOwnership.Automatic; 
        private JournalNavigationScope  _ownJournalScope;
        private List    _commandBindings; 
 
        #endregion Private Fields
 
        #region DTypeThemeStyleKey

        // Returns the DependencyObjectType for the registered ThemeStyleKey's default
        // value. Controls will override this method to return approriate types. 
        internal override DependencyObjectType DTypeThemeStyleKey
        { 
            get { return _dType; } 
        }
 
        private static DependencyObjectType _dType;

        #endregion DTypeThemeStyleKey
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK