Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / MS / Internal / documents / DocumentPageTextView.cs / 1 / DocumentPageTextView.cs
//----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// File: DocumentPageTextView.cs
//
// Description: TextView implementation for DocumentPageView.
//
//---------------------------------------------------------------------------
using System; // InvalidOperationException, ...
using System.Collections.Generic; // List
using System.Collections.ObjectModel; // ReadOnlyCollection
using System.Windows; // Point, Rect, ...
using System.Windows.Controls.Primitives; // DocumentPageView
using System.Windows.Documents; // ITextView, ITextContainer
using System.Windows.Media; // VisualTreeHelper
using MS.Internal.PtsHost; // BackgroundFormatInfo
namespace MS.Internal.Documents
{
///
/// TextView implementation for DocumentPageView.
///
internal class DocumentPageTextView : TextViewBase
{
//-------------------------------------------------------------------
//
// Constructors
//
//-------------------------------------------------------------------
#region Constructors
///
/// Constructor.
///
///
/// Root of layout structure visualizing content of a page.
///
///
/// TextContainer representing content.
///
internal DocumentPageTextView(DocumentPageView owner, ITextContainer textContainer)
{
Invariant.Assert(owner != null && textContainer != null);
_owner = owner;
_page = owner.DocumentPageInternal;
_textContainer = textContainer;
// Retrive inner TextView
if (_page is IServiceProvider)
{
_pageTextView = ((IServiceProvider)_page).GetService(typeof(ITextView)) as ITextView;
}
if (_pageTextView != null)
{
_pageTextView.Updated += new EventHandler(HandlePageTextViewUpdated);
}
}
///
/// Constructor.
///
///
/// Root of layout structure visualizing content of a page.
///
///
/// TextContainer representing content.
///
internal DocumentPageTextView(FlowDocumentView owner, ITextContainer textContainer)
{
Invariant.Assert(owner != null && textContainer != null);
_owner = owner;
_page = owner.DocumentPage;
_textContainer = textContainer;
// Retrive inner TextView
if (_page is IServiceProvider)
{
_pageTextView = ((IServiceProvider)_page).GetService(typeof(ITextView)) as ITextView;
}
if (_pageTextView != null)
{
_pageTextView.Updated += new EventHandler(HandlePageTextViewUpdated);
}
}
#endregion Constructors
//--------------------------------------------------------------------
//
// Internal Methods
//
//-------------------------------------------------------------------
#region Internal Methods
///
///
///
internal override ITextPointer GetTextPositionFromPoint(Point point, bool snapToText)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return null;
}
// Transform to page coordinates.
point = TransformToDescendant(point);
return _pageTextView.GetTextPositionFromPoint(point, snapToText);
}
///
///
///
internal override Rect GetRawRectangleFromTextPosition(ITextPointer position, out Transform transform)
{
Rect rect;
Transform pageTextViewTransform, ancestorTransform;
// Initialize transform to identity
transform = Transform.Identity;
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return Rect.Empty;
}
rect = _pageTextView.GetRawRectangleFromTextPosition(position, out pageTextViewTransform);
Invariant.Assert(pageTextViewTransform != null);
ancestorTransform = GetTransformToAncestor();
transform = GetAggregateTransform(pageTextViewTransform, ancestorTransform);
return rect;
}
///
///
///
internal override Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition)
{
// verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
Geometry geometry = null;
if (!IsPageMissing)
{
geometry = _pageTextView.GetTightBoundingGeometryFromTextPositions(startPosition, endPosition);
if (geometry != null)
{
Transform transform = GetTransformToAncestor().AffineTransform;
CaretElement.AddTransformToGeometry(geometry, transform);
}
}
return (geometry);
}
///
///
///
internal override ITextPointer GetPositionAtNextLine(ITextPointer position, double suggestedX, int count, out double newSuggestedX, out int linesMoved)
{
ITextPointer positionOut;
Point offset;
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
newSuggestedX = suggestedX;
linesMoved = 0;
return position;
}
offset = TransformToDescendant(new Point(suggestedX, 0));
suggestedX = offset.X;
positionOut = _pageTextView.GetPositionAtNextLine(position, suggestedX, count, out newSuggestedX, out linesMoved);
offset = TransformToAncestor(new Point(newSuggestedX, 0));
newSuggestedX = offset.X;
return positionOut;
}
///
///
///
internal override ITextPointer GetPositionAtNextPage(ITextPointer position, Point suggestedOffset, int count, out Point newSuggestedOffset, out int pagesMoved)
{
ITextPointer positionOut = position;
newSuggestedOffset = suggestedOffset;
Point offset = suggestedOffset;
pagesMoved = 0;
if (count == 0)
{
return positionOut;
}
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return position;
}
// Calculate distance from current position
offset.Y = GetYOffsetAtNextPage(offset.Y, count, out pagesMoved);
if (pagesMoved != 0)
{
// Transfrom offset to _pageTextView's coordinate position, obtain position from _pageTextView and convert back
offset = TransformToDescendant(offset);
positionOut = _pageTextView.GetTextPositionFromPoint(offset, true);
Invariant.Assert(positionOut != null);
Rect rect = _pageTextView.GetRectangleFromTextPosition(position);
newSuggestedOffset = TransformToAncestor(new Point(rect.X, rect.Y));
}
return positionOut;
}
///
///
///
internal override bool IsAtCaretUnitBoundary(ITextPointer position)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return false;
}
return _pageTextView.IsAtCaretUnitBoundary(position);
}
///
///
///
internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return null;
}
return _pageTextView.GetNextCaretUnitPosition(position, direction);
}
///
///
///
internal override ITextPointer GetBackspaceCaretUnitPosition(ITextPointer position)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return null;
}
return _pageTextView.GetBackspaceCaretUnitPosition(position);
}
///
///
///
internal override TextSegment GetLineRange(ITextPointer position)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return TextSegment.Null;
}
return _pageTextView.GetLineRange(position);
}
///
///
///
internal override ReadOnlyCollection GetGlyphRuns(ITextPointer start, ITextPointer end)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return new ReadOnlyCollection(new List());
}
return _pageTextView.GetGlyphRuns(start, end);
}
///
///
///
internal override bool Contains(ITextPointer position)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return false;
}
return _pageTextView.Contains(position);
}
///
/// Handler for PageConnected raised by the DocumentPageView.
///
internal void OnPageConnected()
{
OnPageDisconnected();
if (_owner is DocumentPageView)
{
_page = ((DocumentPageView)_owner).DocumentPageInternal;
}
else if (_owner is FlowDocumentView)
{
_page = ((FlowDocumentView)_owner).DocumentPage;
}
if (_page is IServiceProvider)
{
_pageTextView = ((IServiceProvider)_page).GetService(typeof(ITextView)) as ITextView;
}
if (_pageTextView != null)
{
_pageTextView.Updated += new EventHandler(HandlePageTextViewUpdated);
}
if (IsValid)
{
OnUpdated(EventArgs.Empty);
}
}
///
/// Handler for PageDisconnected raised by the DocumentPageView.
///
internal void OnPageDisconnected()
{
if (_pageTextView != null)
{
_pageTextView.Updated -= new EventHandler(HandlePageTextViewUpdated);
}
_pageTextView = null;
_page = null;
}
///
/// Handler for TransformChanged raised by the DocumentPageView.
///
internal void OnTransformChanged()
{
if (IsValid)
{
OnUpdated(EventArgs.Empty);
}
}
///
///
///
internal override bool Validate()
{
if (!_owner.IsMeasureValid || !_owner.IsArrangeValid)
{
_owner.UpdateLayout();
}
return _pageTextView.Validate();
}
///
///
///
internal override bool Validate(ITextPointer position)
{
FlowDocumentView owner = _owner as FlowDocumentView;
bool isValid;
if (owner == null || owner.Document == null)
{
isValid = base.Validate(position);
}
else
{
if (Validate())
{
BackgroundFormatInfo backgroundFormatInfo = owner.Document.StructuralCache.BackgroundFormatInfo;
FlowDocumentFormatter formatter = owner.Document.BottomlessFormatter;
int lastCPInterrupted = -1;
while (this.IsValid && !Contains(position))
{
backgroundFormatInfo.BackgroundFormat(formatter, true /* ignoreThrottle */);
_owner.UpdateLayout(); // May invalidate the view.
// Break if background layout is not progressing.
// There are some edge cases where Validate() == true, but background
// layout will not progress (such as collapsed text in a tree view).
if (backgroundFormatInfo.CPInterrupted <= lastCPInterrupted)
{
// CPInterrupted is reset to -1 when background layout finishes, so
// check explicitly below to see if the position is valid or not.
break;
}
lastCPInterrupted = backgroundFormatInfo.CPInterrupted;
}
}
isValid = this.IsValid && Contains(position);
}
return isValid;
}
///
///
///
internal override void ThrottleBackgroundTasksForUserInput()
{
FlowDocumentView owner = _owner as FlowDocumentView;
if (owner != null && owner.Document != null)
{
owner.Document.StructuralCache.ThrottleBackgroundFormatting();
}
}
#endregion Internal Methods
//--------------------------------------------------------------------
//
// Internal Properties
//
//--------------------------------------------------------------------
#region Internal Properties
///
///
///
internal override UIElement RenderScope
{
get { return _owner; }
}
///
///
///
internal override ITextContainer TextContainer
{
get { return _textContainer; }
}
///
///
///
internal override bool IsValid
{
get
{
if (!_owner.IsMeasureValid || !_owner.IsArrangeValid || _page == null)
{
return false;
}
if (IsPageMissing)
{
return true;
}
return (_pageTextView != null && _pageTextView.IsValid);
}
}
///
///
///
internal override bool RendersOwnSelection
{
get
{
if (_pageTextView != null)
{
return _pageTextView.RendersOwnSelection;
}
return false;
}
}
///
///
///
internal override ReadOnlyCollection TextSegments
{
get
{
if (!IsValid || IsPageMissing)
{
return new ReadOnlyCollection(new List());
}
return _pageTextView.TextSegments;
}
}
///
/// DocumentPageView associated with this TextView.
///
internal DocumentPageView DocumentPageView
{
get { return _owner as DocumentPageView; }
}
#endregion Internal Properties
//-------------------------------------------------------------------
//
// Private Methods
//
//--------------------------------------------------------------------
#region Private Methods
///
/// Handler for Updated event raised by the inner TextView.
///
private void HandlePageTextViewUpdated(object sender, EventArgs e)
{
Invariant.Assert(_pageTextView != null);
if (sender == _pageTextView)
{
OnUpdated(EventArgs.Empty);
}
}
///
/// Gets transform to ancestor
///
private Transform GetTransformToAncestor()
{
Invariant.Assert(IsValid && !IsPageMissing);
// NOTE: TransformToAncestor is safe (will never throw an exception).
Transform transform = _page.Visual.TransformToAncestor(_owner) as Transform;
if (transform == null)
{
transform = Transform.Identity;
}
return transform;
}
///
/// Transforms point from inner scope.
///
private Point TransformToAncestor(Point point)
{
Invariant.Assert(IsValid && !IsPageMissing);
// NOTE: TransformToAncestor is safe (will never throw an exception).
GeneralTransform transform = _page.Visual.TransformToAncestor(_owner);
if (transform != null)
{
point = transform.Transform(point);
}
return point;
}
///
/// Transforms rectangle from inner scope
///
private Point TransformToDescendant(Point point)
{
Invariant.Assert(IsValid && !IsPageMissing);
// NOTE: TransformToAncestor is safe (will never throw an exception).
GeneralTransform transform = _page.Visual.TransformToAncestor(_owner);
if (transform != null)
{
transform = transform.Inverse;
if (transform != null)
{
point = transform.Transform(point);
}
}
return point;
}
///
/// Gets updated offset at next page
///
///
/// Current value of offset
///
/// Number of pages to move
///
///
/// Number of pages actually moved
///
private double GetYOffsetAtNextPage(double offset, int count, out int pagesMoved)
{
double newOffset = offset;
pagesMoved = 0;
if (_owner is IScrollInfo && ((IScrollInfo)_owner).ScrollOwner != null)
{
IScrollInfo scrollInfo = (IScrollInfo)_owner;
double viewportHeight = scrollInfo.ViewportHeight;
double extentHeight = scrollInfo.ExtentHeight;
if (count > 0)
{
while (pagesMoved < count)
{
if (DoubleUtil.LessThanOrClose(offset + viewportHeight, extentHeight))
{
newOffset += viewportHeight;
pagesMoved++;
}
else
{
break;
}
}
}
else
{
while (Math.Abs(pagesMoved) < Math.Abs(count))
{
if (DoubleUtil.GreaterThanOrClose(offset - viewportHeight, 0))
{
newOffset -= viewportHeight;
pagesMoved--;
}
else
{
break;
}
}
}
}
return newOffset;
}
#endregion Private Methods
//-------------------------------------------------------------------
//
// Private Properties
//
//-------------------------------------------------------------------
#region Private Properties
///
/// Whether page is missing.
///
private bool IsPageMissing
{
get { return (_page == DocumentPage.Missing); }
}
#endregion Private Properties
//-------------------------------------------------------------------
//
// Private Fields
//
//--------------------------------------------------------------------
#region Private Fields
///
/// Root of layout structure visualizing content.
///
private readonly UIElement _owner;
///
/// TextContainer representing content.
///
private readonly ITextContainer _textContainer;
///
/// DocumentPage associated with this view.
///
private DocumentPage _page;
///
/// TextView associated with DocumentPage.
///
private ITextView _pageTextView;
#endregion Private Fields
}
}
// 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.
//
// File: DocumentPageTextView.cs
//
// Description: TextView implementation for DocumentPageView.
//
//---------------------------------------------------------------------------
using System; // InvalidOperationException, ...
using System.Collections.Generic; // List
using System.Collections.ObjectModel; // ReadOnlyCollection
using System.Windows; // Point, Rect, ...
using System.Windows.Controls.Primitives; // DocumentPageView
using System.Windows.Documents; // ITextView, ITextContainer
using System.Windows.Media; // VisualTreeHelper
using MS.Internal.PtsHost; // BackgroundFormatInfo
namespace MS.Internal.Documents
{
///
/// TextView implementation for DocumentPageView.
///
internal class DocumentPageTextView : TextViewBase
{
//-------------------------------------------------------------------
//
// Constructors
//
//-------------------------------------------------------------------
#region Constructors
///
/// Constructor.
///
///
/// Root of layout structure visualizing content of a page.
///
///
/// TextContainer representing content.
///
internal DocumentPageTextView(DocumentPageView owner, ITextContainer textContainer)
{
Invariant.Assert(owner != null && textContainer != null);
_owner = owner;
_page = owner.DocumentPageInternal;
_textContainer = textContainer;
// Retrive inner TextView
if (_page is IServiceProvider)
{
_pageTextView = ((IServiceProvider)_page).GetService(typeof(ITextView)) as ITextView;
}
if (_pageTextView != null)
{
_pageTextView.Updated += new EventHandler(HandlePageTextViewUpdated);
}
}
///
/// Constructor.
///
///
/// Root of layout structure visualizing content of a page.
///
///
/// TextContainer representing content.
///
internal DocumentPageTextView(FlowDocumentView owner, ITextContainer textContainer)
{
Invariant.Assert(owner != null && textContainer != null);
_owner = owner;
_page = owner.DocumentPage;
_textContainer = textContainer;
// Retrive inner TextView
if (_page is IServiceProvider)
{
_pageTextView = ((IServiceProvider)_page).GetService(typeof(ITextView)) as ITextView;
}
if (_pageTextView != null)
{
_pageTextView.Updated += new EventHandler(HandlePageTextViewUpdated);
}
}
#endregion Constructors
//--------------------------------------------------------------------
//
// Internal Methods
//
//-------------------------------------------------------------------
#region Internal Methods
///
///
///
internal override ITextPointer GetTextPositionFromPoint(Point point, bool snapToText)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return null;
}
// Transform to page coordinates.
point = TransformToDescendant(point);
return _pageTextView.GetTextPositionFromPoint(point, snapToText);
}
///
///
///
internal override Rect GetRawRectangleFromTextPosition(ITextPointer position, out Transform transform)
{
Rect rect;
Transform pageTextViewTransform, ancestorTransform;
// Initialize transform to identity
transform = Transform.Identity;
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return Rect.Empty;
}
rect = _pageTextView.GetRawRectangleFromTextPosition(position, out pageTextViewTransform);
Invariant.Assert(pageTextViewTransform != null);
ancestorTransform = GetTransformToAncestor();
transform = GetAggregateTransform(pageTextViewTransform, ancestorTransform);
return rect;
}
///
///
///
internal override Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition)
{
// verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
Geometry geometry = null;
if (!IsPageMissing)
{
geometry = _pageTextView.GetTightBoundingGeometryFromTextPositions(startPosition, endPosition);
if (geometry != null)
{
Transform transform = GetTransformToAncestor().AffineTransform;
CaretElement.AddTransformToGeometry(geometry, transform);
}
}
return (geometry);
}
///
///
///
internal override ITextPointer GetPositionAtNextLine(ITextPointer position, double suggestedX, int count, out double newSuggestedX, out int linesMoved)
{
ITextPointer positionOut;
Point offset;
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
newSuggestedX = suggestedX;
linesMoved = 0;
return position;
}
offset = TransformToDescendant(new Point(suggestedX, 0));
suggestedX = offset.X;
positionOut = _pageTextView.GetPositionAtNextLine(position, suggestedX, count, out newSuggestedX, out linesMoved);
offset = TransformToAncestor(new Point(newSuggestedX, 0));
newSuggestedX = offset.X;
return positionOut;
}
///
///
///
internal override ITextPointer GetPositionAtNextPage(ITextPointer position, Point suggestedOffset, int count, out Point newSuggestedOffset, out int pagesMoved)
{
ITextPointer positionOut = position;
newSuggestedOffset = suggestedOffset;
Point offset = suggestedOffset;
pagesMoved = 0;
if (count == 0)
{
return positionOut;
}
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return position;
}
// Calculate distance from current position
offset.Y = GetYOffsetAtNextPage(offset.Y, count, out pagesMoved);
if (pagesMoved != 0)
{
// Transfrom offset to _pageTextView's coordinate position, obtain position from _pageTextView and convert back
offset = TransformToDescendant(offset);
positionOut = _pageTextView.GetTextPositionFromPoint(offset, true);
Invariant.Assert(positionOut != null);
Rect rect = _pageTextView.GetRectangleFromTextPosition(position);
newSuggestedOffset = TransformToAncestor(new Point(rect.X, rect.Y));
}
return positionOut;
}
///
///
///
internal override bool IsAtCaretUnitBoundary(ITextPointer position)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return false;
}
return _pageTextView.IsAtCaretUnitBoundary(position);
}
///
///
///
internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return null;
}
return _pageTextView.GetNextCaretUnitPosition(position, direction);
}
///
///
///
internal override ITextPointer GetBackspaceCaretUnitPosition(ITextPointer position)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return null;
}
return _pageTextView.GetBackspaceCaretUnitPosition(position);
}
///
///
///
internal override TextSegment GetLineRange(ITextPointer position)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return TextSegment.Null;
}
return _pageTextView.GetLineRange(position);
}
///
///
///
internal override ReadOnlyCollection GetGlyphRuns(ITextPointer start, ITextPointer end)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return new ReadOnlyCollection(new List());
}
return _pageTextView.GetGlyphRuns(start, end);
}
///
///
///
internal override bool Contains(ITextPointer position)
{
// Verify that layout information is valid. Cannot continue if not valid.
if (!IsValid)
{
throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
}
if (IsPageMissing)
{
return false;
}
return _pageTextView.Contains(position);
}
///
/// Handler for PageConnected raised by the DocumentPageView.
///
internal void OnPageConnected()
{
OnPageDisconnected();
if (_owner is DocumentPageView)
{
_page = ((DocumentPageView)_owner).DocumentPageInternal;
}
else if (_owner is FlowDocumentView)
{
_page = ((FlowDocumentView)_owner).DocumentPage;
}
if (_page is IServiceProvider)
{
_pageTextView = ((IServiceProvider)_page).GetService(typeof(ITextView)) as ITextView;
}
if (_pageTextView != null)
{
_pageTextView.Updated += new EventHandler(HandlePageTextViewUpdated);
}
if (IsValid)
{
OnUpdated(EventArgs.Empty);
}
}
///
/// Handler for PageDisconnected raised by the DocumentPageView.
///
internal void OnPageDisconnected()
{
if (_pageTextView != null)
{
_pageTextView.Updated -= new EventHandler(HandlePageTextViewUpdated);
}
_pageTextView = null;
_page = null;
}
///
/// Handler for TransformChanged raised by the DocumentPageView.
///
internal void OnTransformChanged()
{
if (IsValid)
{
OnUpdated(EventArgs.Empty);
}
}
///
///
///
internal override bool Validate()
{
if (!_owner.IsMeasureValid || !_owner.IsArrangeValid)
{
_owner.UpdateLayout();
}
return _pageTextView.Validate();
}
///
///
///
internal override bool Validate(ITextPointer position)
{
FlowDocumentView owner = _owner as FlowDocumentView;
bool isValid;
if (owner == null || owner.Document == null)
{
isValid = base.Validate(position);
}
else
{
if (Validate())
{
BackgroundFormatInfo backgroundFormatInfo = owner.Document.StructuralCache.BackgroundFormatInfo;
FlowDocumentFormatter formatter = owner.Document.BottomlessFormatter;
int lastCPInterrupted = -1;
while (this.IsValid && !Contains(position))
{
backgroundFormatInfo.BackgroundFormat(formatter, true /* ignoreThrottle */);
_owner.UpdateLayout(); // May invalidate the view.
// Break if background layout is not progressing.
// There are some edge cases where Validate() == true, but background
// layout will not progress (such as collapsed text in a tree view).
if (backgroundFormatInfo.CPInterrupted <= lastCPInterrupted)
{
// CPInterrupted is reset to -1 when background layout finishes, so
// check explicitly below to see if the position is valid or not.
break;
}
lastCPInterrupted = backgroundFormatInfo.CPInterrupted;
}
}
isValid = this.IsValid && Contains(position);
}
return isValid;
}
///
///
///
internal override void ThrottleBackgroundTasksForUserInput()
{
FlowDocumentView owner = _owner as FlowDocumentView;
if (owner != null && owner.Document != null)
{
owner.Document.StructuralCache.ThrottleBackgroundFormatting();
}
}
#endregion Internal Methods
//--------------------------------------------------------------------
//
// Internal Properties
//
//--------------------------------------------------------------------
#region Internal Properties
///
///
///
internal override UIElement RenderScope
{
get { return _owner; }
}
///
///
///
internal override ITextContainer TextContainer
{
get { return _textContainer; }
}
///
///
///
internal override bool IsValid
{
get
{
if (!_owner.IsMeasureValid || !_owner.IsArrangeValid || _page == null)
{
return false;
}
if (IsPageMissing)
{
return true;
}
return (_pageTextView != null && _pageTextView.IsValid);
}
}
///
///
///
internal override bool RendersOwnSelection
{
get
{
if (_pageTextView != null)
{
return _pageTextView.RendersOwnSelection;
}
return false;
}
}
///
///
///
internal override ReadOnlyCollection TextSegments
{
get
{
if (!IsValid || IsPageMissing)
{
return new ReadOnlyCollection(new List());
}
return _pageTextView.TextSegments;
}
}
///
/// DocumentPageView associated with this TextView.
///
internal DocumentPageView DocumentPageView
{
get { return _owner as DocumentPageView; }
}
#endregion Internal Properties
//-------------------------------------------------------------------
//
// Private Methods
//
//--------------------------------------------------------------------
#region Private Methods
///
/// Handler for Updated event raised by the inner TextView.
///
private void HandlePageTextViewUpdated(object sender, EventArgs e)
{
Invariant.Assert(_pageTextView != null);
if (sender == _pageTextView)
{
OnUpdated(EventArgs.Empty);
}
}
///
/// Gets transform to ancestor
///
private Transform GetTransformToAncestor()
{
Invariant.Assert(IsValid && !IsPageMissing);
// NOTE: TransformToAncestor is safe (will never throw an exception).
Transform transform = _page.Visual.TransformToAncestor(_owner) as Transform;
if (transform == null)
{
transform = Transform.Identity;
}
return transform;
}
///
/// Transforms point from inner scope.
///
private Point TransformToAncestor(Point point)
{
Invariant.Assert(IsValid && !IsPageMissing);
// NOTE: TransformToAncestor is safe (will never throw an exception).
GeneralTransform transform = _page.Visual.TransformToAncestor(_owner);
if (transform != null)
{
point = transform.Transform(point);
}
return point;
}
///
/// Transforms rectangle from inner scope
///
private Point TransformToDescendant(Point point)
{
Invariant.Assert(IsValid && !IsPageMissing);
// NOTE: TransformToAncestor is safe (will never throw an exception).
GeneralTransform transform = _page.Visual.TransformToAncestor(_owner);
if (transform != null)
{
transform = transform.Inverse;
if (transform != null)
{
point = transform.Transform(point);
}
}
return point;
}
///
/// Gets updated offset at next page
///
///
/// Current value of offset
///
/// Number of pages to move
///
///
/// Number of pages actually moved
///
private double GetYOffsetAtNextPage(double offset, int count, out int pagesMoved)
{
double newOffset = offset;
pagesMoved = 0;
if (_owner is IScrollInfo && ((IScrollInfo)_owner).ScrollOwner != null)
{
IScrollInfo scrollInfo = (IScrollInfo)_owner;
double viewportHeight = scrollInfo.ViewportHeight;
double extentHeight = scrollInfo.ExtentHeight;
if (count > 0)
{
while (pagesMoved < count)
{
if (DoubleUtil.LessThanOrClose(offset + viewportHeight, extentHeight))
{
newOffset += viewportHeight;
pagesMoved++;
}
else
{
break;
}
}
}
else
{
while (Math.Abs(pagesMoved) < Math.Abs(count))
{
if (DoubleUtil.GreaterThanOrClose(offset - viewportHeight, 0))
{
newOffset -= viewportHeight;
pagesMoved--;
}
else
{
break;
}
}
}
}
return newOffset;
}
#endregion Private Methods
//-------------------------------------------------------------------
//
// Private Properties
//
//-------------------------------------------------------------------
#region Private Properties
///
/// Whether page is missing.
///
private bool IsPageMissing
{
get { return (_page == DocumentPage.Missing); }
}
#endregion Private Properties
//-------------------------------------------------------------------
//
// Private Fields
//
//--------------------------------------------------------------------
#region Private Fields
///
/// Root of layout structure visualizing content.
///
private readonly UIElement _owner;
///
/// TextContainer representing content.
///
private readonly ITextContainer _textContainer;
///
/// DocumentPage associated with this view.
///
private DocumentPage _page;
///
/// TextView associated with DocumentPage.
///
private ITextView _pageTextView;
#endregion Private Fields
}
}
// 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
- GridViewUpdatedEventArgs.cs
- HiddenFieldPageStatePersister.cs
- Environment.cs
- MULTI_QI.cs
- WmfPlaceableFileHeader.cs
- XsltOutput.cs
- XmlImplementation.cs
- DbConvert.cs
- RSAPKCS1SignatureDeformatter.cs
- LocatorPart.cs
- TypedDataSetSchemaImporterExtensionFx35.cs
- SqlInfoMessageEvent.cs
- TraceShell.cs
- ClientScriptManagerWrapper.cs
- XmlSerializerSection.cs
- XmlConvert.cs
- ImmComposition.cs
- OutputScopeManager.cs
- SuppressMessageAttribute.cs
- NavigationPropertyEmitter.cs
- ConstructorArgumentAttribute.cs
- Group.cs
- HtmlEmptyTagControlBuilder.cs
- ComponentResourceKeyConverter.cs
- COMException.cs
- dbdatarecord.cs
- SocketInformation.cs
- Timer.cs
- ScriptManager.cs
- Attributes.cs
- CapabilitiesRule.cs
- CharKeyFrameCollection.cs
- PageAsyncTask.cs
- XPathScanner.cs
- DependencyObject.cs
- StringUtil.cs
- SecurityChannelFactory.cs
- MouseOverProperty.cs
- ApplicationServiceManager.cs
- MsmqIntegrationSecurityMode.cs
- TemplatedAdorner.cs
- BufferedGraphicsManager.cs
- ServiceOperationParameter.cs
- FrameworkEventSource.cs
- SecurityTokenSerializer.cs
- SqlInternalConnectionSmi.cs
- Propagator.ExtentPlaceholderCreator.cs
- ComplexLine.cs
- MoveSizeWinEventHandler.cs
- Duration.cs
- TagPrefixCollection.cs
- AdornedElementPlaceholder.cs
- CompositeFontParser.cs
- TaskDesigner.cs
- XPathArrayIterator.cs
- ComponentDispatcher.cs
- FileVersionInfo.cs
- OrCondition.cs
- RecipientInfo.cs
- StylusEditingBehavior.cs
- DrawingContextWalker.cs
- DataGridViewTextBoxColumn.cs
- WebResourceUtil.cs
- DependencyPropertyHelper.cs
- AttributeUsageAttribute.cs
- TextInfo.cs
- ClientSettingsStore.cs
- IdentifierCreationService.cs
- ErrorWebPart.cs
- CodeDirectionExpression.cs
- _DomainName.cs
- ToolStripPanel.cs
- ViewLoader.cs
- TiffBitmapDecoder.cs
- MdiWindowListItemConverter.cs
- NavigationFailedEventArgs.cs
- SystemResourceKey.cs
- NullEntityWrapper.cs
- ContainerParaClient.cs
- BitStack.cs
- wmiprovider.cs
- EventHandlerService.cs
- ClientBuildManager.cs
- HttpApplicationFactory.cs
- TdsParser.cs
- FeatureSupport.cs
- GetLedgerEntryForRecipientRequest.cs
- PolicyManager.cs
- EdmEntityTypeAttribute.cs
- ProviderUtil.cs
- SerializationHelper.cs
- WebControlsSection.cs
- ActivationArguments.cs
- FixUp.cs
- ColumnPropertiesGroup.cs
- UriParserTemplates.cs
- WindowCollection.cs
- RegexBoyerMoore.cs
- ColumnClickEvent.cs
- ISCIIEncoding.cs