0
votes

I'm tried highlighting text in richtextbox. I used button click event. this my code.

Result..... This is a bubble sort.

enter image description here

position and targetposition is right.

However, the highlighted character is different from the position.

Later, the text is not painted.

enter image description here

// print one line
this.rtb1.AppendText(this.IntToString(traceInfo.SortingNumbers));
this.rtb1.AppendText("\r\n");

ChangeTextColor(traceInfo.Position, traceInfo.TargetPosition);
private void ChangeTextColor(int position, int targetPosition)
    {
        int length;
        int pos = GetTextPositionAndLength(position, count, out length);

        TextRange textRange = new TextRange(rtb1.Document.ContentStart, rtb1.Document.ContentEnd);
        TextPointer startPointer = textRange.Start.GetPositionAtOffset(pos);
        TextPointer endPointer = textRange.Start.GetPositionAtOffset(pos + length);
        TextRange tr2 = new TextRange(startPointer, endPointer);
        tr2.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Red));

        int pos2 = GetTextPositionAndLength(targetPosition, count, out length);
        TextRange textRange2 = new TextRange(rtb1.Document.ContentStart, rtb1.Document.ContentEnd);
        TextPointer startPointer2 = textRange2.Start.GetPositionAtOffset(pos2);
        TextPointer endPointer2 = textRange2.Start.GetPositionAtOffset(pos2 + length);
        TextRange tr4 = new TextRange(startPointer2, endPointer2);
        tr4.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.LightBlue)); 
   } 
    private int GetTextPositionAndLength(int position, int lineIndex, out int length)
    {
        //  First charcter position index of lineIndex 
        int richtTextLineIndex = GetFirstCharIndexFromLine(lineIndex);

        if (position == 0)
        {
            length = GetTextLength(0, lineIndex);
            return richtTextLineIndex;
        }
        int index = 0;
        int posIter = 0;
        string line = Line(lineIndex);

        length = 0;
        for (index = 0; index < line.Length; index++)
        {
            if (line[index] == ' ')
            {
                posIter++;
                if (posIter == position)
                {
                    index++;
                    length = GetTextLength(index, lineIndex);
                    break;
                }
            }
        }
        return index + richtTextLineIndex;
    }

}

I can't solve this problem. Help me ..please

1
You posted your question 5 times with different code. But in each case code you provided was not enough to help you. Can you share your project or at least full window code to reproduce you scenario? - VMaleev

1 Answers

2
votes

Replace your ChangeTextColor with this one:

    private void ChangeTextColor(int position, int targetPosition)
    {
        int length;
        var line = rtb1.Document.Blocks.ElementAt(count);
        TextRange lineRange = new TextRange(line.ContentStart, line.ContentEnd);


        int positionLeft = GetTextPositionAndLength(position, lineRange.Text, out length);

        TextPointer startPointerLeft = lineRange.Start.GetPositionAtOffset(positionLeft);
        TextPointer endPointerLeft = lineRange.Start.GetPositionAtOffset(positionLeft + length);
        TextRange selectRangeLeft = new TextRange(startPointerLeft, endPointerLeft);
        selectRangeLeft.ApplyPropertyValue(TextElement.ForegroundProperty,
            new SolidColorBrush(Colors.Red));

        int positionRight = GetTextPositionAndLength(targetPosition, lineRange.Text, out length);

        TextPointer startPointerRight = GetTextPointAt(lineRange.Start, positionRight - 1);
        TextPointer endPointerRight = GetTextPointAt(lineRange.Start, positionRight + length - 1);
        TextRange selectRangeRight = new TextRange(startPointerRight, endPointerRight);
        selectRangeRight.ApplyPropertyValue(TextElement.ForegroundProperty,
            new SolidColorBrush(Colors.LightBlue));

        Debug.WriteLine("Left text: " + selectRangeLeft.Text + "; Right text: " + selectRangeRight.Text);

        count++;
    }

And add new methods:

    private static TextPointer GetTextPointAt(TextPointer from, int pos)
    {
        TextPointer ret = from;
        int i = 0;

        while ((i < pos) && (ret != null))
        {
            if ((ret.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text) || (ret.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.None))
                i++;

            if (ret.GetPositionAtOffset(1, LogicalDirection.Forward) == null)
                return ret;

            ret = ret.GetPositionAtOffset(1, LogicalDirection.Forward);
        }

        return ret;
    }

    private int GetTextPositionAndLength(int position, string line, out int length)
    {
        if (position == 0)
        {
            length = GetTextLength(0, line);
            return 0;
        }

        int index = 0;
        int posIter = 0;

        length = 0;
        for (index = 0; index < line.Length; index++)
        {
            if (line[index] == ' ')
            {
                posIter++;
                if (posIter == position)
                {
                    index++;
                    length = GetTextLength(index, line);
                    break;
                }
            }
        }
        return index;
    }

    private int GetTextLength(int index, string line)
    {
        int length = 0;
        for (int i = index; i < line.Length; i++)
        {
            if (line[i] == ' ')
            {
                break;
            }
            length++;
        }
        return length;
    }

It works for me. Hope, it helps