繁体   English   中英

如何从 WPF 中的 RichTextBox 控件中删除第一行文本?

[英]How to remove the top line of text from RichTextBox control in WPF?

我正在开发一个 WPF 应用程序,我需要一个空间来以类似控制台的方式频繁显示彩色文本行(底部显示新行,rest 正在向上移动)。 为此,我决定使用名为“outputBox”的 RichTextBox 控件:

<RichTextBox Name="outputBox" 
                         Grid.Row="0"
                         Background="Black"
                         Foreground="White"
                         Margin="10"
                         FontSize="14"
                         IsReadOnly ="True"
                         Focusable="False"
                         FontFamily="Consolas"
                         VerticalScrollBarVisibility="Visible"
                         >

我还创建了以下方法来将新的文本行(每个不同的颜色)附加到 outputBox:

private void PrintMessage(string msg, MessageType type = MessageType.Default)
        {

            TextRange tr = new(this.Window.outputBox.Document.ContentEnd, this.Window.outputBox.Document.ContentEnd);
            tr.Text = "\n" + msg;

            switch (type)
            {
                case (MessageType.Default):
                    tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.LightGray);
                    break;
                case (MessageType.UserInput):
                    tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Aqua);
                    break;
                case (MessageType.SystemFeedback):
                    tr.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.DarkSalmon);
                    break;
             }

            Window.outputBox.ScrollToEnd();
        }

问题是,当 outputBox 达到大量文本行(例如 100 000)时,应用程序的性能会显着下降。 为了解决这个问题,我想在 outputBox 上设置文本行的限制,因此当达到该限制时,第一行将被删除/清除,而不会丢失剩余文本行的文本格式。 如何做到这一点?

如果将 RichTextBox 的文本添加到ParagraphInlines集合中,则代码将具有更好的性能。

但是为了在缩小文档以限制其中的某些行数时提高性能,我建议限制段落大小。

下面的代码实现了这个逻辑:

public static class RichTextBoxExt
{
    public static void PrintMessage(this RichTextBox rtb, string msg, MessageType type = MessageType.Default)
    {
        // Maximum of blocks in the document
        int MaxBlocks = 500; 
   
        // Maximum of lines in one block (paragraph)
        int InlinesPerBlock = 500;

        SolidColorBrush brush = Brushes.LightGray;
        switch (type)
        {
            case MessageType.UserInput:
                brush = Brushes.Aqua;
                break;
            case MessageType.SystemFeedback:
                brush = Brushes.DarkSalmon;
                break;
        }

        // Get the latest block in the document and try to append a new message to it
        if (rtb.Document.Blocks.LastBlock is Paragraph paragraph)
        {
            var nl = Environment.NewLine;

            // If the current block already contains the maximum count of lines create a new paragraph
            if (paragraph.Inlines.Count >= InlinesPerBlock)
            {
                nl = string.Empty;
                paragraph = new Paragraph();
                rtb.Document.Blocks.Add(paragraph);
            }                
            paragraph.Inlines.Add(new Run(nl + msg) { Foreground = brush });
        }

        if (rtb.Document.Blocks.Count >= MaxBlocks)
        {
            // When the number of lines more that (MaxBlocks-1)*InlinesPerBlock  remove the first block in the document
            rtb.Document.Blocks.Remove(rtb.Document.Blocks.FirstBlock);
        }
    }
}

也许应该调整段落Margin以获得更好的视觉效果:

<RichTextBox x:Name="rtb" Margin="3"  VerticalScrollBarVisibility="Auto">
    <RichTextBox.Resources>
        <Style TargetType="{x:Type Paragraph}">
            <Setter Property="Margin" Value="2,0,0,2"/>
        </Style>
    </RichTextBox.Resources>
    <FlowDocument>
        <Paragraph>                    
        </Paragraph>
    </FlowDocument>
</RichTextBox>

最后添加一条消息:

rtb.PrintMessage("Some_Message");
rtb.ScrollToEnd();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM