9

在 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 查找替换,它将基于可编辑的正则表达式突出显示文本中的匹配项。

有什么不同的方法可以加快速度?(Github 上的示例

4

3 回答 3

10

FlowDocument建议使用新格式手动构建您的(您可以查看 MSDN 杂志 2007 年 8 月:WPF Flexible Content Display With Flow Documents;或最新的 MSDN 文章Flow Document Overview),这将显着提高性能,例如使用您的例如,如果如下手动执行,在我的机器上它将在 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;
}
于 2013-07-25T10:01:04.780 回答
7

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

<RichTextBox IsUndoEnabled="False">
于 2013-07-26T01:58:22.803 回答
3

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

rtb.BeginChange();

/// Your formating logic

rtb.EndChange();
于 2014-01-07T19:43:15.203 回答