缓慢格式化RichTextBox

时间:2013-07-25 08:18:22

标签: wpf performance richtextbox flowdocument

在rtb中格式化文本时,我的表现很差:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal">
        <Button Click="ApplyFormatClick">ApplyFormat</Button>
        <TextBlock x:Name="Time"/>
    </StackPanel>

    <RichTextBox x:Name="Rtb" Grid.Row="1">
        <RichTextBox.Document>
            <FlowDocument>
                <Paragraph>
                    <Run>
                        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
                    </Run>
                </Paragraph>
            </FlowDocument>
        </RichTextBox.Document>
    </RichTextBox>
</Grid>

代码背后:

private readonly SolidColorBrush _blueBrush = Brushes.Blue;
private void ApplyFormatClick(object sender, RoutedEventArgs e)
{
    Stopwatch stopwatch = Stopwatch.StartNew();
    FlowDocument doc = Rtb.Document;
    TextRange range = new TextRange(doc.ContentStart, doc.ContentEnd);
    range.ClearAllProperties();
    int i = 0;
    while (true)
    {
        TextPointer p1 = range.Start.GetPositionAtOffset(i);
        i++;
        TextPointer p2 = range.Start.GetPositionAtOffset(i);
        if (p2 == null)
            break;
        TextRange tempRange = new TextRange(p1, p2);
        tempRange.ApplyPropertyValue(TextElement.ForegroundProperty, _blueBrush);
        tempRange.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
        i++;
    }
    Time.Text = "Formatting took: " + stopwatch.ElapsedMilliseconds + " ms, number of characters: " + range.Text.Length;
}

应用格式化会花费一秒钟,而在对其进行分析时,罪魁祸首是:

tempRange.ApplyPropertyValue(TextElement.ForegroundProperty, _blueBrush);
tempRange.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);

对我来说,分析器结果非常不透明。

之前我从未使用过FlowDocumentRichTextBox因此我可能做错了。

最终结果意味着类似于VS find replace,它将基于可编辑的正则表达式突出显示文本中的匹配。

可以采取哪些不同的措施加快速度? (Sample on Github

3 个答案:

答案 0 :(得分:9)

建议使用新格式化(you can check the MSDN Magazine August 2007: WPF Flexible Content Display With Flow Documents;或最新的MSDN文章Flow Document Overview)手动构建FlowDocument,这将显着提高效果,例如使用你的例子,如果手动如下,在我的机器上它将得到52毫秒的结果,其中使用ApplyPropertyValue需要1266毫秒:

private readonly SolidColorBrush _blueBrush = Brushes.Blue;

private void ApplyFormatClick(object sender, RoutedEventArgs e)
{
    Stopwatch stopwatch = Stopwatch.StartNew();
    FlowDocument doc = Rtb.Document;
    TextRange range = new TextRange(doc.ContentStart, doc.ContentEnd);
    Paragraph para = new Paragraph();
    string rangetem = range.Text;
    range.ClearAllProperties();

    for(int i=0; i<rangetem.Count();i+=2)
    {
        Span s = new Span() { Foreground = _blueBrush };
        Bold b = new Bold();
        s.Inlines.Add(rangetem[i].ToString());
        b.Inlines.Add(s);
        para.Inlines.Add(b);
        if(i+1<rangetem.Count())
        {
            para.Inlines.Add(rangetem[i + 1].ToString());
        }
    }
    doc.Blocks.Clear();
    doc.Blocks.Add(para);

    Time.Text = "Formatting took: " + stopwatch.ElapsedMilliseconds + " ms, number of characters: " + range.Text.Length;
}

答案 1 :(得分:5)

如果RichTextBox不需要后退功能,可以通过将IsUndoEnabled设置为false来提高性能

<RichTextBox IsUndoEnabled="False">

答案 2 :(得分:1)

您可以使用以下方法显着提高文本格式的性能:

rtb.BeginChange();

/// Your formating logic

rtb.EndChange();
相关问题