Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / MS / Internal / documents / IFlowDocumentViewer.cs / 1 / IFlowDocumentViewer.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // //--------------------------------------------------------------------------- using System; // Object, IServiceProvider using System.Windows; // Rect, Point using System.Windows.Documents; // ITextSelection using System.Windows.Controls; // FlowDocumentScrollViewer using System.Windows.Controls.Primitives; // IScrollInfo using System.Windows.Input; // UICommand using System.Windows.Threading; // Dispatcher using MS.Internal.KnownBoxes; // BooleanBoxes namespace MS.Internal.Documents { ////// An IFlowDocumentViewer is used for FlowDocumentReader in order to simplify its /// view switching logic. /// internal interface IFlowDocumentViewer { ////// Navigate to the previous page. /// void PreviousPage(); ////// Navigate to the next page. /// void NextPage(); ////// Navigate to the first page. /// void FirstPage(); ////// Navigate to the last page. /// void LastPage(); ////// Print the document. /// void Print(); ////// Cancel printing of the document. /// void CancelPrint(); ////// Show find result. /// void ShowFindResult(ITextRange findResult); ////// Whether can navigate to specific page number. /// /// Requested page number. ///Whether navigation is possible or not. bool CanGoToPage(int pageNumber); ////// Navigate to requested page number. /// /// Requested page number. void GoToPage(int pageNumber); ////// Associate the viewer with new document. /// /// New document. void SetDocument(FlowDocument document); ////// The content position of the document showed in the control. /// ContentPosition ContentPosition { get; set; } ////// The Selection of TextEditor /// ITextSelection TextSelection { get; set; } ////// Whether can navigate to the previous page. /// bool CanGoToPreviousPage { get; } ////// Whether can navigate to the next page. /// bool CanGoToNextPage { get; } ////// The one-based page number of the page being displayed. /// If there is no content, this value will be 0. /// int PageNumber { get; } ////// The number of pages currently available for viewing. /// int PageCount { get; } ////// Fired when the current page number has been changed. /// event EventHandler PageNumberChanged; ////// Fired when the page count has been changed. /// event EventHandler PageCountChanged; ////// Fired when the print has been started. /// event EventHandler PrintStarted; ////// Fired when the print has been completed. /// event EventHandler PrintCompleted; } ////// This class is an internal subclass of the FlowDocumentScrollViewer that provides /// IFlowDocumentViewer interface used by FlowDocumentReader. /// internal class ReaderScrollViewer : FlowDocumentScrollViewer, IFlowDocumentViewer { //------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------- #region Protected Methods ////// Called when print has been completed. /// protected override void OnPrintCompleted() { base.OnPrintCompleted(); if (_printCompleted != null) { _printCompleted(this, EventArgs.Empty); } } ////// Handler for the Print command. /// protected override void OnPrintCommand() { base.OnPrintCommand(); if (_printStarted != null && IsPrinting) { _printStarted(this, EventArgs.Empty); } } ////// Notification that a specified property has been changed. /// protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); // PageCount and PageNumber are dependent on Document property value. // Hence need to raise changed events when Document property is changing. if (e.Property == DocumentProperty) { if (_pageNumberChanged != null) { _pageNumberChanged(this, EventArgs.Empty); } if (_pageCountChanged != null) { _pageCountChanged(this, EventArgs.Empty); } } } #endregion Protected Methods //-------------------------------------------------------------------- // // Private Methods // //------------------------------------------------------------------- #region Private Methods ////// Returns whether TextSelection is valid for document - As this is flow document, we require the text containers to be equal /// to allow it as a valid selection. /// private bool IsValidTextSelectionForDocument(ITextSelection textSelection, FlowDocument flowDocument) { if(textSelection.Start != null && textSelection.Start.TextContainer == flowDocument.StructuralCache.TextContainer) { return true; } return false; } ////// Set TextSelection. /// private object SetTextSelection(object arg) { ITextSelection newTextSelection = arg as ITextSelection; if (newTextSelection != null && Document != null && IsValidTextSelectionForDocument(newTextSelection, Document)) { ITextSelection textSelection = Document.StructuralCache.TextContainer.TextSelection; if (textSelection != null) { textSelection.SetCaretToPosition(newTextSelection.AnchorPosition, newTextSelection.MovingPosition.LogicalDirection, true, true); textSelection.ExtendToPosition(newTextSelection.MovingPosition); } } return null; } #endregion Private Methods //-------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------- #region Private Fields private EventHandler _pageNumberChanged; private EventHandler _pageCountChanged; private EventHandler _printCompleted; private EventHandler _printStarted; #endregion Private Fields //------------------------------------------------------------------- // // IFlowDocumentViewer Members // //-------------------------------------------------------------------- #region IFlowDocumentViewer Members ////// void IFlowDocumentViewer.PreviousPage() { if (ScrollViewer != null) { ScrollViewer.PageUp(); } } ////// /// void IFlowDocumentViewer.NextPage() { if (ScrollViewer != null) { ScrollViewer.PageDown(); } } ////// /// void IFlowDocumentViewer.FirstPage() { if (ScrollViewer != null) { ScrollViewer.ScrollToHome(); } } ////// /// void IFlowDocumentViewer.LastPage() { if (ScrollViewer != null) { ScrollViewer.ScrollToEnd(); } } ////// /// void IFlowDocumentViewer.Print() { OnPrintCommand(); } ////// /// void IFlowDocumentViewer.CancelPrint() { OnCancelPrintCommand(); } ////// /// void IFlowDocumentViewer.ShowFindResult(ITextRange findResult) { // If we found something, TextEditor will bring the selection into view. // It is possible, because RenderScope is inside ScrollViewer. } ////// /// bool IFlowDocumentViewer.CanGoToPage(int pageNumber) { // FlowDocumentScrollViewer is always a 1 page document, so its page number will always be 1 return (pageNumber == 1); } ////// /// void IFlowDocumentViewer.GoToPage(int pageNumber) { if (pageNumber == 1 && ScrollViewer != null) { ScrollViewer.ScrollToHome(); } } ////// /// void IFlowDocumentViewer.SetDocument(FlowDocument document) { Document = document; } ////// /// ContentPosition IFlowDocumentViewer.ContentPosition { get { return this.ContentPosition; } set { if (value != null && Document != null) { // This need be called because the UI may not be ready when Contentposition is set. Dispatcher.BeginInvoke(DispatcherPriority.Input, new DispatcherOperationCallback(BringContentPositionIntoView), value); } } } ////// /// ITextSelection IFlowDocumentViewer.TextSelection { get { return this.Selection; } set { if (value != null && Document != null) { // This need be called because the UI may not be ready when Contentposition is set. Dispatcher.BeginInvoke(DispatcherPriority.Input, new DispatcherOperationCallback(SetTextSelection), value); } } } ////// /// bool IFlowDocumentViewer.CanGoToPreviousPage { get { return false; } } ////// /// bool IFlowDocumentViewer.CanGoToNextPage { get { return false; } } ////// /// int IFlowDocumentViewer.PageNumber { get { return (Document != null) ? 1 : 0; } } ////// /// int IFlowDocumentViewer.PageCount { get { return (Document != null) ? 1 : 0; } } ////// /// event EventHandler IFlowDocumentViewer.PageNumberChanged { add { _pageNumberChanged += value; } remove { _pageNumberChanged -= value; } } ////// /// event EventHandler IFlowDocumentViewer.PageCountChanged { add { _pageCountChanged += value; } remove { _pageCountChanged -= value; } } ////// /// event EventHandler IFlowDocumentViewer.PrintStarted { add { _printStarted += value; } remove { _printStarted -= value; } } ////// /// event EventHandler IFlowDocumentViewer.PrintCompleted { add { _printCompleted += value; } remove { _printCompleted -= value; } } #endregion IFlowDocumentViewer Members } ////// /// This class is an internal subclass of the FlowDocumentPageViewer that provides /// IFlowDocumentViewer interface used by FlowDocumentReader. /// internal class ReaderPageViewer : FlowDocumentPageViewer, IFlowDocumentViewer { //------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------- #region Protected Methods ////// Called when print has been completed. /// protected override void OnPrintCompleted() { base.OnPrintCompleted(); if (_printCompleted != null) { _printCompleted(this, EventArgs.Empty); } } ////// Handler for the Print command. /// protected override void OnPrintCommand() { base.OnPrintCommand(); if (_printStarted != null && IsPrinting) { _printStarted(this, EventArgs.Empty); } } ////// Notification that a specified property has been changed. /// protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); // Reader control depends on the actual value of PageCount, PageNumber // CanGoToPreviousPage and CanGoToNextPage. So when values of those // properties are changing, schedule async update of the viewer. if (e.Property == PageCountProperty || e.Property == MasterPageNumberProperty || e.Property == CanGoToPreviousPageProperty || e.Property == CanGoToNextPageProperty) { // If there is already pending update request, do nothng. Otherwise schedule a dispatcher task. if (!_raisePageNumberChanged && !_raisePageCountChanged) { Dispatcher.BeginInvoke(DispatcherPriority.Input, new DispatcherOperationCallback(RaisePropertyChangedAsync), null); } // Treat CanGoToPage properties as PageNumber. Becasuse PageNumber change affects // those properties, the reader control will update them. if (e.Property == PageCountProperty) { _raisePageCountChanged = true; CoerceValue(CanGoToNextPageProperty); } else if (e.Property == MasterPageNumberProperty) { _raisePageNumberChanged = true; CoerceValue(CanGoToNextPageProperty); } else { _raisePageNumberChanged = true; } } } #endregion Protected Methods //------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------- #region Private Methods ////// Set TextSelection. /// private object SetTextSelection(object arg) { ITextSelection newTextSelection = arg as ITextSelection; FlowDocument flowDocument = Document as FlowDocument; if (newTextSelection != null && flowDocument != null && newTextSelection.AnchorPosition != null && newTextSelection.AnchorPosition.TextContainer == flowDocument.StructuralCache.TextContainer) { ITextSelection textSelection = flowDocument.StructuralCache.TextContainer.TextSelection; if (textSelection != null) { textSelection.SetCaretToPosition(newTextSelection.AnchorPosition, newTextSelection.MovingPosition.LogicalDirection, true, true); textSelection.ExtendToPosition(newTextSelection.MovingPosition); } } return null; } ////// Asynchronously notify about property changes. /// private object RaisePropertyChangedAsync(object arg) { // PageCount and PageNumber are dependent on associated DP values. // Hence need to raise changed events when those DPs are changing. if (_raisePageCountChanged) { if (_pageCountChanged != null) { _pageCountChanged(this, EventArgs.Empty); } _raisePageCountChanged = false; } if (_raisePageNumberChanged) { if (_pageNumberChanged != null) { _pageNumberChanged(this, EventArgs.Empty); } _raisePageNumberChanged = false; } return null; } #endregion Private Methods //------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------- #region Private Fields private EventHandler _pageNumberChanged; private EventHandler _pageCountChanged; private EventHandler _printCompleted; private EventHandler _printStarted; private bool _raisePageNumberChanged; private bool _raisePageCountChanged; #endregion Private Fields //-------------------------------------------------------------------- // // IFlowDocumentViewer Members // //------------------------------------------------------------------- #region IFlowDocumentViewer Members ////// void IFlowDocumentViewer.PreviousPage() { OnPreviousPageCommand(); } ////// /// void IFlowDocumentViewer.NextPage() { OnNextPageCommand(); } ////// /// void IFlowDocumentViewer.FirstPage() { OnFirstPageCommand(); } ////// /// void IFlowDocumentViewer.LastPage() { OnLastPageCommand(); } ////// /// void IFlowDocumentViewer.Print() { OnPrintCommand(); } ////// /// void IFlowDocumentViewer.CancelPrint() { OnCancelPrintCommand(); } ////// /// void IFlowDocumentViewer.ShowFindResult(ITextRange findResult) { if (findResult.Start is ContentPosition) { BringContentPositionIntoView((ContentPosition)findResult.Start); } } ////// /// bool IFlowDocumentViewer.CanGoToPage(int pageNumber) { return CanGoToPage(pageNumber); } ////// /// void IFlowDocumentViewer.GoToPage(int pageNumber) { OnGoToPageCommand(pageNumber); } ////// /// void IFlowDocumentViewer.SetDocument(FlowDocument document) { Document = document; } ////// /// ContentPosition IFlowDocumentViewer.ContentPosition { get { return ContentPosition; } set { if (value != null && Document != null) { // This need be called because the UI may not be ready when Contentposition is set. Dispatcher.BeginInvoke(DispatcherPriority.Input, new DispatcherOperationCallback(BringContentPositionIntoView), value); } } } ////// /// ITextSelection IFlowDocumentViewer.TextSelection { get { return this.Selection; } set { if (value != null && Document != null) { // This need be called because the UI may not be ready when Contentposition is set. Dispatcher.BeginInvoke(DispatcherPriority.Input, new DispatcherOperationCallback(SetTextSelection), value); } } } ////// /// bool IFlowDocumentViewer.CanGoToPreviousPage { get { return CanGoToPreviousPage; } } ////// /// bool IFlowDocumentViewer.CanGoToNextPage { get { return CanGoToNextPage; } } ////// /// int IFlowDocumentViewer.PageNumber { get { return MasterPageNumber; } } ////// /// int IFlowDocumentViewer.PageCount { get { return PageCount; } } ////// /// event EventHandler IFlowDocumentViewer.PageNumberChanged { add { _pageNumberChanged += value; } remove { _pageNumberChanged -= value; } } ////// /// event EventHandler IFlowDocumentViewer.PageCountChanged { add { _pageCountChanged += value; } remove { _pageCountChanged -= value; } } ////// /// event EventHandler IFlowDocumentViewer.PrintStarted { add { _printStarted += value; } remove { _printStarted -= value; } } ////// /// event EventHandler IFlowDocumentViewer.PrintCompleted { add { _printCompleted += value; } remove { _printCompleted -= value; } } #endregion IFlowDocumentViewer Members } ////// /// This class is an internal subclass of the FlowDocumentPageViewer that provides /// IFlowDocumentViewer interface used by FlowDocumentReader. /// In addition to that it also provides support for TwoPage view. /// internal class ReaderTwoPageViewer : ReaderPageViewer { //-------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------- #region Protected Methods ////// Handler for the PreviousPage command. /// protected override void OnPreviousPageCommand() { GoToPage(Math.Max(1, MasterPageNumber - 2)); } ////// Handler for the NextPage command. /// protected override void OnNextPageCommand() { GoToPage(Math.Min(PageCount, MasterPageNumber + 2)); } ////// Handler for the LastPage command. /// protected override void OnLastPageCommand() { // Always navigate to odd PageNumber GoToPage(PageCount); } ////// Handler for the GoToPage command. /// /// protected override void OnGoToPageCommand(int pageNumber) { // Go to only odd page numbers. base.OnGoToPageCommand((((pageNumber - 1) / 2) * 2) + 1); } ////// Notification that a specified property has been changed. /// protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.Property == MasterPageNumberProperty) { // Only odd page numbers are allowed. int pageNumber = (int)e.NewValue; pageNumber = (((pageNumber - 1) / 2) * 2) + 1; if (pageNumber != (int)e.NewValue) { GoToPage(pageNumber); } } } #endregion Protected Methods //------------------------------------------------------------------- // // Private Methods // //------------------------------------------------------------------- #region Private Methods static ReaderTwoPageViewer() { CanGoToNextPagePropertyKey.OverrideMetadata(typeof(ReaderTwoPageViewer), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox, null, new CoerceValueCallback(CoerceCanGoToNextPage))); } ////// Coerce the value for CanGoToNextPage property. /// private static object CoerceCanGoToNextPage(DependencyObject d, object value) { Invariant.Assert(d != null && d is ReaderTwoPageViewer); ReaderTwoPageViewer viewer = (ReaderTwoPageViewer)d; return (viewer.MasterPageNumber < viewer.PageCount - 1); } #endregion Private Methods } } // 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. // //--------------------------------------------------------------------------- using System; // Object, IServiceProvider using System.Windows; // Rect, Point using System.Windows.Documents; // ITextSelection using System.Windows.Controls; // FlowDocumentScrollViewer using System.Windows.Controls.Primitives; // IScrollInfo using System.Windows.Input; // UICommand using System.Windows.Threading; // Dispatcher using MS.Internal.KnownBoxes; // BooleanBoxes namespace MS.Internal.Documents { ////// An IFlowDocumentViewer is used for FlowDocumentReader in order to simplify its /// view switching logic. /// internal interface IFlowDocumentViewer { ////// Navigate to the previous page. /// void PreviousPage(); ////// Navigate to the next page. /// void NextPage(); ////// Navigate to the first page. /// void FirstPage(); ////// Navigate to the last page. /// void LastPage(); ////// Print the document. /// void Print(); ////// Cancel printing of the document. /// void CancelPrint(); ////// Show find result. /// void ShowFindResult(ITextRange findResult); ////// Whether can navigate to specific page number. /// /// Requested page number. ///Whether navigation is possible or not. bool CanGoToPage(int pageNumber); ////// Navigate to requested page number. /// /// Requested page number. void GoToPage(int pageNumber); ////// Associate the viewer with new document. /// /// New document. void SetDocument(FlowDocument document); ////// The content position of the document showed in the control. /// ContentPosition ContentPosition { get; set; } ////// The Selection of TextEditor /// ITextSelection TextSelection { get; set; } ////// Whether can navigate to the previous page. /// bool CanGoToPreviousPage { get; } ////// Whether can navigate to the next page. /// bool CanGoToNextPage { get; } ////// The one-based page number of the page being displayed. /// If there is no content, this value will be 0. /// int PageNumber { get; } ////// The number of pages currently available for viewing. /// int PageCount { get; } ////// Fired when the current page number has been changed. /// event EventHandler PageNumberChanged; ////// Fired when the page count has been changed. /// event EventHandler PageCountChanged; ////// Fired when the print has been started. /// event EventHandler PrintStarted; ////// Fired when the print has been completed. /// event EventHandler PrintCompleted; } ////// This class is an internal subclass of the FlowDocumentScrollViewer that provides /// IFlowDocumentViewer interface used by FlowDocumentReader. /// internal class ReaderScrollViewer : FlowDocumentScrollViewer, IFlowDocumentViewer { //------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------- #region Protected Methods ////// Called when print has been completed. /// protected override void OnPrintCompleted() { base.OnPrintCompleted(); if (_printCompleted != null) { _printCompleted(this, EventArgs.Empty); } } ////// Handler for the Print command. /// protected override void OnPrintCommand() { base.OnPrintCommand(); if (_printStarted != null && IsPrinting) { _printStarted(this, EventArgs.Empty); } } ////// Notification that a specified property has been changed. /// protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); // PageCount and PageNumber are dependent on Document property value. // Hence need to raise changed events when Document property is changing. if (e.Property == DocumentProperty) { if (_pageNumberChanged != null) { _pageNumberChanged(this, EventArgs.Empty); } if (_pageCountChanged != null) { _pageCountChanged(this, EventArgs.Empty); } } } #endregion Protected Methods //-------------------------------------------------------------------- // // Private Methods // //------------------------------------------------------------------- #region Private Methods ////// Returns whether TextSelection is valid for document - As this is flow document, we require the text containers to be equal /// to allow it as a valid selection. /// private bool IsValidTextSelectionForDocument(ITextSelection textSelection, FlowDocument flowDocument) { if(textSelection.Start != null && textSelection.Start.TextContainer == flowDocument.StructuralCache.TextContainer) { return true; } return false; } ////// Set TextSelection. /// private object SetTextSelection(object arg) { ITextSelection newTextSelection = arg as ITextSelection; if (newTextSelection != null && Document != null && IsValidTextSelectionForDocument(newTextSelection, Document)) { ITextSelection textSelection = Document.StructuralCache.TextContainer.TextSelection; if (textSelection != null) { textSelection.SetCaretToPosition(newTextSelection.AnchorPosition, newTextSelection.MovingPosition.LogicalDirection, true, true); textSelection.ExtendToPosition(newTextSelection.MovingPosition); } } return null; } #endregion Private Methods //-------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------- #region Private Fields private EventHandler _pageNumberChanged; private EventHandler _pageCountChanged; private EventHandler _printCompleted; private EventHandler _printStarted; #endregion Private Fields //------------------------------------------------------------------- // // IFlowDocumentViewer Members // //-------------------------------------------------------------------- #region IFlowDocumentViewer Members ////// void IFlowDocumentViewer.PreviousPage() { if (ScrollViewer != null) { ScrollViewer.PageUp(); } } ////// /// void IFlowDocumentViewer.NextPage() { if (ScrollViewer != null) { ScrollViewer.PageDown(); } } ////// /// void IFlowDocumentViewer.FirstPage() { if (ScrollViewer != null) { ScrollViewer.ScrollToHome(); } } ////// /// void IFlowDocumentViewer.LastPage() { if (ScrollViewer != null) { ScrollViewer.ScrollToEnd(); } } ////// /// void IFlowDocumentViewer.Print() { OnPrintCommand(); } ////// /// void IFlowDocumentViewer.CancelPrint() { OnCancelPrintCommand(); } ////// /// void IFlowDocumentViewer.ShowFindResult(ITextRange findResult) { // If we found something, TextEditor will bring the selection into view. // It is possible, because RenderScope is inside ScrollViewer. } ////// /// bool IFlowDocumentViewer.CanGoToPage(int pageNumber) { // FlowDocumentScrollViewer is always a 1 page document, so its page number will always be 1 return (pageNumber == 1); } ////// /// void IFlowDocumentViewer.GoToPage(int pageNumber) { if (pageNumber == 1 && ScrollViewer != null) { ScrollViewer.ScrollToHome(); } } ////// /// void IFlowDocumentViewer.SetDocument(FlowDocument document) { Document = document; } ////// /// ContentPosition IFlowDocumentViewer.ContentPosition { get { return this.ContentPosition; } set { if (value != null && Document != null) { // This need be called because the UI may not be ready when Contentposition is set. Dispatcher.BeginInvoke(DispatcherPriority.Input, new DispatcherOperationCallback(BringContentPositionIntoView), value); } } } ////// /// ITextSelection IFlowDocumentViewer.TextSelection { get { return this.Selection; } set { if (value != null && Document != null) { // This need be called because the UI may not be ready when Contentposition is set. Dispatcher.BeginInvoke(DispatcherPriority.Input, new DispatcherOperationCallback(SetTextSelection), value); } } } ////// /// bool IFlowDocumentViewer.CanGoToPreviousPage { get { return false; } } ////// /// bool IFlowDocumentViewer.CanGoToNextPage { get { return false; } } ////// /// int IFlowDocumentViewer.PageNumber { get { return (Document != null) ? 1 : 0; } } ////// /// int IFlowDocumentViewer.PageCount { get { return (Document != null) ? 1 : 0; } } ////// /// event EventHandler IFlowDocumentViewer.PageNumberChanged { add { _pageNumberChanged += value; } remove { _pageNumberChanged -= value; } } ////// /// event EventHandler IFlowDocumentViewer.PageCountChanged { add { _pageCountChanged += value; } remove { _pageCountChanged -= value; } } ////// /// event EventHandler IFlowDocumentViewer.PrintStarted { add { _printStarted += value; } remove { _printStarted -= value; } } ////// /// event EventHandler IFlowDocumentViewer.PrintCompleted { add { _printCompleted += value; } remove { _printCompleted -= value; } } #endregion IFlowDocumentViewer Members } ////// /// This class is an internal subclass of the FlowDocumentPageViewer that provides /// IFlowDocumentViewer interface used by FlowDocumentReader. /// internal class ReaderPageViewer : FlowDocumentPageViewer, IFlowDocumentViewer { //------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------- #region Protected Methods ////// Called when print has been completed. /// protected override void OnPrintCompleted() { base.OnPrintCompleted(); if (_printCompleted != null) { _printCompleted(this, EventArgs.Empty); } } ////// Handler for the Print command. /// protected override void OnPrintCommand() { base.OnPrintCommand(); if (_printStarted != null && IsPrinting) { _printStarted(this, EventArgs.Empty); } } ////// Notification that a specified property has been changed. /// protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); // Reader control depends on the actual value of PageCount, PageNumber // CanGoToPreviousPage and CanGoToNextPage. So when values of those // properties are changing, schedule async update of the viewer. if (e.Property == PageCountProperty || e.Property == MasterPageNumberProperty || e.Property == CanGoToPreviousPageProperty || e.Property == CanGoToNextPageProperty) { // If there is already pending update request, do nothng. Otherwise schedule a dispatcher task. if (!_raisePageNumberChanged && !_raisePageCountChanged) { Dispatcher.BeginInvoke(DispatcherPriority.Input, new DispatcherOperationCallback(RaisePropertyChangedAsync), null); } // Treat CanGoToPage properties as PageNumber. Becasuse PageNumber change affects // those properties, the reader control will update them. if (e.Property == PageCountProperty) { _raisePageCountChanged = true; CoerceValue(CanGoToNextPageProperty); } else if (e.Property == MasterPageNumberProperty) { _raisePageNumberChanged = true; CoerceValue(CanGoToNextPageProperty); } else { _raisePageNumberChanged = true; } } } #endregion Protected Methods //------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------- #region Private Methods ////// Set TextSelection. /// private object SetTextSelection(object arg) { ITextSelection newTextSelection = arg as ITextSelection; FlowDocument flowDocument = Document as FlowDocument; if (newTextSelection != null && flowDocument != null && newTextSelection.AnchorPosition != null && newTextSelection.AnchorPosition.TextContainer == flowDocument.StructuralCache.TextContainer) { ITextSelection textSelection = flowDocument.StructuralCache.TextContainer.TextSelection; if (textSelection != null) { textSelection.SetCaretToPosition(newTextSelection.AnchorPosition, newTextSelection.MovingPosition.LogicalDirection, true, true); textSelection.ExtendToPosition(newTextSelection.MovingPosition); } } return null; } ////// Asynchronously notify about property changes. /// private object RaisePropertyChangedAsync(object arg) { // PageCount and PageNumber are dependent on associated DP values. // Hence need to raise changed events when those DPs are changing. if (_raisePageCountChanged) { if (_pageCountChanged != null) { _pageCountChanged(this, EventArgs.Empty); } _raisePageCountChanged = false; } if (_raisePageNumberChanged) { if (_pageNumberChanged != null) { _pageNumberChanged(this, EventArgs.Empty); } _raisePageNumberChanged = false; } return null; } #endregion Private Methods //------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------- #region Private Fields private EventHandler _pageNumberChanged; private EventHandler _pageCountChanged; private EventHandler _printCompleted; private EventHandler _printStarted; private bool _raisePageNumberChanged; private bool _raisePageCountChanged; #endregion Private Fields //-------------------------------------------------------------------- // // IFlowDocumentViewer Members // //------------------------------------------------------------------- #region IFlowDocumentViewer Members ////// void IFlowDocumentViewer.PreviousPage() { OnPreviousPageCommand(); } ////// /// void IFlowDocumentViewer.NextPage() { OnNextPageCommand(); } ////// /// void IFlowDocumentViewer.FirstPage() { OnFirstPageCommand(); } ////// /// void IFlowDocumentViewer.LastPage() { OnLastPageCommand(); } ////// /// void IFlowDocumentViewer.Print() { OnPrintCommand(); } ////// /// void IFlowDocumentViewer.CancelPrint() { OnCancelPrintCommand(); } ////// /// void IFlowDocumentViewer.ShowFindResult(ITextRange findResult) { if (findResult.Start is ContentPosition) { BringContentPositionIntoView((ContentPosition)findResult.Start); } } ////// /// bool IFlowDocumentViewer.CanGoToPage(int pageNumber) { return CanGoToPage(pageNumber); } ////// /// void IFlowDocumentViewer.GoToPage(int pageNumber) { OnGoToPageCommand(pageNumber); } ////// /// void IFlowDocumentViewer.SetDocument(FlowDocument document) { Document = document; } ////// /// ContentPosition IFlowDocumentViewer.ContentPosition { get { return ContentPosition; } set { if (value != null && Document != null) { // This need be called because the UI may not be ready when Contentposition is set. Dispatcher.BeginInvoke(DispatcherPriority.Input, new DispatcherOperationCallback(BringContentPositionIntoView), value); } } } ////// /// ITextSelection IFlowDocumentViewer.TextSelection { get { return this.Selection; } set { if (value != null && Document != null) { // This need be called because the UI may not be ready when Contentposition is set. Dispatcher.BeginInvoke(DispatcherPriority.Input, new DispatcherOperationCallback(SetTextSelection), value); } } } ////// /// bool IFlowDocumentViewer.CanGoToPreviousPage { get { return CanGoToPreviousPage; } } ////// /// bool IFlowDocumentViewer.CanGoToNextPage { get { return CanGoToNextPage; } } ////// /// int IFlowDocumentViewer.PageNumber { get { return MasterPageNumber; } } ////// /// int IFlowDocumentViewer.PageCount { get { return PageCount; } } ////// /// event EventHandler IFlowDocumentViewer.PageNumberChanged { add { _pageNumberChanged += value; } remove { _pageNumberChanged -= value; } } ////// /// event EventHandler IFlowDocumentViewer.PageCountChanged { add { _pageCountChanged += value; } remove { _pageCountChanged -= value; } } ////// /// event EventHandler IFlowDocumentViewer.PrintStarted { add { _printStarted += value; } remove { _printStarted -= value; } } ////// /// event EventHandler IFlowDocumentViewer.PrintCompleted { add { _printCompleted += value; } remove { _printCompleted -= value; } } #endregion IFlowDocumentViewer Members } ////// /// This class is an internal subclass of the FlowDocumentPageViewer that provides /// IFlowDocumentViewer interface used by FlowDocumentReader. /// In addition to that it also provides support for TwoPage view. /// internal class ReaderTwoPageViewer : ReaderPageViewer { //-------------------------------------------------------------------- // // Protected Methods // //------------------------------------------------------------------- #region Protected Methods ////// Handler for the PreviousPage command. /// protected override void OnPreviousPageCommand() { GoToPage(Math.Max(1, MasterPageNumber - 2)); } ////// Handler for the NextPage command. /// protected override void OnNextPageCommand() { GoToPage(Math.Min(PageCount, MasterPageNumber + 2)); } ////// Handler for the LastPage command. /// protected override void OnLastPageCommand() { // Always navigate to odd PageNumber GoToPage(PageCount); } ////// Handler for the GoToPage command. /// /// protected override void OnGoToPageCommand(int pageNumber) { // Go to only odd page numbers. base.OnGoToPageCommand((((pageNumber - 1) / 2) * 2) + 1); } ////// Notification that a specified property has been changed. /// protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.Property == MasterPageNumberProperty) { // Only odd page numbers are allowed. int pageNumber = (int)e.NewValue; pageNumber = (((pageNumber - 1) / 2) * 2) + 1; if (pageNumber != (int)e.NewValue) { GoToPage(pageNumber); } } } #endregion Protected Methods //------------------------------------------------------------------- // // Private Methods // //------------------------------------------------------------------- #region Private Methods static ReaderTwoPageViewer() { CanGoToNextPagePropertyKey.OverrideMetadata(typeof(ReaderTwoPageViewer), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox, null, new CoerceValueCallback(CoerceCanGoToNextPage))); } ////// Coerce the value for CanGoToNextPage property. /// private static object CoerceCanGoToNextPage(DependencyObject d, object value) { Invariant.Assert(d != null && d is ReaderTwoPageViewer); ReaderTwoPageViewer viewer = (ReaderTwoPageViewer)d; return (viewer.MasterPageNumber < viewer.PageCount - 1); } #endregion Private Methods } } // 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
- Clause.cs
- HostedElements.cs
- TableLayoutRowStyleCollection.cs
- DynamicEntity.cs
- MenuItemBindingCollection.cs
- WebPartTransformerAttribute.cs
- DoubleKeyFrameCollection.cs
- UIElementCollection.cs
- PlaceHolder.cs
- ZoomPercentageConverter.cs
- XPathPatternParser.cs
- InternalControlCollection.cs
- UnsafeNetInfoNativeMethods.cs
- SqlBulkCopy.cs
- UrlRoutingHandler.cs
- safelink.cs
- AppendHelper.cs
- IPGlobalProperties.cs
- Converter.cs
- PieceNameHelper.cs
- SocketPermission.cs
- MultiTrigger.cs
- BrushMappingModeValidation.cs
- ProfileSection.cs
- RegisteredDisposeScript.cs
- HwndKeyboardInputProvider.cs
- BoundPropertyEntry.cs
- ActivationServices.cs
- EncoderFallback.cs
- LinearKeyFrames.cs
- LinearGradientBrush.cs
- IsolatedStorageFilePermission.cs
- HtmlControl.cs
- ComponentResourceManager.cs
- ExpressionBinding.cs
- CounterSample.cs
- TextSearch.cs
- Link.cs
- Span.cs
- WebServiceReceiveDesigner.cs
- BufferedReadStream.cs
- NumberSubstitution.cs
- Rotation3DAnimationBase.cs
- SQLBytesStorage.cs
- ToolStripSeparatorRenderEventArgs.cs
- UserControlParser.cs
- StreamInfo.cs
- JournalNavigationScope.cs
- TraceSource.cs
- _AutoWebProxyScriptEngine.cs
- TextReader.cs
- DatatypeImplementation.cs
- SafeMemoryMappedFileHandle.cs
- _BufferOffsetSize.cs
- DataViewSettingCollection.cs
- InitializationEventAttribute.cs
- DefaultTextStoreTextComposition.cs
- _FtpDataStream.cs
- TextSimpleMarkerProperties.cs
- AssemblyNameProxy.cs
- Button.cs
- RepeaterItemEventArgs.cs
- ThreadAttributes.cs
- Italic.cs
- XmlMembersMapping.cs
- UndoManager.cs
- FormClosedEvent.cs
- RenderContext.cs
- RequestNavigateEventArgs.cs
- FileDetails.cs
- IERequestCache.cs
- ApplicationException.cs
- ExclusiveCanonicalizationTransform.cs
- RuleSettings.cs
- InfoCardTraceRecord.cs
- EncodingDataItem.cs
- metadatamappinghashervisitor.cs
- RIPEMD160.cs
- HttpProcessUtility.cs
- XmlSchemaDatatype.cs
- ImmutableObjectAttribute.cs
- ExceptionRoutedEventArgs.cs
- SystemIPAddressInformation.cs
- UInt32Storage.cs
- AssemblyCache.cs
- Convert.cs
- TemplateBindingExtension.cs
- SwitchLevelAttribute.cs
- InlineCollection.cs
- WindowsAltTab.cs
- DataGridViewCellEventArgs.cs
- XmlSchemaAttribute.cs
- ScrollPattern.cs
- ConfigurationSectionCollection.cs
- StringSource.cs
- OdbcConnection.cs
- IResourceProvider.cs
- GPRECTF.cs
- UpDownEvent.cs
- SEHException.cs