Выберите диапазон текста в WPF RichTextBox (FlowDocument) программно

Я не уверен, правильно ли я понял вопрос.

В любом случае, вы ищете это:

std::string ip ="192.168.1.54";
std::stringstream s(ip);
int a,b,c,d; //to store the 4 ints
char ch; //to temporarily store the '.'
s >> a >> ch >> b >> ch >> c >> ch >> d;
std::cout << a << "  " << b << "  " << c << "  "<< d;

Выход:

192  168  1  54

17
задан Johan Danforth 28 September 2009 в 14:53
поделиться

6 ответов

Public Function GoToPoint(ByVal start As TextPointer, ByVal x As Integer) As TextPointer
    Dim out As TextPointer = start
    Dim i As Integer = 0
    Do While i < x
        If out.GetPointerContext(LogicalDirection.Backward) = TextPointerContext.Text Or _
             out.GetPointerContext(LogicalDirection.Backward) = TextPointerContext.None Then
            i += 1
        End If
        If out.GetPositionAtOffset(1, LogicalDirection.Forward) Is Nothing Then
            Return out
        Else
            out = out.GetPositionAtOffset(1, LogicalDirection.Forward)
        End If


    Loop
    Return out
End Function

Попробуйте это, это должно вернуть текстовый указатель для заданного смещения символа. (Извините, это в VB, но это то, над чем я работаю ...)

11
ответ дан 30 November 2019 в 12:27
поделиться

Я попытался использовать решение, опубликованное KratzVB, но обнаружил, что оно игнорирует переводы строки. Если вы хотите считать символы \ r и \ n, тогда этот код должен работать:

private static TextPointer GetPoint(TextPointer start, int x)
{

        var ret = start;
        var i = 0;
        while (ret != null)
        {
            string stringSoFar = new TextRange(ret, ret.GetPositionAtOffset(i, LogicalDirection.Forward)).Text;
            if (stringSoFar.Length == x)
                    break;
            i++;
            if (ret.GetPositionAtOffset(i, LogicalDirection.Forward) == null)
                return ret.GetPositionAtOffset(i-1, LogicalDirection.Forward)

        }
        ret=ret.GetPositionAtOffset(i, LogicalDirection.Forward);
        return ret;
}
7
ответ дан 30 November 2019 в 12:27
поделиться

Не удалось найти решение с приемлемой производительностью решения этой проблемы в течение длительного времени. Следующий пример работает в моем случае с максимальной производительностью. Надеюсь, это тоже кому-нибудь поможет.

TextPointer startPos = rtb.Document.ContentStart.GetPositionAtOffset(searchWordIndex, LogicalDirection.Forward);
startPos = startPos.CorrectPosition(searchWord, FindDialog.IsCaseSensitive);
if (startPos != null)
{
    TextPointer endPos = startPos.GetPositionAtOffset(textLength, LogicalDirection.Forward);
    if (endPos != null)
    {
         rtb.Selection.Select(startPos, endPos);
    }
}

public static TextPointer CorrectPosition(this TextPointer position, string word, bool caseSensitive)
{
   TextPointer start = null;
   while (position != null)
   {
       if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
       {
           string textRun = position.GetTextInRun(LogicalDirection.Forward);

           int indexInRun = textRun.IndexOf(word, caseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase);
           if (indexInRun >= 0)
           {
               start = position.GetPositionAtOffset(indexInRun);
               break;
           }
       }

       position = position.GetNextContextPosition(LogicalDirection.Forward);
   }

   return start; 
}
2
ответ дан 30 November 2019 в 12:27
поделиться
    private TextPointer GetPoint(TextPointer start, int pos)
    {
        var ret = start;
        int i = 0;
        while (i < pos)
        {
            if (ret.GetPointerContext(LogicalDirection.Forward) ==
    TextPointerContext.Text)
                i++;
            if (ret.GetPositionAtOffset(1, LogicalDirection.Forward) == null)
                return ret;
            ret = ret.GetPositionAtOffset(1, LogicalDirection.Forward);
        }
        return ret;
    }
0
ответ дан 30 November 2019 в 12:27
поделиться

Попробуйте следующее:

var textRange = MyRichTextBox.Selection;
var start = MyRichTextBox.Document.ContentStart;
var startPos = start.GetPositionAtOffset(3);
var endPos = start.GetPositionAtOffset(8);
textRange.Select(startPos, endPos);
textRange.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(Colors.Blue));
textRange.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
8
ответ дан 30 November 2019 в 12:27
поделиться

Между прочим (и это может быть академическим для всех, кроме меня), если вы установите FocusManager.IsFocusScope = "True" в контейнере RichTextBox, например, в Grid

<Grid FocusManager.IsFocusScope="True">...</Grid>

, тогда вы должен иметь возможность использовать метод Colorize Йохана Данфорта без двух вызовов ApplyPropertyValue, а RichTextBox должен использовать выбор по умолчанию Background и Foreground для выделения выделения.

private void Colorize(int offset, int length, Color color)
{
    var textRange = MyRichTextBox.Selection;
    var start = MyRichTextBox.Document.ContentStart;
    var startPos = GetPoint(start, offset);
    var endPos = GetPoint(start, offset + length);

    textRange.Select(startPos, endPos);
}

Не пробовал использовать RichTextBox, но он неплохо работает при создании шаблонов для поиска TextBox в FlowDocumentReader. Чтобы быть уверенным, вы также можете установить

<RichTextBox FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}">...</RichTextBox>

, чтобы RichTextBox имел фокус в пределах своей области фокуса.

Обратной стороной этого, конечно же, является то, что если пользователь щелкает или выполняет выбор в RichTextBox, ваш выбор исчезает.

1
ответ дан 30 November 2019 в 12:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: