2010年10月03日

ScrollIntoView(TextElement)

FlowDocumentScrollViewer には、直接スクロールを扱う機構が存在してないみたいです。テンプレート(またはビジュアルツリー)を漁れば ScrollViewer が手に入り、こちらを使えばスクロールを扱えます。

しかし、当然ながら ScrollViewer 自体は物理インクリメントによるスクロールのみのサポートであり、「このテキスト要素を表示したいんだけど」というのは直接的にはできません。

幸い、テキスト要素 TextElement が提供する TextPointer には、自分を表示しているビューア全体のどの範囲に表示されるかを表す GetCharacterRect メソッドが用意されています。

ということで、TextElement を引数に取る ScrollIntoView を実装してみましょう。FlowDocumentScrollViewer の派生クラスのメソッドとしておきますが、(拡張メソッドを含めた)静的メソッドとしても構いません。テンプレートが差し替えられていることまで考慮する場合、内部の ScrollViewer を取得するには VisualTreeHelper で子要素を辿っていくようにする必要があるでしょう。

public bool ScrollIntoView(TextElement element) {
  if (element == null)
    throw new ArgumentNullException("element");
  if (this.Document == null)
    return false;
  if (!this.Document.ContentStart.IsInSameDocument(element.ContentStart)
    return false;
  var contentHost = (ScrollViewer)this.Template.FindName("PART_ContentHost", this);
  if (contentHost == null)
    return false;
  var rect = element.ContentStart.GetCharacterRect(LogicalDirection.Backward);
  contentHost.ScrollToVerticalOffset(contentHost.VerticalOffset + rect.Top);
  // HorizontalOffset の方は取り敢えず略
  return true;
}
posted by Hongliang at 18:39| Comment(0) | TrackBack(0) | WPF | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック

ここ(hongliang.seesaa.net)で公開しているものについて、利用は自由に行って頂いて構いません。改変、再頒布もお好きになさって下さい。利用に対しこちらが何かを要求することはありません。

ただし、公開するものを使用、または参考したことによって何らかの損害等が生じた場合でも、私はいかなる責任も負いません。

あ、こんなのに使ったってコメントを頂ければ嬉しいです。

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。