Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / System / Windows / Navigation / NavigationWindow.cs / 1 / NavigationWindow.cs
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// Description:
// The NavigationWindow extends the base window class to provide Navigation functionality.
//
// Using the navigation window it's possible to set the Uri of a Navigation Window, and the
// Content region of the window displays the markup at that Uri.
//
// It's also possible to change the outermost "chrome" of markup that hosts the content region
// of the window.
//
// History:
// 10/27/01: mihaii Created
// 05/21/03: marka Moved over to WCP dir. Made match spec, updated comments.
// 11/14/05: ChangoV "Island Frame" implementation. Journaling-related operations factored out into
// JournalNavigationScope.
//
//---------------------------------------------------------------------------
using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using MS.Internal;
using MS.Internal.AppModel;
using MS.Internal.KnownBoxes;
using MS.Internal.Utility;
using MS.Utility;
using MS.Win32;
using MS.Internal.PresentationFramework;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Navigation;
using System.Windows.Markup;
using System.Windows.Threading;
using System.Windows.Documents;
namespace System.Windows.Navigation
{
#region NavigationWindow Class
///
/// Public class NavigationWindow
///
///
[ContentProperty]
[TemplatePart(Name = "PART_NavWinCP", Type = typeof(ContentPresenter))]
public class NavigationWindow : Window, INavigator, INavigatorImpl, IDownloader, IJournalNavigationScopeHost
{
#region DependencyProperties
///
/// DependencyProperty for SandboxExternalContent property.
///
public static readonly DependencyProperty SandboxExternalContentProperty =
Frame.SandboxExternalContentProperty.AddOwner(typeof(NavigationWindow));
///
/// 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)
{
NavigationWindow window = (NavigationWindow)d;
// 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)
{
window.NavigationService.Refresh();
}
}
private static object CoerceSandBoxExternalContentValue(DependencyObject d, object value)
{
// This feature is disabled in partial trust due to a P3P violation
bool fSandBox = (bool)value;
SecurityHelper.ThrowExceptionIfSettingTrueInPartialTrust(ref fSandBox);
return fSandBox;
}
///
/// DependencyProperty for ShowsNavigationUI property.
///
public static readonly DependencyProperty ShowsNavigationUIProperty =
DependencyProperty.Register(
"ShowsNavigationUI",
typeof(bool),
typeof(NavigationWindow),
new FrameworkPropertyMetadata(BooleanBoxes.TrueBox));
///
/// DependencyProperty for BackStack property.
///
public static readonly DependencyProperty BackStackProperty =
JournalNavigationScope.BackStackProperty.AddOwner(typeof(NavigationWindow));
///
/// DependencyProperty for ForwardStack property.
///
public static readonly DependencyProperty ForwardStackProperty =
JournalNavigationScope.ForwardStackProperty.AddOwner(typeof(NavigationWindow));
///
/// The DependencyProperty for the CanGoBack property.
/// Flags: None
/// Default Value: false
/// Readonly: true
///
public static readonly DependencyProperty CanGoBackProperty =
JournalNavigationScope.CanGoBackProperty.AddOwner(typeof(NavigationWindow));
///
/// The DependencyProperty for the CanGoForward property.
/// Flags: None
/// Default Value: false
/// Readonly: true
///
public static readonly DependencyProperty CanGoForwardProperty =
JournalNavigationScope.CanGoForwardProperty.AddOwner(typeof(NavigationWindow));
#endregion DependencyProperties
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
///
/// Constructs a window object
///
static NavigationWindow()
{
_dType = DependencyObjectType.FromSystemTypeInternal(typeof(NavigationWindow));
DefaultStyleKeyProperty.OverrideMetadata(
typeof(NavigationWindow),
new FrameworkPropertyMetadata(typeof(NavigationWindow)));
ContentProperty.OverrideMetadata(
typeof(NavigationWindow),
new FrameworkPropertyMetadata(
null,
new CoerceValueCallback(CoerceContent)));
SandboxExternalContentProperty.OverrideMetadata(
typeof(NavigationWindow),
new FrameworkPropertyMetadata(new PropertyChangedCallback(OnSandboxExternalContentPropertyChanged),
new CoerceValueCallback(CoerceSandBoxExternalContentValue)));
CommandManager.RegisterClassCommandBinding(
typeof(NavigationWindow),
new CommandBinding(
NavigationCommands.BrowseBack,
new ExecutedRoutedEventHandler(OnGoBack),
new CanExecuteRoutedEventHandler(OnQueryGoBack)));
CommandManager.RegisterClassCommandBinding(
typeof(NavigationWindow),
new CommandBinding(
NavigationCommands.BrowseForward,
new ExecutedRoutedEventHandler(OnGoForward),
new CanExecuteRoutedEventHandler(OnQueryGoForward)));
CommandManager.RegisterClassCommandBinding(
typeof(NavigationWindow),
new CommandBinding(NavigationCommands.NavigateJournal, new ExecutedRoutedEventHandler(OnNavigateJournal)));
CommandManager.RegisterClassCommandBinding(
typeof(NavigationWindow),
new CommandBinding(
NavigationCommands.Refresh,
new ExecutedRoutedEventHandler(OnRefresh),
new CanExecuteRoutedEventHandler(OnQueryRefresh)));
CommandManager.RegisterClassCommandBinding(
typeof(NavigationWindow),
new CommandBinding(
NavigationCommands.BrowseStop,
new ExecutedRoutedEventHandler(OnBrowseStop),
new CanExecuteRoutedEventHandler(OnQueryBrowseStop)));
}
///
/// Constructs a NavigationWindow object
///
///
/// Automatic determination of current Dispatcher. Use alternative constructor
/// that accepts a Dispatcher for best performance.
///
/// Initialize set _framelet to false and init commandlinks
///
public NavigationWindow()
{
this.Initialize();
}
///
/// The only scenarios where we're currently going to enable creation of Windows is with RootBrowserWindow.
/// Do not call it outside the scope of the RBW scenario
///
[SecurityCritical]
internal NavigationWindow(bool inRbw): base(inRbw)
{
this.Initialize();
}
private void Initialize()
{
Debug.Assert(_navigationService == null && _JNS == null);
_navigationService = new NavigationService(this);
_navigationService.BPReady += new BPReadyEventHandler(OnBPReady);
_JNS = new JournalNavigationScope(this);
_fFramelet = false;
}
#endregion Constructors
//------------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
#region Public Methods
#region IDownloader implementation
NavigationService IDownloader.Downloader
{
get { return _navigationService; }
}
#endregion IDownloader implementation
#region INavigator Methods
///
/// Navigates to the Uri and downloads the content.
///
/// URI of the application or content being navigated to.
/// bool indicating whether the navigation was successfully started or not
public bool Navigate(Uri source)
{
VerifyContextAndObjectState();
return NavigationService.Navigate(source);
}
///
/// This method navigates this window to the given Uri.
///
/// The URI to be navigated to.
///
/// Enables the develeoper to supply an extra object, that will be returned in the NavigatedEventArgs 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)
{
VerifyContextAndObjectState();
// Close/update PS844614 to investigate why we need to delay create WNC instead of
// creating and calling Navigate immediately here
return NavigationService.Navigate(source, extraData);
}
///
/// Navigates 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)
{
VerifyContextAndObjectState();
// Close/update PS844614 to investigate why we need to delay create WNC instead of
// creating and calling Navigate immediately here
return NavigationService.Navigate(content);
}
///
/// This method navigates this window to the
/// given Element.
///
/// The Element to be navigated to.
/// enables the develeoper to supply an extra object, that will be returned in the NavigatedEventArgs 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)
{
VerifyContextAndObjectState();
// Close/update PS844614 to investigate why we need to delay create WNC instead of
// creating and calling Navigate immediately here
return NavigationService.Navigate(content, extraData);
}
JournalNavigationScope INavigator.GetJournal(bool create)
{
Debug.Assert(_JNS != null);
return _JNS;
}
///
/// Navigates to the next entry in the Forward branch of the Journal, if one exists.
/// If there is no entry in the Forward stack of the journal, the method throws an
/// exception. The behavior is the same as clicking the Forward button.
///
///
/// There is no entry in the Forward stack of the journal to navigate to.
///
public void GoForward()
{
_JNS.GoForward();
}
///
/// Navigates to the previous entry in the Back branch of the Journal, if one exists.
/// The behavior is the same as clicking the Back button.
///
///
/// There is no entry in the Back stack of the journal to navigate to.
///
public void GoBack()
{
_JNS.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.
/// The behavior is the same as clicking the Stop button.
///
public void StopLoading()
{
VerifyContextAndObjectState();
if (InAppShutdown)
return;
NavigationService.StopLoading();
}
///
/// Reloads the current content. The behavior is the same as clicking the Refresh button.
///
public void Refresh()
{
VerifyContextAndObjectState();
if (InAppShutdown)
{
return;
}
NavigationService.Refresh();
}
///
/// 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)
{
VerifyContextAndObjectState();
NavigationService.AddBackEntry(state);
}
///
/// Remove the first JournalEntry from NavigationWindow's back history
///
public JournalEntry RemoveBackEntry()
{
return _JNS.RemoveBackEntry();
}
#endregion INavigator Methods
///
/// Called when style is actually applied.
///
///
/// HuWang
[SecurityCritical]
public override void OnApplyTemplate()
{
VerifyContextAndObjectState( );
base.OnApplyTemplate();
// base actually changed something. sniff
// around to see if there are any framelet
// objects we need to hook up.
// Get the root element of the style
FrameworkElement root = (this.GetVisualChild(0)) as FrameworkElement;
if (_navigationService != null)
{
_navigationService.VisualTreeAvailable(root);
}
// did we just apply the framelet style?
if ((root != null) && (root.Name == "NavigationBarRoot"))
{
if (!_fFramelet)
{
// transitioning to Framelet style
// HuWang
#if WCP_SYSTEM_THEMES_ENABLED
NativeMethods.WTA_OPTIONS wo = new NativeMethods.WTA_OPTIONS();
wo.dwFlags = (NativeMethods.WTNCA_NODRAWCAPTION | NativeMethods.WTNCA_NODRAWICON | NativeMethods.WTNCA_NOSYSMENU);
wo.dwMask = NativeMethods.WTNCA_VALIDBITS;
// call to turn off theme parts
UnsafeNativeMethods.SetWindowThemeAttribute( new HandleRef(this,Handle), NativeMethods.WINDOWTHEMEATTRIBUTETYPE.WTA_NONCLIENT, wo );
#endif // WCP_SYSTEM_THEMES_ENABLED
_fFramelet = true;
}
}
else
{
if (_fFramelet)
{
//
#if WCP_SYSTEM_THEMES_ENABLED
NativeMethods.WTA_OPTIONS wo = new NativeMethods.WTA_OPTIONS();
wo.dwFlags = 0;
wo.dwMask = NativeMethods.WTNCA_VALIDBITS;
// call to turn off theme parts
UnsafeNativeMethods.SetWindowThemeAttribute( new HandleRef(this,Handle), NativeMethods.WINDOWTHEMEATTRIBUTETYPE.WTA_NONCLIENT, wo );
#endif // WCP_SYSTEM_THEMES_ENABLED
// no longer in framelet mode
_fFramelet = false;
}
}
}
///
/// 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
if (_navigationService != null)
{
return !_navigationService.CanReloadFromUri;
}
return true;
}
#endregion Public Methods
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
#region Public Properties
///
/// NavigationWindow's NavigationService
///
public NavigationService NavigationService
{
#if DEBUG
[DebuggerStepThrough]
#endif
get
{
VerifyContextAndObjectState();
return _navigationService;
}
}
///
/// List of back journal entries
///
public IEnumerable BackStack
{
get { return _JNS.BackStack; }
}
///
/// List of forward journal entries
///
public IEnumerable ForwardStack
{
get { return _JNS.ForwardStack; }
}
///
/// Determines whether to show the default navigation UI.
///
public bool ShowsNavigationUI
{
get
{
VerifyContextAndObjectState();
return (bool)GetValue(ShowsNavigationUIProperty);
}
set
{
VerifyContextAndObjectState();
SetValue(ShowsNavigationUIProperty, value);
}
}
#region INavigator Properties
///
///
///
public static readonly DependencyProperty SourceProperty =
Frame.SourceProperty.AddOwner(
typeof(NavigationWindow),
new FrameworkPropertyMetadata(
(Uri)null,
new PropertyChangedCallback(OnSourcePropertyChanged),
new CoerceValueCallback(CoerceSource)));
private static object CoerceSource(DependencyObject d, object value)
{
NavigationWindow navWin = (NavigationWindow)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 (navWin._sourceUpdatedFromNavService)
{
Invariant.Assert(navWin._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( navWin._navigationService.Source != null ? !navWin._navigationService.Source.IsAbsoluteUri : true, "NavService's Source should always be relative");
return navWin._navigationService.Source;
}
return value;
}
///
/// Called when SourceProperty is invalidated on 'd'
///
private static void OnSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
NavigationWindow navWin = (NavigationWindow)d;
// Don't navigate if the Source value change is from NavService as a result of a navigation happening.
if (! navWin._sourceUpdatedFromNavService )
{
// We used not to need to resolve the Uri here because we did not allow navigating to a xaml rooted inside a NavWin.
// Now after we allow this, we will need to support navigating to the following xaml,
//
// When the xaml is rooted in a NavigationWindow with source pointing to a relative uri, the relative uri will need
// to be resolved with its baseuri unless it is a fragment navigation or there is no baseuri.
// In this case NavWin is always the root, parser will set the BaseUriProperty for the root element so NavWin doesn't need to
// implement IUriContext.
Uri uriToNavigate = BindUriHelper.GetUriToNavigate(navWin, d.GetValue(BaseUriHelper.BaseUriProperty) as Uri, (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.
navWin._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)
{
_sourceUpdatedFromNavService = true;
try
{
// If the Source DP is not set locally, or it is expression/animation,
// we do not want to SetValue on it when it is from GoBack/GoForward, journal navigation or cancel.
// Only when it comes from calling Navigate API directly, we consider it has the same pri as SetValue.
if (journalOrCancel)
{
bool hasModifiers, isExpression, isAnimated, isCoerced;
BaseValueSourceInternal valueSource = GetValueSource(SourceProperty, null, out hasModifiers, out isExpression, out isAnimated, out isCoerced);
if ((valueSource != BaseValueSourceInternal.Local) || isExpression || isAnimated)
{
CoerceValue(SourceProperty);
return;
}
}
SetValue(SourceProperty, _navigationService.Source);
}
finally
{
_sourceUpdatedFromNavService = false;
}
}
///
/// Uri for the page currently contained by the NavigationWindow
/// - Setting this property performs a navigation to the specified Uri.
/// - Getting this property when a navigation is not in progress returns the URI of
/// the current page. Getting this property when a navigation is in progress returns
/// the URI of the page being navigated to.
///
///
/// Supporting navigation via setting a property makes it possible to write
/// a NavigationWindow in markup and specify its initial content.
///
[DefaultValue(null)]
public Uri Source
{
get { return (Uri)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
///
/// Uri for the current page in the window. Getting this property always
/// returns the URI of the content thats currently displayed in the window,
/// regardless of whether a navigation is in progress or not.
///
public Uri CurrentSource
{
get
{
VerifyContextAndObjectState( );
return (_navigationService == null ? null : _navigationService.CurrentSource);
}
}
///
/// Tells whether there are any entries in the Forward branch of the Journal.
/// This property can be used to enable the Forward button.
///
public bool CanGoForward
{
get
{
return _JNS.CanGoForward;
}
}
///
/// Tells whether there are any entries in the Back branch of the Journal.
/// This property can be used to enable the Back button.
///
public bool CanGoBack
{
get
{
return _JNS.CanGoBack;
}
}
#endregion INavigator Properties
#endregion Public Properties
//-----------------------------------------------------
//
// Public Events
//
//------------------------------------------------------
#region Public Events
///
/// 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
{
VerifyContextAndObjectState( );
NavigationService.Navigating += value;
}
remove
{
VerifyContextAndObjectState( );
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
{
VerifyContextAndObjectState( );
NavigationService.NavigationProgress += value;
}
remove
{
VerifyContextAndObjectState( );
NavigationService.NavigationProgress -= value;
}
}
///
/// Raised when 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
{
VerifyContextAndObjectState();
NavigationService.NavigationFailed += value;
}
remove
{
VerifyContextAndObjectState();
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
{
VerifyContextAndObjectState( );
NavigationService.Navigated += value;
}
remove
{
VerifyContextAndObjectState( );
NavigationService.Navigated -= value;
}
}
///
/// 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 window, 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
{
VerifyContextAndObjectState( );
NavigationService.LoadCompleted += value;
}
remove
{
VerifyContextAndObjectState( );
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
{
VerifyContextAndObjectState( );
NavigationService.NavigationStopped += value;
}
remove
{
VerifyContextAndObjectState( );
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
{
VerifyContextAndObjectState();
NavigationService.FragmentNavigation += value;
}
remove
{
VerifyContextAndObjectState();
NavigationService.FragmentNavigation -= value;
}
}
#endregion Public Events
//-----------------------------------------------------
//
// Protected Methods
//
//-----------------------------------------------------
#region Protected Methods
///
/// Creates AutomationPeer ( )
///
protected override AutomationPeer OnCreateAutomationPeer()
{
return new NavigationWindowAutomationPeer(this);
}
///
/// Add an object child to this control
///
protected override void AddChild(object value)
{
throw new InvalidOperationException(SR.Get(SRID.NoAddChild));
}
///
/// Add a text string to this control
///
protected override void AddText(string text)
{
XamlSerializerUtil.ThrowIfNonWhiteSpaceInAddText(text, this);
}
///
/// This even fires when window is closed. This event is non cancelable and is
/// for user infromational purposes
///
///
/// This method follows the .Net programming guideline of having a protected virtual
/// method that raises an event, to provide a convenience for developers that subclass
/// the event. If you override this method - you need to call Base.OnClosed(...) for
/// the corresponding event to be raised.
///
protected override void OnClosed(EventArgs args)
{
VerifyContextAndObjectState( );
// We override OnClosed here to Dispose of the NCTree.
base.OnClosed( args ) ;
// detach the event handlers on the NC
if(_navigationService != null)
_navigationService.Dispose();
}
#endregion Protected Methods
//-----------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
#region Internal Methods
internal override void OnPreApplyTemplate()
{
base.OnPreApplyTemplate();
// This causes the Journal instance to be created. BackStackProperty and ForwardStackProperty
// have to be set before the navigation chrome data-binds to them but after RootBrowserWindow
// .SetJournalForBrowserInterop() is called.
_JNS.EnsureJournal();
}
#region IJournalNavigationScopeHost Members
void IJournalNavigationScopeHost.VerifyContextAndObjectState()
{
VerifyContextAndObjectState();
}
void IJournalNavigationScopeHost.OnJournalAvailable()
{
}
bool IJournalNavigationScopeHost.GoBackOverride()
{
return false; // not overriding here; RBW does
}
bool IJournalNavigationScopeHost.GoForwardOverride()
{
return false;
}
NavigationService IJournalNavigationScopeHost.NavigationService
{
get { return _navigationService; }
}
#endregion
#region INavigatorImpl members
// Note: OnSourceUpdatedFromNavService is next to the other Source-related members of NW.
Visual INavigatorImpl.FindRootViewer()
{
return NavigationHelper.FindRootViewer(this, "PART_NavWinCP");
}
#endregion INavigatorImpl
#endregion Internal Methods
//-----------------------------------------------------
//
// Internal Properties
//
//------------------------------------------------------
#region Internal Properties
///
/// Journal for the window. Maintains Back/Forward navigation history.
///
#if DEBUG
// to prevent creating the Journal instance prematurely while debugging
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
#endif
internal Journal Journal
{
get
{
return _JNS.Journal;
}
}
internal JournalNavigationScope JournalNavigationScope
{
#if DEBUG
[DebuggerStepThrough]
#endif
get
{
return _JNS;
}
}
#endregion Internal Properties
#region Private Methods
//------------------------------------------------------
//
// Private Methods
//
//-----------------------------------------------------
private static object CoerceContent(DependencyObject d, object value)
{
// whenever content changes, defer the change until the Navigate comes in
NavigationWindow w = (NavigationWindow) d;
if (w.NavigationService.Content == value)
{
return value;
}
w.Navigate(value);
return DependencyProperty.UnsetValue;
}
private void OnBPReady(Object sender, BPReadyEventArgs e)
{
// set Window.ContentProperty
Content = e.Content;
}
private static void OnGoBack(object sender, ExecutedRoutedEventArgs args)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
nw.GoBack();
}
private static void OnQueryGoBack(object sender, CanExecuteRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
e.CanExecute = nw.CanGoBack;
e.ContinueRouting = !nw.CanGoBack;
}
private static void OnGoForward(object sender, ExecutedRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
nw.GoForward();
}
private static void OnQueryGoForward(object sender, CanExecuteRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
e.CanExecute = nw.CanGoForward;
e.ContinueRouting = !nw.CanGoForward;
}
private static void OnRefresh(object sender, ExecutedRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
nw.Refresh();
}
private static void OnQueryRefresh(object sender, CanExecuteRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
e.CanExecute = nw.Content != null;
}
private static void OnBrowseStop(object sender, ExecutedRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
nw.StopLoading();
}
private static void OnQueryBrowseStop(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private static void OnNavigateJournal(object sender, ExecutedRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
FrameworkElement journalEntryUIElem = e.Parameter as FrameworkElement;
if (journalEntryUIElem != null)
{
// Get journal entry from MenuItem
JournalEntry je = journalEntryUIElem.DataContext as JournalEntry;
if (je != null)
{
nw.JournalNavigationScope.NavigateToEntry(je);
}
}
}
#endregion Private Methods
#region Private Properties
//------------------------------------------------------
//
// Private Properties
//
//-----------------------------------------------------
private bool InAppShutdown
{
get
{
return System.Windows.Application.IsShuttingDown;
}
}
//
// This property
// 1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject
// 2. This is a performance optimization
//
internal override int EffectiveValuesInitialSize
{
get { return 42; }
}
#endregion Private Properties
//-----------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
#region Private Fields
private NavigationService _navigationService;
private JournalNavigationScope _JNS;
private bool _sourceUpdatedFromNavService;
// Framelet stuff
private bool _fFramelet;
#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
}
#endregion NavigationWindow Class
}
// 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:
// The NavigationWindow extends the base window class to provide Navigation functionality.
//
// Using the navigation window it's possible to set the Uri of a Navigation Window, and the
// Content region of the window displays the markup at that Uri.
//
// It's also possible to change the outermost "chrome" of markup that hosts the content region
// of the window.
//
// History:
// 10/27/01: mihaii Created
// 05/21/03: marka Moved over to WCP dir. Made match spec, updated comments.
// 11/14/05: ChangoV "Island Frame" implementation. Journaling-related operations factored out into
// JournalNavigationScope.
//
//---------------------------------------------------------------------------
using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using MS.Internal;
using MS.Internal.AppModel;
using MS.Internal.KnownBoxes;
using MS.Internal.Utility;
using MS.Utility;
using MS.Win32;
using MS.Internal.PresentationFramework;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Navigation;
using System.Windows.Markup;
using System.Windows.Threading;
using System.Windows.Documents;
namespace System.Windows.Navigation
{
#region NavigationWindow Class
///
/// Public class NavigationWindow
///
///
[ContentProperty]
[TemplatePart(Name = "PART_NavWinCP", Type = typeof(ContentPresenter))]
public class NavigationWindow : Window, INavigator, INavigatorImpl, IDownloader, IJournalNavigationScopeHost
{
#region DependencyProperties
///
/// DependencyProperty for SandboxExternalContent property.
///
public static readonly DependencyProperty SandboxExternalContentProperty =
Frame.SandboxExternalContentProperty.AddOwner(typeof(NavigationWindow));
///
/// 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)
{
NavigationWindow window = (NavigationWindow)d;
// 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)
{
window.NavigationService.Refresh();
}
}
private static object CoerceSandBoxExternalContentValue(DependencyObject d, object value)
{
// This feature is disabled in partial trust due to a P3P violation
bool fSandBox = (bool)value;
SecurityHelper.ThrowExceptionIfSettingTrueInPartialTrust(ref fSandBox);
return fSandBox;
}
///
/// DependencyProperty for ShowsNavigationUI property.
///
public static readonly DependencyProperty ShowsNavigationUIProperty =
DependencyProperty.Register(
"ShowsNavigationUI",
typeof(bool),
typeof(NavigationWindow),
new FrameworkPropertyMetadata(BooleanBoxes.TrueBox));
///
/// DependencyProperty for BackStack property.
///
public static readonly DependencyProperty BackStackProperty =
JournalNavigationScope.BackStackProperty.AddOwner(typeof(NavigationWindow));
///
/// DependencyProperty for ForwardStack property.
///
public static readonly DependencyProperty ForwardStackProperty =
JournalNavigationScope.ForwardStackProperty.AddOwner(typeof(NavigationWindow));
///
/// The DependencyProperty for the CanGoBack property.
/// Flags: None
/// Default Value: false
/// Readonly: true
///
public static readonly DependencyProperty CanGoBackProperty =
JournalNavigationScope.CanGoBackProperty.AddOwner(typeof(NavigationWindow));
///
/// The DependencyProperty for the CanGoForward property.
/// Flags: None
/// Default Value: false
/// Readonly: true
///
public static readonly DependencyProperty CanGoForwardProperty =
JournalNavigationScope.CanGoForwardProperty.AddOwner(typeof(NavigationWindow));
#endregion DependencyProperties
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
///
/// Constructs a window object
///
static NavigationWindow()
{
_dType = DependencyObjectType.FromSystemTypeInternal(typeof(NavigationWindow));
DefaultStyleKeyProperty.OverrideMetadata(
typeof(NavigationWindow),
new FrameworkPropertyMetadata(typeof(NavigationWindow)));
ContentProperty.OverrideMetadata(
typeof(NavigationWindow),
new FrameworkPropertyMetadata(
null,
new CoerceValueCallback(CoerceContent)));
SandboxExternalContentProperty.OverrideMetadata(
typeof(NavigationWindow),
new FrameworkPropertyMetadata(new PropertyChangedCallback(OnSandboxExternalContentPropertyChanged),
new CoerceValueCallback(CoerceSandBoxExternalContentValue)));
CommandManager.RegisterClassCommandBinding(
typeof(NavigationWindow),
new CommandBinding(
NavigationCommands.BrowseBack,
new ExecutedRoutedEventHandler(OnGoBack),
new CanExecuteRoutedEventHandler(OnQueryGoBack)));
CommandManager.RegisterClassCommandBinding(
typeof(NavigationWindow),
new CommandBinding(
NavigationCommands.BrowseForward,
new ExecutedRoutedEventHandler(OnGoForward),
new CanExecuteRoutedEventHandler(OnQueryGoForward)));
CommandManager.RegisterClassCommandBinding(
typeof(NavigationWindow),
new CommandBinding(NavigationCommands.NavigateJournal, new ExecutedRoutedEventHandler(OnNavigateJournal)));
CommandManager.RegisterClassCommandBinding(
typeof(NavigationWindow),
new CommandBinding(
NavigationCommands.Refresh,
new ExecutedRoutedEventHandler(OnRefresh),
new CanExecuteRoutedEventHandler(OnQueryRefresh)));
CommandManager.RegisterClassCommandBinding(
typeof(NavigationWindow),
new CommandBinding(
NavigationCommands.BrowseStop,
new ExecutedRoutedEventHandler(OnBrowseStop),
new CanExecuteRoutedEventHandler(OnQueryBrowseStop)));
}
///
/// Constructs a NavigationWindow object
///
///
/// Automatic determination of current Dispatcher. Use alternative constructor
/// that accepts a Dispatcher for best performance.
///
/// Initialize set _framelet to false and init commandlinks
///
public NavigationWindow()
{
this.Initialize();
}
///
/// The only scenarios where we're currently going to enable creation of Windows is with RootBrowserWindow.
/// Do not call it outside the scope of the RBW scenario
///
[SecurityCritical]
internal NavigationWindow(bool inRbw): base(inRbw)
{
this.Initialize();
}
private void Initialize()
{
Debug.Assert(_navigationService == null && _JNS == null);
_navigationService = new NavigationService(this);
_navigationService.BPReady += new BPReadyEventHandler(OnBPReady);
_JNS = new JournalNavigationScope(this);
_fFramelet = false;
}
#endregion Constructors
//------------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
#region Public Methods
#region IDownloader implementation
NavigationService IDownloader.Downloader
{
get { return _navigationService; }
}
#endregion IDownloader implementation
#region INavigator Methods
///
/// Navigates to the Uri and downloads the content.
///
/// URI of the application or content being navigated to.
/// bool indicating whether the navigation was successfully started or not
public bool Navigate(Uri source)
{
VerifyContextAndObjectState();
return NavigationService.Navigate(source);
}
///
/// This method navigates this window to the given Uri.
///
/// The URI to be navigated to.
///
/// Enables the develeoper to supply an extra object, that will be returned in the NavigatedEventArgs 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)
{
VerifyContextAndObjectState();
// Close/update PS844614 to investigate why we need to delay create WNC instead of
// creating and calling Navigate immediately here
return NavigationService.Navigate(source, extraData);
}
///
/// Navigates 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)
{
VerifyContextAndObjectState();
// Close/update PS844614 to investigate why we need to delay create WNC instead of
// creating and calling Navigate immediately here
return NavigationService.Navigate(content);
}
///
/// This method navigates this window to the
/// given Element.
///
/// The Element to be navigated to.
/// enables the develeoper to supply an extra object, that will be returned in the NavigatedEventArgs 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)
{
VerifyContextAndObjectState();
// Close/update PS844614 to investigate why we need to delay create WNC instead of
// creating and calling Navigate immediately here
return NavigationService.Navigate(content, extraData);
}
JournalNavigationScope INavigator.GetJournal(bool create)
{
Debug.Assert(_JNS != null);
return _JNS;
}
///
/// Navigates to the next entry in the Forward branch of the Journal, if one exists.
/// If there is no entry in the Forward stack of the journal, the method throws an
/// exception. The behavior is the same as clicking the Forward button.
///
///
/// There is no entry in the Forward stack of the journal to navigate to.
///
public void GoForward()
{
_JNS.GoForward();
}
///
/// Navigates to the previous entry in the Back branch of the Journal, if one exists.
/// The behavior is the same as clicking the Back button.
///
///
/// There is no entry in the Back stack of the journal to navigate to.
///
public void GoBack()
{
_JNS.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.
/// The behavior is the same as clicking the Stop button.
///
public void StopLoading()
{
VerifyContextAndObjectState();
if (InAppShutdown)
return;
NavigationService.StopLoading();
}
///
/// Reloads the current content. The behavior is the same as clicking the Refresh button.
///
public void Refresh()
{
VerifyContextAndObjectState();
if (InAppShutdown)
{
return;
}
NavigationService.Refresh();
}
///
/// 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)
{
VerifyContextAndObjectState();
NavigationService.AddBackEntry(state);
}
///
/// Remove the first JournalEntry from NavigationWindow's back history
///
public JournalEntry RemoveBackEntry()
{
return _JNS.RemoveBackEntry();
}
#endregion INavigator Methods
///
/// Called when style is actually applied.
///
///
/// HuWang
[SecurityCritical]
public override void OnApplyTemplate()
{
VerifyContextAndObjectState( );
base.OnApplyTemplate();
// base actually changed something. sniff
// around to see if there are any framelet
// objects we need to hook up.
// Get the root element of the style
FrameworkElement root = (this.GetVisualChild(0)) as FrameworkElement;
if (_navigationService != null)
{
_navigationService.VisualTreeAvailable(root);
}
// did we just apply the framelet style?
if ((root != null) && (root.Name == "NavigationBarRoot"))
{
if (!_fFramelet)
{
// transitioning to Framelet style
// HuWang
#if WCP_SYSTEM_THEMES_ENABLED
NativeMethods.WTA_OPTIONS wo = new NativeMethods.WTA_OPTIONS();
wo.dwFlags = (NativeMethods.WTNCA_NODRAWCAPTION | NativeMethods.WTNCA_NODRAWICON | NativeMethods.WTNCA_NOSYSMENU);
wo.dwMask = NativeMethods.WTNCA_VALIDBITS;
// call to turn off theme parts
UnsafeNativeMethods.SetWindowThemeAttribute( new HandleRef(this,Handle), NativeMethods.WINDOWTHEMEATTRIBUTETYPE.WTA_NONCLIENT, wo );
#endif // WCP_SYSTEM_THEMES_ENABLED
_fFramelet = true;
}
}
else
{
if (_fFramelet)
{
//
#if WCP_SYSTEM_THEMES_ENABLED
NativeMethods.WTA_OPTIONS wo = new NativeMethods.WTA_OPTIONS();
wo.dwFlags = 0;
wo.dwMask = NativeMethods.WTNCA_VALIDBITS;
// call to turn off theme parts
UnsafeNativeMethods.SetWindowThemeAttribute( new HandleRef(this,Handle), NativeMethods.WINDOWTHEMEATTRIBUTETYPE.WTA_NONCLIENT, wo );
#endif // WCP_SYSTEM_THEMES_ENABLED
// no longer in framelet mode
_fFramelet = false;
}
}
}
///
/// 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
if (_navigationService != null)
{
return !_navigationService.CanReloadFromUri;
}
return true;
}
#endregion Public Methods
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
#region Public Properties
///
/// NavigationWindow's NavigationService
///
public NavigationService NavigationService
{
#if DEBUG
[DebuggerStepThrough]
#endif
get
{
VerifyContextAndObjectState();
return _navigationService;
}
}
///
/// List of back journal entries
///
public IEnumerable BackStack
{
get { return _JNS.BackStack; }
}
///
/// List of forward journal entries
///
public IEnumerable ForwardStack
{
get { return _JNS.ForwardStack; }
}
///
/// Determines whether to show the default navigation UI.
///
public bool ShowsNavigationUI
{
get
{
VerifyContextAndObjectState();
return (bool)GetValue(ShowsNavigationUIProperty);
}
set
{
VerifyContextAndObjectState();
SetValue(ShowsNavigationUIProperty, value);
}
}
#region INavigator Properties
///
///
///
public static readonly DependencyProperty SourceProperty =
Frame.SourceProperty.AddOwner(
typeof(NavigationWindow),
new FrameworkPropertyMetadata(
(Uri)null,
new PropertyChangedCallback(OnSourcePropertyChanged),
new CoerceValueCallback(CoerceSource)));
private static object CoerceSource(DependencyObject d, object value)
{
NavigationWindow navWin = (NavigationWindow)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 (navWin._sourceUpdatedFromNavService)
{
Invariant.Assert(navWin._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( navWin._navigationService.Source != null ? !navWin._navigationService.Source.IsAbsoluteUri : true, "NavService's Source should always be relative");
return navWin._navigationService.Source;
}
return value;
}
///
/// Called when SourceProperty is invalidated on 'd'
///
private static void OnSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
NavigationWindow navWin = (NavigationWindow)d;
// Don't navigate if the Source value change is from NavService as a result of a navigation happening.
if (! navWin._sourceUpdatedFromNavService )
{
// We used not to need to resolve the Uri here because we did not allow navigating to a xaml rooted inside a NavWin.
// Now after we allow this, we will need to support navigating to the following xaml,
//
// When the xaml is rooted in a NavigationWindow with source pointing to a relative uri, the relative uri will need
// to be resolved with its baseuri unless it is a fragment navigation or there is no baseuri.
// In this case NavWin is always the root, parser will set the BaseUriProperty for the root element so NavWin doesn't need to
// implement IUriContext.
Uri uriToNavigate = BindUriHelper.GetUriToNavigate(navWin, d.GetValue(BaseUriHelper.BaseUriProperty) as Uri, (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.
navWin._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)
{
_sourceUpdatedFromNavService = true;
try
{
// If the Source DP is not set locally, or it is expression/animation,
// we do not want to SetValue on it when it is from GoBack/GoForward, journal navigation or cancel.
// Only when it comes from calling Navigate API directly, we consider it has the same pri as SetValue.
if (journalOrCancel)
{
bool hasModifiers, isExpression, isAnimated, isCoerced;
BaseValueSourceInternal valueSource = GetValueSource(SourceProperty, null, out hasModifiers, out isExpression, out isAnimated, out isCoerced);
if ((valueSource != BaseValueSourceInternal.Local) || isExpression || isAnimated)
{
CoerceValue(SourceProperty);
return;
}
}
SetValue(SourceProperty, _navigationService.Source);
}
finally
{
_sourceUpdatedFromNavService = false;
}
}
///
/// Uri for the page currently contained by the NavigationWindow
/// - Setting this property performs a navigation to the specified Uri.
/// - Getting this property when a navigation is not in progress returns the URI of
/// the current page. Getting this property when a navigation is in progress returns
/// the URI of the page being navigated to.
///
///
/// Supporting navigation via setting a property makes it possible to write
/// a NavigationWindow in markup and specify its initial content.
///
[DefaultValue(null)]
public Uri Source
{
get { return (Uri)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
///
/// Uri for the current page in the window. Getting this property always
/// returns the URI of the content thats currently displayed in the window,
/// regardless of whether a navigation is in progress or not.
///
public Uri CurrentSource
{
get
{
VerifyContextAndObjectState( );
return (_navigationService == null ? null : _navigationService.CurrentSource);
}
}
///
/// Tells whether there are any entries in the Forward branch of the Journal.
/// This property can be used to enable the Forward button.
///
public bool CanGoForward
{
get
{
return _JNS.CanGoForward;
}
}
///
/// Tells whether there are any entries in the Back branch of the Journal.
/// This property can be used to enable the Back button.
///
public bool CanGoBack
{
get
{
return _JNS.CanGoBack;
}
}
#endregion INavigator Properties
#endregion Public Properties
//-----------------------------------------------------
//
// Public Events
//
//------------------------------------------------------
#region Public Events
///
/// 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
{
VerifyContextAndObjectState( );
NavigationService.Navigating += value;
}
remove
{
VerifyContextAndObjectState( );
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
{
VerifyContextAndObjectState( );
NavigationService.NavigationProgress += value;
}
remove
{
VerifyContextAndObjectState( );
NavigationService.NavigationProgress -= value;
}
}
///
/// Raised when 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
{
VerifyContextAndObjectState();
NavigationService.NavigationFailed += value;
}
remove
{
VerifyContextAndObjectState();
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
{
VerifyContextAndObjectState( );
NavigationService.Navigated += value;
}
remove
{
VerifyContextAndObjectState( );
NavigationService.Navigated -= value;
}
}
///
/// 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 window, 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
{
VerifyContextAndObjectState( );
NavigationService.LoadCompleted += value;
}
remove
{
VerifyContextAndObjectState( );
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
{
VerifyContextAndObjectState( );
NavigationService.NavigationStopped += value;
}
remove
{
VerifyContextAndObjectState( );
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
{
VerifyContextAndObjectState();
NavigationService.FragmentNavigation += value;
}
remove
{
VerifyContextAndObjectState();
NavigationService.FragmentNavigation -= value;
}
}
#endregion Public Events
//-----------------------------------------------------
//
// Protected Methods
//
//-----------------------------------------------------
#region Protected Methods
///
/// Creates AutomationPeer ( )
///
protected override AutomationPeer OnCreateAutomationPeer()
{
return new NavigationWindowAutomationPeer(this);
}
///
/// Add an object child to this control
///
protected override void AddChild(object value)
{
throw new InvalidOperationException(SR.Get(SRID.NoAddChild));
}
///
/// Add a text string to this control
///
protected override void AddText(string text)
{
XamlSerializerUtil.ThrowIfNonWhiteSpaceInAddText(text, this);
}
///
/// This even fires when window is closed. This event is non cancelable and is
/// for user infromational purposes
///
///
/// This method follows the .Net programming guideline of having a protected virtual
/// method that raises an event, to provide a convenience for developers that subclass
/// the event. If you override this method - you need to call Base.OnClosed(...) for
/// the corresponding event to be raised.
///
protected override void OnClosed(EventArgs args)
{
VerifyContextAndObjectState( );
// We override OnClosed here to Dispose of the NCTree.
base.OnClosed( args ) ;
// detach the event handlers on the NC
if(_navigationService != null)
_navigationService.Dispose();
}
#endregion Protected Methods
//-----------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
#region Internal Methods
internal override void OnPreApplyTemplate()
{
base.OnPreApplyTemplate();
// This causes the Journal instance to be created. BackStackProperty and ForwardStackProperty
// have to be set before the navigation chrome data-binds to them but after RootBrowserWindow
// .SetJournalForBrowserInterop() is called.
_JNS.EnsureJournal();
}
#region IJournalNavigationScopeHost Members
void IJournalNavigationScopeHost.VerifyContextAndObjectState()
{
VerifyContextAndObjectState();
}
void IJournalNavigationScopeHost.OnJournalAvailable()
{
}
bool IJournalNavigationScopeHost.GoBackOverride()
{
return false; // not overriding here; RBW does
}
bool IJournalNavigationScopeHost.GoForwardOverride()
{
return false;
}
NavigationService IJournalNavigationScopeHost.NavigationService
{
get { return _navigationService; }
}
#endregion
#region INavigatorImpl members
// Note: OnSourceUpdatedFromNavService is next to the other Source-related members of NW.
Visual INavigatorImpl.FindRootViewer()
{
return NavigationHelper.FindRootViewer(this, "PART_NavWinCP");
}
#endregion INavigatorImpl
#endregion Internal Methods
//-----------------------------------------------------
//
// Internal Properties
//
//------------------------------------------------------
#region Internal Properties
///
/// Journal for the window. Maintains Back/Forward navigation history.
///
#if DEBUG
// to prevent creating the Journal instance prematurely while debugging
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
#endif
internal Journal Journal
{
get
{
return _JNS.Journal;
}
}
internal JournalNavigationScope JournalNavigationScope
{
#if DEBUG
[DebuggerStepThrough]
#endif
get
{
return _JNS;
}
}
#endregion Internal Properties
#region Private Methods
//------------------------------------------------------
//
// Private Methods
//
//-----------------------------------------------------
private static object CoerceContent(DependencyObject d, object value)
{
// whenever content changes, defer the change until the Navigate comes in
NavigationWindow w = (NavigationWindow) d;
if (w.NavigationService.Content == value)
{
return value;
}
w.Navigate(value);
return DependencyProperty.UnsetValue;
}
private void OnBPReady(Object sender, BPReadyEventArgs e)
{
// set Window.ContentProperty
Content = e.Content;
}
private static void OnGoBack(object sender, ExecutedRoutedEventArgs args)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
nw.GoBack();
}
private static void OnQueryGoBack(object sender, CanExecuteRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
e.CanExecute = nw.CanGoBack;
e.ContinueRouting = !nw.CanGoBack;
}
private static void OnGoForward(object sender, ExecutedRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
nw.GoForward();
}
private static void OnQueryGoForward(object sender, CanExecuteRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
e.CanExecute = nw.CanGoForward;
e.ContinueRouting = !nw.CanGoForward;
}
private static void OnRefresh(object sender, ExecutedRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
nw.Refresh();
}
private static void OnQueryRefresh(object sender, CanExecuteRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
e.CanExecute = nw.Content != null;
}
private static void OnBrowseStop(object sender, ExecutedRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
nw.StopLoading();
}
private static void OnQueryBrowseStop(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private static void OnNavigateJournal(object sender, ExecutedRoutedEventArgs e)
{
NavigationWindow nw = sender as NavigationWindow;
Debug.Assert(nw != null, "sender must be of type NavigationWindow.");
FrameworkElement journalEntryUIElem = e.Parameter as FrameworkElement;
if (journalEntryUIElem != null)
{
// Get journal entry from MenuItem
JournalEntry je = journalEntryUIElem.DataContext as JournalEntry;
if (je != null)
{
nw.JournalNavigationScope.NavigateToEntry(je);
}
}
}
#endregion Private Methods
#region Private Properties
//------------------------------------------------------
//
// Private Properties
//
//-----------------------------------------------------
private bool InAppShutdown
{
get
{
return System.Windows.Application.IsShuttingDown;
}
}
//
// This property
// 1. Finds the correct initial size for the _effectiveValues store on the current DependencyObject
// 2. This is a performance optimization
//
internal override int EffectiveValuesInitialSize
{
get { return 42; }
}
#endregion Private Properties
//-----------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
#region Private Fields
private NavigationService _navigationService;
private JournalNavigationScope _JNS;
private bool _sourceUpdatedFromNavService;
// Framelet stuff
private bool _fFramelet;
#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
}
#endregion NavigationWindow Class
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- MemoryStream.cs
- ZipIOLocalFileHeader.cs
- LongTypeConverter.cs
- KnownColorTable.cs
- DesignerSerializationOptionsAttribute.cs
- FlowDocumentScrollViewerAutomationPeer.cs
- Int16AnimationUsingKeyFrames.cs
- BindingsCollection.cs
- SplashScreen.cs
- DmlSqlGenerator.cs
- AvTraceFormat.cs
- HighlightComponent.cs
- Expression.cs
- OptimalTextSource.cs
- CodeExpressionCollection.cs
- XhtmlBasicLabelAdapter.cs
- CachedFontFamily.cs
- SocketException.cs
- Localizer.cs
- MsmqHostedTransportConfiguration.cs
- InfiniteTimeSpanConverter.cs
- LingerOption.cs
- Journaling.cs
- ConsoleCancelEventArgs.cs
- EntryPointNotFoundException.cs
- GraphicsPath.cs
- ActiveXHost.cs
- DefaultValueConverter.cs
- HostDesigntimeLicenseContext.cs
- DocumentViewerConstants.cs
- Point3D.cs
- ButtonColumn.cs
- LambdaCompiler.Lambda.cs
- DataServiceStreamProviderWrapper.cs
- IgnoreSectionHandler.cs
- XmlSchemaComplexContent.cs
- LifetimeServices.cs
- DefaultShape.cs
- CodeGenerator.cs
- SizeChangedEventArgs.cs
- Visual3DCollection.cs
- MatrixTransform.cs
- M3DUtil.cs
- ToolStripItemClickedEventArgs.cs
- MessageQuerySet.cs
- JavaScriptObjectDeserializer.cs
- ClientTargetCollection.cs
- GlobalProxySelection.cs
- FileRecordSequence.cs
- DbMetaDataColumnNames.cs
- XmlBufferReader.cs
- SortAction.cs
- MultipartContentParser.cs
- ServiceErrorHandler.cs
- QilGenerator.cs
- XmlMemberMapping.cs
- PropertyDescriptorGridEntry.cs
- StatusBarDrawItemEvent.cs
- BinaryMessageEncodingBindingElement.cs
- PriorityQueue.cs
- ManifestBasedResourceGroveler.cs
- BindingsCollection.cs
- Permission.cs
- OracleColumn.cs
- OptionUsage.cs
- CommonProperties.cs
- DbgUtil.cs
- NativeObjectSecurity.cs
- CorePropertiesFilter.cs
- ViewLoader.cs
- TextDecoration.cs
- WebPartDisplayModeCancelEventArgs.cs
- PinnedBufferMemoryStream.cs
- XmlWriterDelegator.cs
- AssemblyResourceLoader.cs
- FlowDocumentReaderAutomationPeer.cs
- RoutingEndpointTrait.cs
- SqlProvider.cs
- Pen.cs
- SerializationTrace.cs
- OledbConnectionStringbuilder.cs
- ExpressionPrinter.cs
- XMLDiffLoader.cs
- Slider.cs
- RepeatBehavior.cs
- altserialization.cs
- ListViewDeletedEventArgs.cs
- OperatorExpressions.cs
- _ShellExpression.cs
- GACMembershipCondition.cs
- RotateTransform.cs
- BuildResultCache.cs
- EntityDataSourceViewSchema.cs
- OutputBuffer.cs
- SchemaObjectWriter.cs
- WindowsScroll.cs
- RSAPKCS1KeyExchangeFormatter.cs
- LineProperties.cs
- ReadOnlyAttribute.cs
- OleDbWrapper.cs