簡體   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