Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Controls / FlowDocumentReader.cs / 1305600 / FlowDocumentReader.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; // Object using System.Collections; // IEnumerator using System.Collections.ObjectModel; // ReadOnlyCollectionusing System.Security; // SecurityCritical using System.Windows.Automation.Peers; // AutomationPeer using System.Windows.Data; // BindingOperations using System.Windows.Controls.Primitives; // PlacementMode using System.Windows.Documents; // FlowDocument using System.Windows.Input; // KeyEventArgs using System.Windows.Media; // ScaleTransform, VisualTreeHelper using System.Windows.Markup; // IAddChild using System.Windows.Threading; // Dispatcher using MS.Internal; // Invariant, DoubleUtil using MS.Internal.Commands; // CommandHelpers using MS.Internal.Controls; // EmptyEnumerator using MS.Internal.Documents; // FindToolBar using MS.Internal.KnownBoxes; // BooleanBoxes using MS.Internal.AppModel; // IJournalState namespace System.Windows.Controls { /// /// FlowDocumentReader provides a full user experience for consuming text content. /// It will be used as the default viewer for loose XAML or containers that contain /// text content, and can be styled and re-used by developers for use within their applications. /// [TemplatePart(Name = "PART_ContentHost", Type = typeof(Decorator))] [TemplatePart(Name = "PART_FindToolBarHost", Type = typeof(Decorator))] [ContentProperty("Document")] public class FlowDocumentReader : Control, IAddChild, IJournalState { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Static Constructor /// static FlowDocumentReader() { DefaultStyleKeyProperty.OverrideMetadata( typeof(FlowDocumentReader), new FrameworkPropertyMetadata(new ComponentResourceKey(typeof(PresentationUIStyleResources), "PUIFlowDocumentReader"))); _dType = DependencyObjectType.FromSystemTypeInternal(typeof(FlowDocumentReader)); TextBoxBase.SelectionBrushProperty.OverrideMetadata(typeof(FlowDocumentReader), new FrameworkPropertyMetadata(new PropertyChangedCallback(UpdateCaretElement))); TextBoxBase.SelectionOpacityProperty.OverrideMetadata(typeof(FlowDocumentReader), new FrameworkPropertyMetadata(new PropertyChangedCallback(UpdateCaretElement))); CreateCommandBindings(); EventManager.RegisterClassHandler(typeof(FlowDocumentReader), Keyboard.KeyDownEvent, new KeyEventHandler(KeyDownHandler), true); } ////// Default Constructor /// public FlowDocumentReader() : base() { } #endregion Constructors //-------------------------------------------------------------------- // // Public Methods // //------------------------------------------------------------------- #region Public Methods ////// Build Visual tree /// public override void OnApplyTemplate() { base.OnApplyTemplate(); // Initialize ContentHost. // If old ContentHost is enabled, disable it first to ensure appropriate cleanup. if (CurrentViewer != null) { DetachViewer(CurrentViewer); _contentHost.Child = null; } _contentHost = GetTemplateChild(_contentHostTemplateName) as Decorator; if (_contentHost != null) { if (_contentHost.Child != null) { throw new NotSupportedException(SR.Get(SRID.FlowDocumentReaderDecoratorMarkedAsContentHostMustHaveNoContent)); } SwitchViewingModeCore(ViewingMode); } // Initialize FindTooBar host. // If old FindToolBar is enabled, disable it first to ensure appropriate cleanup. if (FindToolBar != null) { ToggleFindToolBar(false); } _findToolBarHost = GetTemplateChild(_findToolBarHostTemplateName) as Decorator; _findButton = GetTemplateChild(_findButtonTemplateName) as ToggleButton; } ////// Whether the master page can be moved to the specified page. /// /// Page number. public bool CanGoToPage(int pageNumber) { bool canGoToPage = false; if (CurrentViewer != null) { canGoToPage = CurrentViewer.CanGoToPage(pageNumber); } return canGoToPage; } ////// Invokes the Find Toolbar. This is analogous to the ApplicationCommands.Find. /// public void Find() { OnFindCommand(); } ////// Invokes the Print Dialog. This is analogous to the ApplicationCommands.Print. /// public void Print() { OnPrintCommand(); } ////// Cancels current printing job. This is analogous to the ApplicationCommands.CancelPrint. /// public void CancelPrint() { OnCancelPrintCommand(); } ////// Increases the current zoom. /// public void IncreaseZoom() { OnIncreaseZoomCommand(); } ////// Decreases the current zoom. /// public void DecreaseZoom() { OnDecreaseZoomCommand(); } ////// Switches the current viewing mode. This is analogous to the SwitchViewingModeCommand. /// /// Viewing mode. public void SwitchViewingMode(FlowDocumentReaderViewingMode viewingMode) { OnSwitchViewingModeCommand(viewingMode); } #endregion Public Methods //-------------------------------------------------------------------- // // Public Properties // //-------------------------------------------------------------------- #region Public Properties ////// ViewingMode of FlowDocumentReader. /// public FlowDocumentReaderViewingMode ViewingMode { get { return (FlowDocumentReaderViewingMode)GetValue(ViewingModeProperty); } set { SetValue(ViewingModeProperty, value); } } ////// Text Selection (readonly) /// public TextSelection Selection { get { TextSelection result = null; IFlowDocumentViewer viewer; if (_contentHost != null) { viewer = _contentHost.Child as IFlowDocumentViewer; if(viewer != null) { result = viewer.TextSelection as TextSelection; } } return result; } } ////// Whether Page view can be enabled or not. /// public bool IsPageViewEnabled { get { return (bool)GetValue(IsPageViewEnabledProperty); } set { SetValue(IsPageViewEnabledProperty, BooleanBoxes.Box(value)); } } ////// Whether TwoPage view can be enabled or not. /// public bool IsTwoPageViewEnabled { get { return (bool)GetValue(IsTwoPageViewEnabledProperty); } set { SetValue(IsTwoPageViewEnabledProperty, BooleanBoxes.Box(value)); } } ////// Whether Scroll view can be enabled or not. /// public bool IsScrollViewEnabled { get { return (bool)GetValue(IsScrollViewEnabledProperty); } set { SetValue(IsScrollViewEnabledProperty, BooleanBoxes.Box(value)); } } ////// The number of pages currently available for viewing. This value /// is updated as content is paginated, and will change dramatically /// when the content is resized, or edited. /// public int PageCount { get { return (int)GetValue(PageCountProperty); } } ////// The one-based page number of the page being displayed. If there is no content, /// this value will be 0. /// public int PageNumber { get { return (int)GetValue(PageNumberProperty); } } ////// Whether the viewer can move the master page to the previous page. /// public bool CanGoToPreviousPage { get { return (bool)GetValue(CanGoToPreviousPageProperty); } } ////// Whether the viewer can advance the master page to the next page. /// public bool CanGoToNextPage { get { return (bool)GetValue(CanGoToNextPageProperty); } } ////// Is find function enabled or not /// public bool IsFindEnabled { get { return (bool)GetValue(IsFindEnabledProperty); } set { SetValue(IsFindEnabledProperty, BooleanBoxes.Box(value)); } } ////// Is print function enabled or not /// public bool IsPrintEnabled { get { return (bool)GetValue(IsPrintEnabledProperty); } set { SetValue(IsPrintEnabledProperty, BooleanBoxes.Box(value)); } } ////// A Property representing a content of this FlowDocumentScrollViewer. /// public FlowDocument Document { get { return (FlowDocument)GetValue(DocumentProperty); } set { SetValue(DocumentProperty, value); } } ////// The Zoom applied to all pages; this value is 100-based. /// public double Zoom { get { return (double)GetValue(ZoomProperty); } set { SetValue(ZoomProperty, value); } } ////// The maximum allowed value of the Zoom property. /// public double MaxZoom { get { return (double)GetValue(MaxZoomProperty); } set { SetValue(MaxZoomProperty, value); } } ////// The minimum allowed value of the Zoom property. /// public double MinZoom { get { return (double)GetValue(MinZoomProperty); } set { SetValue(MinZoomProperty, value); } } ////// The amount the Zoom property is incremented or decremented when /// the IncreaseZoom or DecreaseZoom command is executed. /// public double ZoomIncrement { get { return (double)GetValue(ZoomIncrementProperty); } set { SetValue(ZoomIncrementProperty, value); } } ////// Whether the viewer can increase the current zoom. /// public bool CanIncreaseZoom { get { return (bool)GetValue(CanIncreaseZoomProperty); } } ////// Whether the viewer can decrease the current zoom. /// public bool CanDecreaseZoom { get { return (bool)GetValue(CanDecreaseZoomProperty); } } ////// public Brush SelectionBrush { get { return (Brush)GetValue(SelectionBrushProperty); } set { SetValue(SelectionBrushProperty, value); } } ////// /// public double SelectionOpacity { get { return (double)GetValue(SelectionOpacityProperty); } set { SetValue(SelectionOpacityProperty, value); } } #region Public Dynamic Properties ////// /// public static readonly DependencyProperty ViewingModeProperty = DependencyProperty.Register( "ViewingMode", typeof(FlowDocumentReaderViewingMode), typeof(FlowDocumentReader), new FrameworkPropertyMetadata( FlowDocumentReaderViewingMode.Page, FrameworkPropertyMetadataOptions.AffectsMeasure, new PropertyChangedCallback(ViewingModeChanged)), new ValidateValueCallback(IsValidViewingMode)); ////// /// public static readonly DependencyProperty IsPageViewEnabledProperty = DependencyProperty.Register( "IsPageViewEnabled", typeof(bool), typeof(FlowDocumentReader), new FrameworkPropertyMetadata( BooleanBoxes.TrueBox, new PropertyChangedCallback(ViewingModeEnabledChanged))); ////// /// public static readonly DependencyProperty IsTwoPageViewEnabledProperty = DependencyProperty.Register( "IsTwoPageViewEnabled", typeof(bool), typeof(FlowDocumentReader), new FrameworkPropertyMetadata( BooleanBoxes.TrueBox, new PropertyChangedCallback(ViewingModeEnabledChanged))); ////// /// public static readonly DependencyProperty IsScrollViewEnabledProperty = DependencyProperty.Register( "IsScrollViewEnabled", typeof(bool), typeof(FlowDocumentReader), new FrameworkPropertyMetadata( BooleanBoxes.TrueBox, new PropertyChangedCallback(ViewingModeEnabledChanged))); ////// /// private static readonly DependencyPropertyKey PageCountPropertyKey = DependencyProperty.RegisterReadOnly( "PageCount", typeof(int), typeof(FlowDocumentReader), new FrameworkPropertyMetadata(0)); ////// /// public static readonly DependencyProperty PageCountProperty = PageCountPropertyKey.DependencyProperty; ////// /// private static readonly DependencyPropertyKey PageNumberPropertyKey = DependencyProperty.RegisterReadOnly( "PageNumber", typeof(int), typeof(FlowDocumentReader), new FrameworkPropertyMetadata(0)); ////// /// public static readonly DependencyProperty PageNumberProperty = PageNumberPropertyKey.DependencyProperty; ////// /// private static readonly DependencyPropertyKey CanGoToPreviousPagePropertyKey = DependencyProperty.RegisterReadOnly( "CanGoToPreviousPage", typeof(bool), typeof(FlowDocumentReader), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox)); ////// /// public static readonly DependencyProperty CanGoToPreviousPageProperty = CanGoToPreviousPagePropertyKey.DependencyProperty; ////// /// private static readonly DependencyPropertyKey CanGoToNextPagePropertyKey = DependencyProperty.RegisterReadOnly( "CanGoToNextPage", typeof(bool), typeof(FlowDocumentReader), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox)); ////// /// public static readonly DependencyProperty CanGoToNextPageProperty = CanGoToNextPagePropertyKey.DependencyProperty; ////// /// public static readonly DependencyProperty IsFindEnabledProperty = DependencyProperty.Register( "IsFindEnabled", typeof(bool), typeof(FlowDocumentReader), new FrameworkPropertyMetadata( BooleanBoxes.TrueBox, new PropertyChangedCallback(IsFindEnabledChanged))); ////// /// public static readonly DependencyProperty IsPrintEnabledProperty = DependencyProperty.Register( "IsPrintEnabled", typeof(bool), typeof(FlowDocumentReader), new FrameworkPropertyMetadata( BooleanBoxes.TrueBox, new PropertyChangedCallback(IsPrintEnabledChanged))); ////// /// public static readonly DependencyProperty DocumentProperty = DependencyProperty.Register( "Document", typeof(FlowDocument), typeof(FlowDocumentReader), new FrameworkPropertyMetadata( null, new PropertyChangedCallback(DocumentChanged))); ////// /// public static readonly DependencyProperty ZoomProperty = FlowDocumentPageViewer.ZoomProperty.AddOwner( typeof(FlowDocumentReader), new FrameworkPropertyMetadata( 100d, new PropertyChangedCallback(ZoomChanged), new CoerceValueCallback(CoerceZoom))); ////// /// public static readonly DependencyProperty MaxZoomProperty = FlowDocumentPageViewer.MaxZoomProperty.AddOwner( typeof(FlowDocumentReader), new FrameworkPropertyMetadata( 200d, new PropertyChangedCallback(MaxZoomChanged), new CoerceValueCallback(CoerceMaxZoom))); ////// /// public static readonly DependencyProperty MinZoomProperty = FlowDocumentPageViewer.MinZoomProperty.AddOwner( typeof(FlowDocumentReader), new FrameworkPropertyMetadata( 80d, new PropertyChangedCallback(MinZoomChanged))); ////// /// public static readonly DependencyProperty ZoomIncrementProperty = FlowDocumentPageViewer.ZoomIncrementProperty.AddOwner( typeof(FlowDocumentReader)); ////// /// private static readonly DependencyPropertyKey CanIncreaseZoomPropertyKey = DependencyProperty.RegisterReadOnly( "CanIncreaseZoom", typeof(bool), typeof(FlowDocumentReader), new FrameworkPropertyMetadata(BooleanBoxes.TrueBox)); ////// /// public static readonly DependencyProperty CanIncreaseZoomProperty = CanIncreaseZoomPropertyKey.DependencyProperty; ////// /// private static readonly DependencyPropertyKey CanDecreaseZoomPropertyKey = DependencyProperty.RegisterReadOnly( "CanDecreaseZoom", typeof(bool), typeof(FlowDocumentReader), new FrameworkPropertyMetadata(BooleanBoxes.TrueBox)); ////// /// public static readonly DependencyProperty CanDecreaseZoomProperty = CanDecreaseZoomPropertyKey.DependencyProperty; ////// /// public static readonly DependencyProperty SelectionBrushProperty = TextBoxBase.SelectionBrushProperty.AddOwner(typeof(FlowDocumentReader)); ////// /// public static readonly DependencyProperty SelectionOpacityProperty = TextBoxBase.SelectionOpacityProperty.AddOwner(typeof(FlowDocumentReader)); #endregion Public Dynamic Properties #endregion Public Properties //------------------------------------------------------------------- // // Public Commands // //-------------------------------------------------------------------- #region Public Commands ////// /// Switch ViewingMode command /// public static readonly RoutedUICommand SwitchViewingModeCommand = new RoutedUICommand(SR.Get(SRID.SwitchViewingMode), "SwitchViewingMode", typeof(FlowDocumentReader), null); #endregion //------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------- #region Protected Methods ////// Called when print has been completed. /// protected virtual void OnPrintCompleted() { if (_printInProgress) { _printInProgress = false; // Since _printInProgress value is used to determine CanExecute state, we must invalidate that state. CommandManager.InvalidateRequerySuggested(); } } ////// Handler for the Find command /// protected virtual void OnFindCommand() { if (CanShowFindToolBar) { // Toggle on the FindToolBar between visible and hidden state. ToggleFindToolBar(FindToolBar == null); } } ////// Handler for the Print command. /// protected virtual void OnPrintCommand() { if (CurrentViewer != null) { CurrentViewer.Print(); } } ////// Handler for the CancelPrint command. /// protected virtual void OnCancelPrintCommand() { if (CurrentViewer != null) { CurrentViewer.CancelPrint(); } } ////// Handler for the IncreaseZoom command. /// protected virtual void OnIncreaseZoomCommand() { // If can zoom in, increase zoom by the zoom increment value. if (CanIncreaseZoom) { SetCurrentValueInternal(ZoomProperty, Math.Min(Zoom + ZoomIncrement, MaxZoom)); } } ////// Handler for the DecreaseZoom command. /// protected virtual void OnDecreaseZoomCommand() { // If can zoom out, decrease zoom by the zoom increment value. if (CanDecreaseZoom) { SetCurrentValueInternal(ZoomProperty, Math.Max(Zoom - ZoomIncrement, MinZoom)); } } ////// Handler for the SwitchViewingMode command. /// /// Viewing mode. protected virtual void OnSwitchViewingModeCommand(FlowDocumentReaderViewingMode viewingMode) { SwitchViewingModeCore(viewingMode); } ////// Called when IsInitialized is set to true. /// /// Event arguments protected override void OnInitialized(EventArgs e) { base.OnInitialized(e); // Defer the Is*ViewEnabled & ViewingMode conflict exception. // Otherwisewon't work. if (IsInitialized && !CanSwitchToViewingMode(ViewingMode)) { throw new ArgumentException(SR.Get(SRID.FlowDocumentReaderViewingModeEnabledConflict)); } } /// /// Creates AutomationPeer ( protected override AutomationPeer OnCreateAutomationPeer() { return new FlowDocumentReaderAutomationPeer(this); } ///) /// /// An event reporting that the IsKeyboardFocusWithin property changed. /// protected override void OnIsKeyboardFocusWithinChanged(DependencyPropertyChangedEventArgs e) { base.OnIsKeyboardFocusWithinChanged(e); // In order to enable selection rendering and other similar services, the embedded viewer // needs to get focus, when any part of the control gets focused. // But if the focus is within the Document, do not change it. Otherwise it // will interfere with input handling inside the Document. if (IsKeyboardFocusWithin && CurrentViewer != null) { bool isFocusWithinDocument = IsFocusWithinDocument(); if (!isFocusWithinDocument) { ((FrameworkElement)CurrentViewer).Focus(); } } } ////// This is the method that responds to the KeyDown event. /// /// Event arguments ////// Critical: get_SearchUp is defined in a non-APTCA assembly. /// TreatAsSafe: call to get_SearchUp does not entail any risk. /// [SecurityCritical, SecurityTreatAsSafe] protected override void OnKeyDown(KeyEventArgs e) { if (e.Handled) { return; } switch (e.Key) { // Esc -- Close FindToolBar case Key.Escape: if (FindToolBar != null) { ToggleFindToolBar(false); e.Handled = true; } break; // F3 -- Invoke Find case Key.F3: if (CanShowFindToolBar) { if (FindToolBar != null) { // If the Shift key is also pressed, then search up. FindToolBar.SearchUp = ((e.KeyboardDevice.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift); OnFindInvoked(this, EventArgs.Empty); } else { // Make the FindToolBar visible ToggleFindToolBar(true); } e.Handled = true; } break; } // If not handled, do default handling. if (!e.Handled) { base.OnKeyDown(e); } } #endregion Protected Methods //------------------------------------------------------------------- // // Protected Properties // //-------------------------------------------------------------------- #region Protected Properties ////// Returns enumerator to logical children. /// protected internal override IEnumerator LogicalChildren { get { if (HasLogicalChildren && Document != null) { return new SingleChildEnumerator(Document); } return EmptyEnumerator.Instance; } } #endregion Protected Properties //------------------------------------------------------------------- // // Internal Methods // //-------------------------------------------------------------------- #region Internal Methods ////// Allows FrameworkElement to augment the EventRoute. /// internal override bool BuildRouteCore(EventRoute route, RoutedEventArgs args) { // Do not add intermediate ContentElements to the route, // because they were added by embedded viewer. return BuildRouteCoreHelper(route, args, false); } #endregion Internal Methods //-------------------------------------------------------------------- // // Private Methods // //------------------------------------------------------------------- #region Private Methods ////// Handler for the SwitchViewingMode command. /// /// Viewing mode. protected virtual void SwitchViewingModeCore(FlowDocumentReaderViewingMode viewingMode) { ITextSelection textSelection = null; ContentPosition contentPosition = null; IFlowDocumentViewer viewer; FrameworkElement feViewer; bool isKeyboardFocusWithin; DependencyObject focusedElement = null; if (_contentHost != null) { // Remember the current keyboard focus state. isKeyboardFocusWithin = IsKeyboardFocusWithin; // Detach old viewer viewer = _contentHost.Child as IFlowDocumentViewer; if (viewer != null) { // Remember focused element, if the focus is within the Document. // After switching to a different viewer, this focus needs to be restored. if (isKeyboardFocusWithin) { bool isFocusWithinDocument = IsFocusWithinDocument(); if (isFocusWithinDocument) { focusedElement = Keyboard.FocusedElement as DependencyObject; } } // Retrieve the current viewing state from the old viewer. textSelection = viewer.TextSelection; contentPosition = viewer.ContentPosition; // Detach old viewer DetachViewer(viewer); } viewer = GetViewerFromMode(viewingMode); feViewer = (FrameworkElement)viewer; if (viewer != null) { // Attach new viewer _contentHost.Child = feViewer; AttachViewer(viewer); // Restore viewing state. viewer.TextSelection = textSelection; viewer.ContentPosition = contentPosition; // Bring the focus to previously focused element within the document // or to the current viewer. if (isKeyboardFocusWithin) { if (focusedElement is UIElement) { ((UIElement)focusedElement).Focus(); } else if (focusedElement is ContentElement) { ((ContentElement)focusedElement).Focus(); } else { feViewer.Focus(); } } } // Viewer changes invalidates following properties: // - PageCount // - PageNumber // - CanGoToPreviousPage // - CanGoToNextPage UpdateReadOnlyProperties(true, true); } } ////// Determines whether focus is within Document. /// private bool IsFocusWithinDocument() { DependencyObject focusedElement = Keyboard.FocusedElement as DependencyObject; while (focusedElement != null && focusedElement != Document) { // Skip elements in the control's template (if such exists) and // walk up logical tree to find if the focused element is within // the document. FrameworkElement fe = focusedElement as FrameworkElement; if (fe != null && fe.TemplatedParent != null) { focusedElement = fe.TemplatedParent; } else { focusedElement = LogicalTreeHelper.GetParent(focusedElement); } } return (focusedElement != null); } ////// The Document has changed and needs to be updated. /// private void DocumentChanged(FlowDocument oldDocument, FlowDocument newDocument) { // Cleanup state associated with the old document. if (oldDocument != null) { // If Document was added to logical tree before, remove it. if (_documentAsLogicalChild) { RemoveLogicalChild(oldDocument); } } // If FlowDocumentReader was created through style, then do not modify // the logical tree. Instead, set "core parent" for the Document. if (TemplatedParent != null && newDocument != null && LogicalTreeHelper.GetParent(newDocument) != null) { // Set the "core parent" back to us. ContentOperations.SetParent(newDocument, this); _documentAsLogicalChild = false; } else { _documentAsLogicalChild = true; } // Initialize state associated with the new document. if (newDocument != null) { // If Document should be part of DocumentViewer's logical tree, add it. if (_documentAsLogicalChild) { AddLogicalChild(newDocument); } } // Attach document to the current viewer. if (CurrentViewer != null) { CurrentViewer.SetDocument(newDocument); } // Document invalidation invalidates following properties: // - PageCount // - PageNumber // - CanGoToPreviousPage // - CanGoToNextPage UpdateReadOnlyProperties(true, true); // Update the toolbar with our current document state. if (!CanShowFindToolBar) { // Disable FindToolBar, if the content does not support it. if (FindToolBar != null) { ToggleFindToolBar(false); } } // Document is also represented as Automation child. Need to invalidate peer to force update. FlowDocumentReaderAutomationPeer peer = UIElementAutomationPeer.FromElement(this) as FlowDocumentReaderAutomationPeer; if (peer != null) { peer.InvalidatePeer(); } } ////// Detach embedded viewer form the reader control. /// private void DetachViewer(IFlowDocumentViewer viewer) { Invariant.Assert(viewer != null && viewer is FrameworkElement); FrameworkElement feViewer = (FrameworkElement)viewer; // Clear property bindings. BindingOperations.ClearBinding(feViewer, ZoomProperty); BindingOperations.ClearBinding(feViewer, MaxZoomProperty); BindingOperations.ClearBinding(feViewer, MinZoomProperty); BindingOperations.ClearBinding(feViewer, ZoomIncrementProperty); // Unregister event handlers. viewer.PageCountChanged -= new EventHandler(OnPageCountChanged); viewer.PageNumberChanged -= new EventHandler(OnPageNumberChanged); viewer.PrintStarted -= new EventHandler(OnViewerPrintStarted); viewer.PrintCompleted -= new EventHandler(OnViewerPrintCompleted); // Clear TemplatedParent //feViewer._templatedParent = null; // Detach document viewer.SetDocument(null); } ////// Attach embedded viewer to the reader control. /// private void AttachViewer(IFlowDocumentViewer viewer) { Invariant.Assert(viewer != null && viewer is FrameworkElement); FrameworkElement feViewer = (FrameworkElement)viewer; // Set document viewer.SetDocument(Document); // Set TemplatedParent //feViewer._templatedParent = TemplatedParent; // Register event handlers. viewer.PageCountChanged += new EventHandler(OnPageCountChanged); viewer.PageNumberChanged += new EventHandler(OnPageNumberChanged); viewer.PrintStarted += new EventHandler(OnViewerPrintStarted); viewer.PrintCompleted += new EventHandler(OnViewerPrintCompleted); // Create property bindings. CreateTwoWayBinding(feViewer, ZoomProperty, "Zoom"); CreateTwoWayBinding(feViewer, MaxZoomProperty, "MaxZoom"); CreateTwoWayBinding(feViewer, MinZoomProperty, "MinZoom"); CreateTwoWayBinding(feViewer, ZoomIncrementProperty, "ZoomIncrement"); } ////// Create two way property binding. /// private void CreateTwoWayBinding(FrameworkElement fe, DependencyProperty dp, string propertyPath) { Binding binding = new Binding(propertyPath); binding.Mode = BindingMode.TwoWay; binding.Source = this; fe.SetBinding(dp, binding); } ////// Determines whether can switch to specified ViewingMode or not. /// private bool CanSwitchToViewingMode(FlowDocumentReaderViewingMode mode) { bool canSwitch = false; switch (mode) { case FlowDocumentReaderViewingMode.Page: canSwitch = IsPageViewEnabled; break; case FlowDocumentReaderViewingMode.TwoPage: canSwitch = IsTwoPageViewEnabled; break; case FlowDocumentReaderViewingMode.Scroll: canSwitch = IsScrollViewEnabled; break; } return canSwitch; } ////// Retrieves viewer form specified ViewingMode. /// private IFlowDocumentViewer GetViewerFromMode(FlowDocumentReaderViewingMode mode) { IFlowDocumentViewer viewer = null; switch (mode) { case FlowDocumentReaderViewingMode.Page: if (_pageViewer == null) { _pageViewer = new ReaderPageViewer(); _pageViewer.SetResourceReference(StyleProperty, PageViewStyleKey); _pageViewer.Name = "PageViewer"; CommandManager.AddPreviewCanExecuteHandler(_pageViewer, new CanExecuteRoutedEventHandler(PreviewCanExecuteRoutedEventHandler)); } viewer = _pageViewer; break; case FlowDocumentReaderViewingMode.TwoPage: if (_twoPageViewer == null) { _twoPageViewer = new ReaderTwoPageViewer(); _twoPageViewer.SetResourceReference(StyleProperty, TwoPageViewStyleKey); _twoPageViewer.Name = "TwoPageViewer"; CommandManager.AddPreviewCanExecuteHandler(_twoPageViewer, new CanExecuteRoutedEventHandler(PreviewCanExecuteRoutedEventHandler)); } viewer = _twoPageViewer; break; case FlowDocumentReaderViewingMode.Scroll: if (_scrollViewer == null) { _scrollViewer = new ReaderScrollViewer(); _scrollViewer.SetResourceReference(StyleProperty, ScrollViewStyleKey); _scrollViewer.Name = "ScrollViewer"; CommandManager.AddPreviewCanExecuteHandler(_scrollViewer, new CanExecuteRoutedEventHandler(PreviewCanExecuteRoutedEventHandler)); } viewer = _scrollViewer; break; } return viewer; } ////// Update values for readonly properties. /// /// Whether PageCount has been changed. /// Whether PageNumber has been changed. private void UpdateReadOnlyProperties(bool pageCountChanged, bool pageNumberChanged) { if (pageCountChanged) { SetValue(PageCountPropertyKey, (CurrentViewer != null) ? CurrentViewer.PageCount : 0); } if (pageNumberChanged) { SetValue(PageNumberPropertyKey, (CurrentViewer != null) ? CurrentViewer.PageNumber : 0); SetValue(CanGoToPreviousPagePropertyKey, (CurrentViewer != null) ? CurrentViewer.CanGoToPreviousPage : false); } if (pageCountChanged || pageNumberChanged) { SetValue(CanGoToNextPagePropertyKey, (CurrentViewer != null) ? CurrentViewer.CanGoToNextPage : false); } } ////// Event handler for IFlowDocumentViewer.PageCountChanged. /// private void OnPageCountChanged(object sender, EventArgs e) { Invariant.Assert(CurrentViewer != null && sender == CurrentViewer); UpdateReadOnlyProperties(true, false); } ////// Event handler for IFlowDocumentViewer.PageNumberChanged. /// private void OnPageNumberChanged(object sender, EventArgs e) { Invariant.Assert(CurrentViewer != null && sender == CurrentViewer); UpdateReadOnlyProperties(false, true); } ////// Event handler for IFlowDocumentViewer.PrintStarted. /// private void OnViewerPrintStarted(object sender, EventArgs e) { Invariant.Assert(CurrentViewer != null && sender == CurrentViewer); _printInProgress = true; // Since _printInProgress value is used to determine CanExecute state, we must invalidate that state. CommandManager.InvalidateRequerySuggested(); } ////// Event handler for IFlowDocumentViewer.PrintCompleted. /// private void OnViewerPrintCompleted(object sender, EventArgs e) { Invariant.Assert(CurrentViewer != null && sender == CurrentViewer); OnPrintCompleted(); } ////// Convert object value to FlowDocumentReaderViewingMode. /// private bool ConvertToViewingMode(object value, out FlowDocumentReaderViewingMode mode) { bool success; if (value is FlowDocumentReaderViewingMode) { mode = (FlowDocumentReaderViewingMode)value; success = true; } else if (value is String) { String str = (String)value; if (str == FlowDocumentReaderViewingMode.Page.ToString()) { mode = FlowDocumentReaderViewingMode.Page; success = true; } else if (str == FlowDocumentReaderViewingMode.TwoPage.ToString()) { mode = FlowDocumentReaderViewingMode.TwoPage; success = true; } else if (str == FlowDocumentReaderViewingMode.Scroll.ToString()) { mode = FlowDocumentReaderViewingMode.Scroll; success = true; } else { mode = FlowDocumentReaderViewingMode.Page; success = false; } } else { mode = FlowDocumentReaderViewingMode.Page; success = false; } return success; } ////// Enables/disables the FindToolBar. /// /// Whether to enable/disable FindToolBar. private void ToggleFindToolBar(bool enable) { Invariant.Assert(enable == (FindToolBar == null)); // Command event for toggle button is only fired in OnClick - Therefore we just need to change the state if(_findButton != null && _findButton.IsChecked.HasValue && _findButton.IsChecked.Value != enable) { _findButton.IsChecked = enable; } DocumentViewerHelper.ToggleFindToolBar(_findToolBarHost, new EventHandler(OnFindInvoked), enable); } #region Commands ////// Set up Command and RoutedCommand bindings. /// private static void CreateCommandBindings() { ExecutedRoutedEventHandler executedHandler; CanExecuteRoutedEventHandler canExecuteHandler; // Create our generic ExecutedRoutedEventHandler. executedHandler = new ExecutedRoutedEventHandler(ExecutedRoutedEventHandler); // Create our generic CanExecuteRoutedEventHandler canExecuteHandler = new CanExecuteRoutedEventHandler(CanExecuteRoutedEventHandler); // Command: SwitchViewingMode CommandHelpers.RegisterCommandHandler(typeof(FlowDocumentReader), FlowDocumentReader.SwitchViewingModeCommand, executedHandler, canExecuteHandler, SRID.KeySwitchViewingMode, SRID.KeySwitchViewingModeDisplayString); // Command: ApplicationCommands.Find CommandHelpers.RegisterCommandHandler(typeof(FlowDocumentReader), ApplicationCommands.Find, executedHandler, canExecuteHandler); // Command: ApplicationCommands.Print CommandHelpers.RegisterCommandHandler(typeof(FlowDocumentReader), ApplicationCommands.Print, executedHandler, canExecuteHandler); // Command: ApplicationCommands.CancelPrint CommandHelpers.RegisterCommandHandler(typeof(FlowDocumentReader), ApplicationCommands.CancelPrint, executedHandler, canExecuteHandler); // Command: NavigationCommands.PreviousPage CommandHelpers.RegisterCommandHandler(typeof(FlowDocumentReader), NavigationCommands.PreviousPage, executedHandler, canExecuteHandler); // Command: NavigationCommands.NextPage CommandHelpers.RegisterCommandHandler(typeof(FlowDocumentReader), NavigationCommands.NextPage, executedHandler, canExecuteHandler); // Command: NavigationCommands.FirstPage CommandHelpers.RegisterCommandHandler(typeof(FlowDocumentReader), NavigationCommands.FirstPage, executedHandler, canExecuteHandler); // Command: NavigationCommands.LastPage CommandHelpers.RegisterCommandHandler(typeof(FlowDocumentReader), NavigationCommands.LastPage, executedHandler, canExecuteHandler); // Command: NavigationCommands.IncreaseZoom CommandHelpers.RegisterCommandHandler(typeof(FlowDocumentReader), NavigationCommands.IncreaseZoom, executedHandler, canExecuteHandler, new KeyGesture(Key.OemPlus, ModifierKeys.Control)); // Command: NavigationCommands.DecreaseZoom CommandHelpers.RegisterCommandHandler(typeof(FlowDocumentReader), NavigationCommands.DecreaseZoom, executedHandler, canExecuteHandler, new KeyGesture(Key.OemMinus, ModifierKeys.Control)); } ////// Central handler for CanExecute events fired by Commands directed at FlowDocumentReader. /// /// The target of this Command, expected to be FlowDocumentReader /// The event arguments for this event. private static void CanExecuteRoutedEventHandler(object target, CanExecuteRoutedEventArgs args) { FlowDocumentReader viewer = target as FlowDocumentReader; Invariant.Assert(viewer != null, "Target of CanExecuteRoutedEventHandler must be FlowDocumentReader."); Invariant.Assert(args != null, "args cannot be null."); // FlowDocumentReader is capable of execution of the majority of its commands. // Special rules: // a) during printing only CancelPrint is enabled. // b) Find command is enabled only when FindToolBar is enabled. // c) Print command is enabled when Document is attached and printing is enabled. // d) CancelPrint command is enabled only during printing. // e) SwitchViewingMode command is enabled if the viewing mode is enabled, or // the command has no parameters (will switch to the next available view). if (!viewer._printInProgress) { if (args.Command == FlowDocumentReader.SwitchViewingModeCommand) { // This command is enabled if the viewing mode is enabled, or the command // has no parameters (will switch to the next available view). FlowDocumentReaderViewingMode mode; if (viewer.ConvertToViewingMode(args.Parameter, out mode)) { args.CanExecute = viewer.CanSwitchToViewingMode(mode); } else { args.CanExecute = (args.Parameter == null); } } else if (args.Command == ApplicationCommands.Find) { args.CanExecute = viewer.CanShowFindToolBar; } else if (args.Command == ApplicationCommands.Print) { args.CanExecute = (viewer.Document != null) && viewer.IsPrintEnabled; } else if (args.Command == ApplicationCommands.CancelPrint) { args.CanExecute = false; } else { args.CanExecute = true; } } else { args.CanExecute = (args.Command == ApplicationCommands.CancelPrint); } } ////// Central handler for all ExecuteEvents fired by Commands directed at FlowDocumentReader. /// /// The target of this Command, expected to be FlowDocumentReader. /// The event arguments associated with this event. private static void ExecutedRoutedEventHandler(object target, ExecutedRoutedEventArgs args) { FlowDocumentReader viewer = target as FlowDocumentReader; Invariant.Assert(viewer != null, "Target of ExecutedRoutedEventHandler must be FlowDocumentReader."); Invariant.Assert(args != null, "args cannot be null."); if (args.Command == FlowDocumentReader.SwitchViewingModeCommand) { viewer.TrySwitchViewingMode(args.Parameter); } else if (args.Command == ApplicationCommands.Find) { viewer.OnFindCommand(); } else if (args.Command == ApplicationCommands.Print) { viewer.OnPrintCommand(); } else if (args.Command == ApplicationCommands.CancelPrint) { viewer.OnCancelPrintCommand(); } else if (args.Command == NavigationCommands.IncreaseZoom) { viewer.OnIncreaseZoomCommand(); } else if (args.Command == NavigationCommands.DecreaseZoom) { viewer.OnDecreaseZoomCommand(); } else if (args.Command == NavigationCommands.PreviousPage) { viewer.OnPreviousPageCommand(); } else if (args.Command == NavigationCommands.NextPage) { viewer.OnNextPageCommand(); } else if (args.Command == NavigationCommands.FirstPage) { viewer.OnFirstPageCommand(); } else if (args.Command == NavigationCommands.LastPage) { viewer.OnLastPageCommand(); } else { Invariant.Assert(false, "Command not handled in ExecutedRoutedEventHandler."); } } ////// Changes the current viewing mode. /// private void TrySwitchViewingMode(object parameter) { FlowDocumentReaderViewingMode mode; // Convert command parameter to viewing mode value. // If parameter is not provided, the viewing mode is the next one available. // If parameter cannot be converted, the command is ignored. if (!ConvertToViewingMode(parameter, out mode)) { if (parameter == null) { mode = (FlowDocumentReaderViewingMode)((((int)ViewingMode) + 1) % 3); } else { return; } } // If the current ViewingMode is disabled, go to next one. while (!CanSwitchToViewingMode(mode)) { mode = (FlowDocumentReaderViewingMode)((((int)mode) + 1) % 3); } // Set new ViewingMode value. SetCurrentValueInternal(ViewingModeProperty, mode); } ////// Handler for the PreviousPage command. /// private void OnPreviousPageCommand() { if (CurrentViewer != null) { CurrentViewer.PreviousPage(); } } ////// Handler for the NextPage command. /// private void OnNextPageCommand() { if (CurrentViewer != null) { CurrentViewer.NextPage(); } } ////// Handler for the FirstPage command. /// private void OnFirstPageCommand() { if (CurrentViewer != null) { CurrentViewer.FirstPage(); } } ////// Handler for the LastPage command. /// private void OnLastPageCommand() { if (CurrentViewer != null) { CurrentViewer.LastPage(); } } ////// Invoked when the "Find" button in the Find Toolbar is clicked. /// This method invokes the actual Find process. /// /// The object that sent this event /// The Click Events associated with this event private void OnFindInvoked(object sender, EventArgs e) { ITextRange findResult; TextEditor textEditor = TextEditor; FindToolBar findToolBar = FindToolBar; if (findToolBar != null && textEditor != null) { // In order to show current text selection TextEditor requires Focus to be set on the UIScope. // If there embedded controls, it may happen that embedded control currently has focus and find // was invoked through hotkeys. To support this case we manually move focus to the appropriate element. if (CurrentViewer != null && CurrentViewer is UIElement) { ((UIElement)CurrentViewer).Focus(); } findResult = DocumentViewerHelper.Find(findToolBar, textEditor, textEditor.TextView, textEditor.TextView); // If we found something, bring it into the view. Otherwise alert the user. if ((findResult != null) && (!findResult.IsEmpty)) { // Bring find result into view. if (CurrentViewer != null) { CurrentViewer.ShowFindResult(findResult); } } else { DocumentViewerHelper.ShowFindUnsuccessfulMessage(findToolBar); } } } ////// Disable commands on IFlowDocumentViewer when this funcionality is explicitly /// disabled on the reader control. /// private void PreviewCanExecuteRoutedEventHandler(object target, CanExecuteRoutedEventArgs args) { if (args.Command == ApplicationCommands.Find) { // Find is handled by FlowDocumentReader. args.CanExecute = false; args.Handled = true; } else if (args.Command == ApplicationCommands.Print) { args.CanExecute = IsPrintEnabled; args.Handled = !IsPrintEnabled; } } ////// Called when a key event occurs. /// private static void KeyDownHandler(object sender, KeyEventArgs e) { DocumentViewerHelper.KeyDownHelper(e, ((FlowDocumentReader)sender)._findToolBarHost); } #endregion Commands #region Static Methods ////// ViewingMode has been changed. /// private static void ViewingModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Invariant.Assert(d != null && d is FlowDocumentReader); FlowDocumentReader viewer = (FlowDocumentReader)d; if (viewer.CanSwitchToViewingMode((FlowDocumentReaderViewingMode)e.NewValue)) { viewer.SwitchViewingModeCore((FlowDocumentReaderViewingMode)e.NewValue); } else if (viewer.IsInitialized) { throw new ArgumentException(SR.Get(SRID.FlowDocumentReaderViewingModeEnabledConflict)); } // Fire automation events if automation is active. FlowDocumentReaderAutomationPeer peer = UIElementAutomationPeer.FromElement(viewer) as FlowDocumentReaderAutomationPeer; if (peer != null) { peer.RaiseCurrentViewChangedEvent((FlowDocumentReaderViewingMode)e.NewValue, (FlowDocumentReaderViewingMode)e.OldValue); } } ////// Validate value of ViewingMode property. /// private static bool IsValidViewingMode(object o) { FlowDocumentReaderViewingMode value = (FlowDocumentReaderViewingMode)o; return (value == FlowDocumentReaderViewingMode.Page || value == FlowDocumentReaderViewingMode.TwoPage || value == FlowDocumentReaderViewingMode.Scroll); } ////// One of viewing modes has been enabled/disabled. /// private static void ViewingModeEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Invariant.Assert(d != null && d is FlowDocumentReader); FlowDocumentReader viewer = (FlowDocumentReader)d; // Cannot disable all viewing modes. if (!viewer.IsPageViewEnabled && !viewer.IsTwoPageViewEnabled && !viewer.IsScrollViewEnabled) { throw new ArgumentException(SR.Get(SRID.FlowDocumentReaderCannotDisableAllViewingModes)); } // Cannot disable the current viewing mode. if (viewer.IsInitialized && !viewer.CanSwitchToViewingMode(viewer.ViewingMode)) { throw new ArgumentException(SR.Get(SRID.FlowDocumentReaderViewingModeEnabledConflict)); } // Fire automation events if automation is active. FlowDocumentReaderAutomationPeer peer = UIElementAutomationPeer.FromElement(viewer) as FlowDocumentReaderAutomationPeer; if (peer != null) { peer.RaiseSupportedViewsChangedEvent(e); } } ////// IsFindEnabled value has changed. /// private static void IsFindEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Invariant.Assert(d != null && d is FlowDocumentReader); FlowDocumentReader viewer = (FlowDocumentReader)d; // Update the toolbar with our current state. if (!viewer.CanShowFindToolBar) { if (viewer.FindToolBar != null) { viewer.ToggleFindToolBar(false); } } // Since IsFindEnabled state is used to determine CanExecute state, we must invalidate that state. CommandManager.InvalidateRequerySuggested(); } ////// IsPrintEnabled value has changed. /// private static void IsPrintEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Invariant.Assert(d != null && d is FlowDocumentReader); FlowDocumentReader viewer = (FlowDocumentReader)d; // Since IsPrintEnabled state is used to determine CanExecute state, we must invalidate that state. CommandManager.InvalidateRequerySuggested(); } ////// The Document has changed and needs to be updated. /// private static void DocumentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Invariant.Assert(d != null && d is FlowDocumentReader); FlowDocumentReader viewer = (FlowDocumentReader)d; viewer.DocumentChanged((FlowDocument)e.OldValue, (FlowDocument)e.NewValue); // Since Document state is used to determine CanExecute state, we must invalidate that state. CommandManager.InvalidateRequerySuggested(); } ////// The Zoom has changed and needs to be updated. /// private static void ZoomChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Invariant.Assert(d != null && d is FlowDocumentReader); FlowDocumentReader viewer = (FlowDocumentReader)d; if (!DoubleUtil.AreClose((double)e.OldValue, (double)e.NewValue)) { // If zoom has been changed, CanIncrease/DecreaseZoom property need to be updated. viewer.SetValue(CanIncreaseZoomPropertyKey, BooleanBoxes.Box(DoubleUtil.GreaterThan(viewer.MaxZoom, viewer.Zoom))); viewer.SetValue(CanDecreaseZoomPropertyKey, BooleanBoxes.Box(DoubleUtil.LessThan(viewer.MinZoom, viewer.Zoom))); } } ////// Coerce Zoom with Max/MinZoom, MinZoom works as the baseline. /// private static object CoerceZoom(DependencyObject d, object value) { Invariant.Assert(d != null && d is FlowDocumentReader); FlowDocumentReader viewer = (FlowDocumentReader)d; double zoom = (double)value; double maxZoom = viewer.MaxZoom; if (DoubleUtil.LessThan(maxZoom, zoom)) { return maxZoom; } double minZoom = viewer.MinZoom; if (DoubleUtil.GreaterThan(minZoom, zoom)) { return minZoom; } return value; } ////// The MaxZoom has changed and needs to be updated. /// private static void MaxZoomChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Invariant.Assert(d != null && d is FlowDocumentReader); FlowDocumentReader viewer = (FlowDocumentReader)d; viewer.CoerceValue(ZoomProperty); viewer.SetValue(CanIncreaseZoomPropertyKey, BooleanBoxes.Box(DoubleUtil.GreaterThan(viewer.MaxZoom, viewer.Zoom))); } ////// MaxZoom need to be coerced if MinZoom > MaxZoom /// private static object CoerceMaxZoom(DependencyObject d, object value) { Invariant.Assert(d != null && d is FlowDocumentReader); FlowDocumentReader viewer = (FlowDocumentReader)d; double min = viewer.MinZoom; return ((double)value < min) ? min : value; } ////// The MinZoom has changed and needs to be updated. /// private static void MinZoomChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Invariant.Assert(d != null && d is FlowDocumentReader); FlowDocumentReader viewer = (FlowDocumentReader)d; viewer.CoerceValue(MaxZoomProperty); viewer.CoerceValue(ZoomProperty); viewer.SetValue(CanDecreaseZoomPropertyKey, BooleanBoxes.Box(DoubleUtil.LessThan(viewer.MinZoom, viewer.Zoom))); } ////// Validate Zoom, MaxZoom, MinZoom and ZoomIncrement value. /// /// Value to validate. ///True if the value is valid, false otherwise. private static bool ZoomValidateValue(object o) { double value = (double)o; return (!Double.IsNaN(value) && !Double.IsInfinity(value) && DoubleUtil.GreaterThan(value, 0d)); } ////// PropertyChanged callback for a property that affects the selection or caret rendering. /// private static void UpdateCaretElement(DependencyObject d, DependencyPropertyChangedEventArgs e) { FlowDocumentReader reader = (FlowDocumentReader)d; if (reader.Selection != null) { CaretElement caretElement = reader.Selection.CaretElement; if (caretElement != null) { caretElement.InvalidateVisual(); } } } #endregion Static Methods #endregion Private Methods //-------------------------------------------------------------------- // // Private Properties // //------------------------------------------------------------------- #region Private Properties ////// Whether FindToolBar can be enabled. /// private bool CanShowFindToolBar { get { return ((_findToolBarHost != null) && IsFindEnabled && (Document != null)); } } ////// Returns TextEditor, if availabe. /// private TextEditor TextEditor { get { TextEditor textEditor = null; IFlowDocumentViewer currentViewer = CurrentViewer; if (currentViewer != null && currentViewer.TextSelection != null) { textEditor = currentViewer.TextSelection.TextEditor; } return textEditor; } } ////// Returns FindToolBar, if enabled. /// private FindToolBar FindToolBar { get { return (_findToolBarHost != null) ? _findToolBarHost.Child as FindToolBar : null; } } ////// Returns the current content viewer. /// private IFlowDocumentViewer CurrentViewer { get { if (_contentHost != null) { return (IFlowDocumentViewer)_contentHost.Child; } return null; } } #endregion Private Properties //------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields private Decorator _contentHost; // Host for content viewer private Decorator _findToolBarHost; // Host for FindToolBar private ToggleButton _findButton; // Find toggle button private ReaderPageViewer _pageViewer; // Viewer for Page viewing mode private ReaderTwoPageViewer _twoPageViewer; // Viewer for TwoPage viewing mode private ReaderScrollViewer _scrollViewer; // Viewer for Scroll viewing mode private bool _documentAsLogicalChild; // Is Document part of logical tree private bool _printInProgress; // Whether print is currently in progress. private const string _contentHostTemplateName = "PART_ContentHost"; // Name for ContentHost private const string _findToolBarHostTemplateName = "PART_FindToolBarHost"; // Name for the Find ToolBar host private const string _findButtonTemplateName = "FindButton"; // Name for the Find Button #endregion Private Fields //-------------------------------------------------------------------- // // IAddChild Members // //------------------------------------------------------------------- #region IAddChild Members ////// Called to add the object as a Child. /// /// Object to add as a child. ///FlowDocumentScrollViewer only supports a single child of type IDocumentPaginator. void IAddChild.AddChild(Object value) { if (value == null) { throw new ArgumentNullException("value"); } // Check if Content has already been set. if (this.Document != null) { throw new ArgumentException(SR.Get(SRID.FlowDocumentReaderCanHaveOnlyOneChild)); } if (!(value is FlowDocument)) { throw new ArgumentException(SR.Get(SRID.UnexpectedParameterType, value.GetType(), typeof(FlowDocument)), "value"); } Document = value as FlowDocument; } ////// Called when text appears under the tag in markup /// /// Text to add to the Object. ///FlowDocumentScrollViewer does not support Text children. void IAddChild.AddText(string text) { XamlSerializerUtil.ThrowIfNonWhiteSpaceInAddText(text, this); } #endregion IAddChild Members //-------------------------------------------------------------------- // // IJournalState Members // //-------------------------------------------------------------------- #region IJournalState Members [Serializable] private class JournalState : CustomJournalStateInternal { public JournalState(int contentPosition, LogicalDirection contentPositionDirection, double zoom, FlowDocumentReaderViewingMode viewingMode) { ContentPosition = contentPosition; ContentPositionDirection = contentPositionDirection; Zoom = zoom; ViewingMode = viewingMode; } public int ContentPosition; public LogicalDirection ContentPositionDirection; public double Zoom; public FlowDocumentReaderViewingMode ViewingMode; } ////// CustomJournalStateInternal IJournalState.GetJournalState(JournalReason journalReason) { int cp = -1; LogicalDirection cpDirection = LogicalDirection.Forward; IFlowDocumentViewer viewer = CurrentViewer; if (viewer != null) { TextPointer contentPosition = viewer.ContentPosition as TextPointer; if (contentPosition != null) { cp = contentPosition.Offset; cpDirection = contentPosition.LogicalDirection; } } return new JournalState(cp, cpDirection, Zoom, ViewingMode); } ////// /// void IJournalState.RestoreJournalState(CustomJournalStateInternal state) { JournalState viewerState = state as JournalState; if (state != null) { SetCurrentValueInternal(ZoomProperty, viewerState.Zoom); SetCurrentValueInternal(ViewingModeProperty, viewerState.ViewingMode); if (viewerState.ContentPosition != -1) { IFlowDocumentViewer viewer = CurrentViewer; FlowDocument document = Document; if (viewer != null && document != null) { TextContainer textContainer = document.StructuralCache.TextContainer; if (viewerState.ContentPosition <= textContainer.SymbolCount) { TextPointer contentPosition = textContainer.CreatePointerAtOffset(viewerState.ContentPosition, viewerState.ContentPositionDirection); viewer.ContentPosition = contentPosition; } } } } } #endregion IJournalState Members //------------------------------------------------------------------- // // DTypeThemeStyleKey // //-------------------------------------------------------------------- #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 //------------------------------------------------------------------- // // Style Keys // //------------------------------------------------------------------- #region Style Keys ////// Key used to mark the style for use by the PageView /// private static ResourceKey PageViewStyleKey { get { if (_pageViewStyleKey == null) { _pageViewStyleKey = new ComponentResourceKey(typeof(PresentationUIStyleResources), "PUIPageViewStyleKey"); } return _pageViewStyleKey; } } ////// Key used to mark the style for use by the TwoPageView /// private static ResourceKey TwoPageViewStyleKey { get { if (_twoPageViewStyleKey == null) { _twoPageViewStyleKey = new ComponentResourceKey(typeof(PresentationUIStyleResources), "PUITwoPageViewStyleKey"); } return _twoPageViewStyleKey; } } ////// Key used to mark the style for use by the ScrollView /// private static ResourceKey ScrollViewStyleKey { get { if (_scrollViewStyleKey == null) { _scrollViewStyleKey = new ComponentResourceKey(typeof(PresentationUIStyleResources), "PUIScrollViewStyleKey"); } return _scrollViewStyleKey; } } private static ComponentResourceKey _pageViewStyleKey; private static ComponentResourceKey _twoPageViewStyleKey; private static ComponentResourceKey _scrollViewStyleKey; #endregion } ////// public enum FlowDocumentReaderViewingMode { /// /// Page, /// /// TwoPage, /// /// Scroll } } // 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
- BuildProviderCollection.cs
- EnumType.cs
- ZipIOBlockManager.cs
- CheckStoreFileValidityRequest.cs
- MarkupCompilePass1.cs
- SByte.cs
- FixedLineResult.cs
- PermissionAttributes.cs
- TextRunTypographyProperties.cs
- EntityDataSourceStatementEditorForm.cs
- Base64Encoder.cs
- RemotingServices.cs
- SelectionItemPatternIdentifiers.cs
- MulticastDelegate.cs
- OleDbFactory.cs
- OptimalBreakSession.cs
- HwndAppCommandInputProvider.cs
- ConfigXmlSignificantWhitespace.cs
- WebPartAddingEventArgs.cs
- BamlLocalizer.cs
- DataMemberConverter.cs
- StrongNameIdentityPermission.cs
- UmAlQuraCalendar.cs
- _KerberosClient.cs
- ColorTransform.cs
- PerformanceCounterPermissionAttribute.cs
- BasicAsyncResult.cs
- RelationshipManager.cs
- FormsAuthenticationEventArgs.cs
- DataGridViewSortCompareEventArgs.cs
- ListChunk.cs
- CodeConstructor.cs
- ToolStripProgressBar.cs
- ConfigXmlSignificantWhitespace.cs
- BinaryParser.cs
- Command.cs
- ObjectListDataBindEventArgs.cs
- JsonQNameDataContract.cs
- SecurityRequiresReviewAttribute.cs
- Property.cs
- UrlEncodedParameterWriter.cs
- Group.cs
- XmlImplementation.cs
- Expressions.cs
- ChannelManagerBase.cs
- ConstNode.cs
- Highlights.cs
- CheckBoxDesigner.cs
- XPathDocumentNavigator.cs
- FileReservationCollection.cs
- RegexCompiler.cs
- String.cs
- TransformGroup.cs
- DropShadowBitmapEffect.cs
- ObjectFullSpanRewriter.cs
- DiscoveryExceptionDictionary.cs
- ScriptReferenceBase.cs
- securitycriticaldataformultiplegetandset.cs
- TimelineCollection.cs
- Window.cs
- SpeechSeg.cs
- MetadataException.cs
- cookieexception.cs
- CodeAccessSecurityEngine.cs
- ServiceTimeoutsBehavior.cs
- Pts.cs
- Schema.cs
- XmlSchemaValidationException.cs
- DirectionalLight.cs
- KeyValuePair.cs
- ConfigurationSchemaErrors.cs
- GridLengthConverter.cs
- AbandonedMutexException.cs
- CopyAction.cs
- SectionUpdates.cs
- SafePointer.cs
- AutomationPatternInfo.cs
- login.cs
- ExceptionUtil.cs
- LocationReferenceValue.cs
- DataAdapter.cs
- UniqueIdentifierService.cs
- Cloud.cs
- StylesEditorDialog.cs
- TypographyProperties.cs
- CustomBindingCollectionElement.cs
- RegexRunnerFactory.cs
- TailCallAnalyzer.cs
- XPathSelfQuery.cs
- StorageSetMapping.cs
- Transactions.cs
- SpecularMaterial.cs
- AsymmetricKeyExchangeDeformatter.cs
- BoundPropertyEntry.cs
- PolicyChain.cs
- ErrorHandlingAcceptor.cs
- CachedFontFamily.cs
- DataListItem.cs
- HiddenFieldPageStatePersister.cs
- ReferenceEqualityComparer.cs