1

Silverlight 5 リッチテキスト ボックスを使用してユーザー コントロールを作成しようとしています。「インラインUI」を挿入できるようにする必要があり、現在のカーソル位置を取得する方法がわかりません。

次のようにコードをトリガーします。

this.GetAbsolutePos(this.richText.Selection.Start);

このメソッドの根性は次のとおりです。

private int GetAbsolutePos(TextPointer textPointer)
{
   int index = 0;
   TextPointer pos = this.richText.ContentStart;
   while (pos.CompareTo(textPointer) != 0)
   {
      if (pos.IsAtInsertionPosition)
      {
          index++;
      }

      pos = pos.GetNextInsertionPosition(LogicalDirection.Forward);
   }
   return index;
}

次のテキストが richtextbox コントロールにある場合....

空のコントロール

カーソルが最初の行の 5 と 6 の間にある場合、上記の関数は正しく 5 を返します。つまり、2 行目の 5 と 6 の間は 16 を返し、3 行目は 27 を返します。

これらの位置にインライン要素を挿入すると、「シンボル」としてカウントされ、さらにカウントがうまくいかなくなるため、さらに難しくなります。

この画像は、各行の 5 と 6 の間にインライン UI を「挿入」したときに何が起こっているかを示しています。 3 インラインで

完全を期すために、ここでは richtext.Xaml の Xaml を示します (わかりやすくするために、Section/Paragraph 要素からすべての余分な属性を削除しました)。

<Section>
   <Paragraph>
       <Run>1234567890</Run>
       <LineBreak />
       <Run>1234567890</Run>
       <LineBreak />
       <Run>1234567890</Run>
   </Paragraph>
</Section> 

このページのコメントに基づくMSDN Silverlight TextPointer Class

シンボル - TextPointer 操作の場合、次のいずれかがシンボルと見なされます。

  • TextElement 要素の開始タグまたは終了タグ。

  • InlineUIContainer 内に含まれる UIElement 要素。UIElement は常に 1 つのシンボルとしてカウントされることに注意してください。UIElement に含まれる追加のコンテンツまたは要素は、シンボルとは見なされません。

  • テキスト Run 要素内の各 16 ビット Unicode 文字。

現在どのような「シンボル」を使用しているかを「知る」必要があると思いますが、その方法がわかりません。

簡単なように思えますが、TextPointers の操作は非常に直感的ではないようです。カーソル位置を見つけるために Xaml を解析するというアイデアがありましたが、それは本当のハックのようです。

どんな助けでも大歓迎です。

ありがとう

4

2 に答える 2

0

最後に、テキスト ポイントの前にある SubstituteEdits (UIElement の表現) の数だけ手動でインデックスを調整するだけです。まだ不安定で、コントロールには他の問題がありますが、今のところは十分です。

乾杯

ティム

    private int GetAbsolutePos(SubstituteEdit newSub)
    {
        int index = 0;
        TextPointer textPointer = this.richText.Selection.Start;
        TextPointer caretWhere = this.richText.ContentStart;

        while (true)
        {
            caretWhere = caretWhere.GetNextInsertionPosition(LogicalDirection.Forward);
            if (caretWhere == null || caretWhere.CompareTo(textPointer) == 0)
            {
                break;
            }

            index++;
        }

        foreach (SubstituteEdit sub in this.Substitutes)
        {
            if (sub.Position < index && sub != newSub)
            {
                index--;
            }
        }

        return index;
    }
于 2013-04-05T08:42:10.623 に答える