Обновить текст FlowDocument в CodeBehind - PullRequest
0 голосов
/ 31 мая 2018

Мне нужно изменить текст FlowDocument без изменения существующего форматирования, и у меня возникают проблемы при этом.

Я думал сделать foreach из Blocks в документе.Затем для любого Paragraph выполните foreach из Inlines следующим образом:

foreach (var x in par.Inlines)
{
    if (x.GetType() == typeof(Run))
    {
        Run r = (Run)x;
        r.Text = r.Text.Replace("@", "$");
    }
}

Проблема заключается в том, что это возвращает следующее сообщение об ошибке:

System.InvalidOperationException: «Коллекция была изменена;Операция перечисления может не выполняться. '

Как правильно это сделать?

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Обычным решением является вызов ToList () для коллекции и итерация по новой коллекции, возвращаемой ToList ().

var runs =
    flowdoc.Blocks.OfType<Paragraph>()
    .SelectMany(par => par.Inlines).OfType<Run>()
    .ToList();

foreach (var r in runs)
{
    r.Text = r.Text.Replace("@", "$");
}
0 голосов
/ 31 мая 2018

Ваша ошибка возникла из-за попытки использовать цикл foreach для перечисления в коллекции при одновременном изменении коллекции.Используйте цикл for.

Для изменения текста в потоковом документе попробуйте TextPointer + TextRange, вот пример (этот изменяет текстовый фон, но вы можете изменить текст так же легко).

private void ClearTextHighlight(FlowDocument haystack)
{
    TextPointer text = haystack.ContentStart;
    TextPointer tpnext = text.GetNextContextPosition(LogicalDirection.Forward);

    while (tpnext != null){
        TextRange txt = new TextRange(text, tpnext);
        //access text via txt.Text

        //apply changes like:
        var backgroundProp = txt.GetPropertyValue(TextElement.BackgroundProperty) as SolidColorBrush;

        if(backgroundProp != null && backgroundProp.Equals(Setting_HighlightColor)){
            //change is here
            txt.ApplyPropertyValue(TextElement.BackgroundProperty, Setting_DefaultColor);                
        }
        text = tpnext;
        tpnext = text.GetNextContextPosition(LogicalDirection.Forward);   
    }
}
...