FormattedText上でヒットテストを実行するための良い方法は何ですか?

StackOverflow https://stackoverflow.com/questions/540002

  •  22-08-2019
  •  | 
  •  

質問

私はFormattedTextを使用してテキストをレンダリングするんだけど、レンダリングされた出力にあたり-charはヒットテストを実行するためにどのような方法があるように見えるん。これは読み取り専用ですので、私は基本的に唯一の選択を必要とする、無編集ます。

私はRichTextBoxまたは類似を使用すると思いますが、私は、制御コードに基づいて、出力テキストに必要なテキスト自体に埋め込むので、彼らは非常に複雑な権利インライン要素を構築します常に巣を、しません。また、私は、そのソリューションのパフォーマンスについて少し心配です。私は、行の数が多いと、新しい行が頻繁に追加されます。

私はGlyphRunを見てきました。

、<...私がヒットテストを受ける可能性があり、それから、または関連クラスを表示されますが、私は多くの機能を再実装するだろう、と簡単な方法があるはずのように思えます/ P>

誰もがこれを実装するための良い方法を知っていますか?

役に立ちましたか?

解決

最善の方法は、あなたのテキストおよびこれもヒットテストを考慮を格納するための良いデータ構造を設計することです。一例としては、(何が必要に応じて、単語、行または段落)のブロックにテキストを分割することができます。次いで、そのような各ブロックは、任意のフォーマット操作で再計算されなければならないバウンディングボックスを有するべきです。また、あなたのデザインのキャレット位置を検討します。

あなたはそれがヒットテストを行うことは非常に容易になり、このような機能を持っていたら、ちょうどバウンディングボックスを使用します。また、テキストの特定の部分を強調するようなその後の操作に役立ちます。

他のヒント

あなたはFormattedTextオブジェクトから各文字の形状を取得し、ヒットテストを行うために、各文字の境界を使用することができます。

var geometry = (GeometryGroup)((GeometryGroup)text.BuildGeometry(new Point(0, 0))).Children[0];
foreach (var c in geometry.Children)
{
  if (c.Bounds.Contains(point))
    return index;
  index++;
}

OnRenderであなたの代わりにフォーマットされたテキストのこれらのジオメトリオブジェクトをレンダリングすることができます。

完全に飲み会に同意する - 最も簡単な方法は、あなたが個々の項目を分割することであることを行っている離れFormattedTextの機能の全体の負荷を再実装しないと取得するつもりだあなたはヒットテストをするために、独自のコントロールにしたいです/インラインます。

これは、インライン(または)自分だとして、そして、インラインのIsMouseDirectlyOverプロパティにバインドする私たちのMouseEnterイベント&MouseLeaveイベントにデリゲートを追加のいずれかのTextBlockを使用し、各単語を追加することを検討します。

あなたは、実際のグリフのピクセルレベルのヒットテストを行いたい場合は、

は、その後、あなたがGlyphRunsを使用する必要がありますし、(グリフに手動ヒットテストを行う(すなわち、マウスは、まさにこの「I」のドットです)読み:ハードワークを)

私は非常に遅くパーティーによ - パーティーが終わっていない、とあなたが実際の文字ジオメトリを必要としない場合、私はこの便利なようなものを見つけます:

 for (int i = 0; i < FormattedText.Text.Length; i++)
 {
            characterHighlightGeometry = FormattedText.BuildHighlightGeometry(new Point(), i, 1);
            CharacterHighlightGeometries.Children.Add(characterHighlightGeometry);
 }

BuildGeometry()は文字の実際のパスの幾何学的形状を含みます。 BuildHighlightGeometry()全ての文字の外側の境界を生成する - を含みます スペース、そのスペースへのインデックスがで配置することができます:

 foreach (var c in CharacterHighlightGeometries.Children)
        {
            if (c.Bounds.Contains(centerpoint))
            {
                q = c;
                cpos = index;
                break;
            }
            index++;
        }

この情報がお役に立てば幸いです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top