/// <summary> /// <see cref="ITextView.BringPointIntoViewAsync"/> /// </summary> internal override void BringPointIntoViewAsync(Point point, object userState) { DocumentPageTextView pageTextView; ITextPointer position; BringPointIntoViewRequest pendingRequest; bool bringIntoViewPending; // Verify that layout information is valid. Cannot continue if not valid. if (!IsValid) { throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout)); } if (_pendingRequest != null) { // Ignore new request if the previous is not completed yet. OnBringPointIntoViewCompleted(new BringPointIntoViewCompletedEventArgs( point, null, false, null, false, userState)); } else { pendingRequest = new BringPointIntoViewRequest(point, userState); _pendingRequest = pendingRequest; pageTextView = GetTextViewFromPoint(point, false); // If the point is currently in the view, use existing TextView to retrieve the position. // Otherwise, let the viewer handle the request. if (pageTextView != null) { // Transform to DocumentPageView coordinates and query inner TextView point = TransformToDescendant(pageTextView.RenderScope, point); position = pageTextView.GetTextPositionFromPoint(point, true); pendingRequest.Position = position; OnBringPointIntoViewCompleted(pendingRequest); } else { // Request to bring point into view in the Viewer. // This code is specific to known viewers. Since text selection is not // exposed in a public way, it should not cause any "extensibility" problems. GeneralTransform transform = _renderScope.TransformToAncestor(_viewer); // transform.TryTransform(point, out point); bringIntoViewPending = false; if (_viewer is FlowDocumentPageViewer) { // Special handling for FlowDocumentPageViewer bringIntoViewPending = ((FlowDocumentPageViewer)_viewer).BringPointIntoView(point); } else if (_viewer is DocumentViewer) { // Special handling for DocumentViewer bringIntoViewPending = ((DocumentViewer)_viewer).BringPointIntoView(point); } else { if (DoubleUtil.LessThan(point.X, 0)) { if (_viewer.CanGoToPreviousPage) { _viewer.PreviousPage(); bringIntoViewPending = true; } } else if (DoubleUtil.GreaterThan(point.X, _viewer.RenderSize.Width)) { if (_viewer.CanGoToNextPage) { _viewer.NextPage(); bringIntoViewPending = true; } } else if (DoubleUtil.LessThan(point.Y, 0)) { if (_viewer.CanGoToPreviousPage) { _viewer.PreviousPage(); bringIntoViewPending = true; } } else if (DoubleUtil.GreaterThan(point.Y, _viewer.RenderSize.Height)) { if (_viewer.CanGoToNextPage) { _viewer.NextPage(); bringIntoViewPending = true; } } } if (!bringIntoViewPending) { OnBringPointIntoViewCompleted(pendingRequest); } } } }
/// <summary> /// Fires BringPointIntoViewCompleted event. /// </summary> private void OnBringPointIntoViewCompleted(BringPointIntoViewRequest request) { _pendingRequest = null; OnBringPointIntoViewCompleted(new BringPointIntoViewCompletedEventArgs( request.Point, request.Position, request.Position != null, null, false, request.UserState)); }