11

選択する特定のテキストのインデックスと長さ(またはEndIndex)のみが指定されている場合、RichTextBoxのWPFバージョンでこれをどのように実行しますか?

これは、Textbox.Select(startIndex、Length)を呼び出すことができるため、Textboxで非常に実行可能ですが、RTBで同等のものは表示されません。

編集:私は選択をするための答えを見つけました

internal string Select(RichTextBox rtb, int index, int length)
        {
            TextRange textRange = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);

            if (textRange.Text.Length >= (index + length))
            {
                TextPointer start = textRange.Start.GetPositionAtOffset(index, LogicalDirection.Forward);
                TextPointer end = textRange.Start.GetPositionAtOffset(index + length, LogicalDirection.Backward);
                rtb.Selection.Select(start, end);
            }
            return rtb.Selection.Text;
        } 

ただし、選択後に行を強調表示しようとすると、次のようになります。

rtb.Selection.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.LightBlue));

強調表示機能は、最初の試行でのみ機能し、2回目の試行後に中断します。誰もがこれの理由を知っていますか?

4

3 に答える 3

6

わかりました、この質問は古いですが、私はついに答えを見つけたので、これをここに置きます。

RichTextBoxを使用してSyntaxhighlighterを作成しようとしたときに、同様の問題が発生していました。私が見つけたのは、ApplyPropertyValueをいじくり回すと、 GetPositionAtOffsetを単純に使用できなくなるということです。propertyvaluesを適用すると、ドキュメント内のTextTokenの「内部位置」が変更され、この機能が「ブレーキ」されるように見えると思います。

回避策:

GetPositionAtOffsetを操作する必要があるときはいつでも、最初にドキュメントの完全なTextRangeでClearAllPropertiesを呼び出し、次にApplyPropertyValueを使用してすべてのプロパティを再適用しますが、今回は右から左に適用します。(右は最大オフセットを意味します)

PropertyValuesを適用したかどうかはわかりませんが、Selectionが強調表示されることを期待しているので、そこにもっと考える必要があるかもしれません。

これは、問題が発生したときの私のコードの外観です。

    private void _highlightTokens(FlowDocument document)
    {
        TextRange fullRange = new TextRange(document.ContentStart, document.ContentEnd);
        foreach (Token token in _tokenizer.GetTokens(fullRange.Text))
        {
            TextPointer start = fullRange.Start.GetPositionAtOffset(token.Position);
            TextPointer end = start.GetPositionAtOffset(token.Length);

            TextRange range = new TextRange(start, end);
            range.ApplyPropertyValue(TextElement.ForegroundProperty, _getTokenColor(token));
        }
    }

そして私はそれをこのように修正しました:

    private void _highlightTokens(FlowDocument document)
    {
        TextRange fullRange = new TextRange(document.ContentStart, document.ContentEnd);
        fullRange.ClearAllProperties(); // NOTICE: first remove allProperties.
        foreach (Token token in _tokenizer.GetTokens(fullRange.Text).Reverse()) // NOTICE: Reverse() to make the "right to left" work
        {
            TextPointer start = fullRange.Start.GetPositionAtOffset(token.Position);
            TextPointer end = start.GetPositionAtOffset(token.Length);

            TextRange range = new TextRange(start, end);
            range.ApplyPropertyValue(TextElement.ForegroundProperty, _getTokenColor(token));
        }
    }
于 2014-07-31T12:46:25.447 に答える
-1

RichTextBox.SelectionプロパティのSelect()メソッドを使用します。

于 2012-08-22T02:48:44.313 に答える
-1

スペース間のテキストを取得できるBlockquote....。

プライベート文字列RichWordOver(RichTextBox rch、int x、int y){

        int pos = rch.GetCharIndexFromPosition(new Point(x, y));
        if (pos <= 0) return "";


        string txt = rch.Text;

        int start_pos;
        for (start_pos = pos; start_pos >= 0; start_pos--)
        {

            char ch = txt[start_pos];
            if (!char.IsLetterOrDigit(ch) && !(ch=='_')) break;
        }
        start_pos++;
        int end_pos;
        for (end_pos = pos; end_pos < txt.Length; end_pos++)
        {
            char ch = txt[end_pos];
            if (!char.IsLetterOrDigit(ch) && !(ch == '_')) break;
        }
        end_pos--;


        if (start_pos > end_pos) return "";
        return txt.Substring(start_pos, end_pos - start_pos + 1);
    }

private void rchText_MouseClick(object sender、MouseEventArgs e){MessageBox.Show(RichWordOver(rchText、eX、eY)); }

于 2013-12-19T21:01:09.450 に答える