更新CodeBehind

时间:2018-05-31 18:02:42

标签: wpf flowdocument

我需要在不更改现有格式的情况下更改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 :(得分:1)

您的错误来自于尝试使用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);   
    }
}

答案 1 :(得分:1)

通常的解决方案是在集合上调用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("@", "$");
}