为什么在添加新文本时,行之间有空行?

Why when adding new text the lines have empty lines between them?

private void Println(string text, SolidColorBrush brush) => Dispatcher.Invoke(() =>
        {
            RichTextBoxLogger.Document.Blocks.Add(new Paragraph(new Run(text) { Foreground = brush }));
        });

        private void Println(string text)
        {
            Println(text, Brushes.LawnGreen);
        }

        private void PrintMsg(string message)
        {
            Println($"[+] {message}", Brushes.Yellow);
        }

        private void PrintErr(Exception e)
        {
            Println($"[-] {e}", Brushes.Red);
        }

正在使用

private void Fsw_Deleted(object sender, FileSystemEventArgs e)
        {
            string time = DateTime.Now.ToString("h:mm:ss tt");

            string output = $"[*] {e.Name}: \"Deleted At : {time}\"";
            Println(output);
        }

结果是:

我想添加这几行,它们之间没有空行。

为了防止两个连续段落之间出现中断,您必须将 Paragraph.KeepWithNext 属性 设置为 true:

var paragraphWithoutBreak = new Paragraph { KeepWithNext = true };

我不建议您使用繁重的 RichTextBox 来完成您的任务。当输出增长时它会变慢。而是使用灯 ListBoxListBox 具有 UI 虚拟化功能,将显着提高性能。当您将 ListBoxItem.IsHitTestVisible 设置为 false 时,ListBox 看起来和感觉起来就像一个 read-only 文档。为每个消息类型定义一个 DataTemplate 以控制输出的外观:

ILogMessage.cs

interface ILogMessage
{
  string Message { get; }
}

ErrorMessage.cs
一条红色消息。

class ErrorMessage : ILogMessage
{
  // TODO::Implement interface and add a constructor that accepts a message.
}

WarningMessage.cs
一条黄色消息。

class WarningMessage : ILogMessage
{
  // TODO::Implement interface and add a constructor that accepts a message.
}

InfoMessage.cs
一条绿色消息。

class InfoMessage : ILogMessage
{
  // TODO::Implement interface and add a constructor that accepts a message.
}

MainWindow.xaml.cs

partial class MainWindow : Window
{
  public ObservableCollection<ILogMessage> Messages { get; }
  
  public MainWindow()
  {
    InitializeConmponent();
    this.Messages = new ObservableCollection<ILogMessage>();
  }

  private void WriteInfoLine(string message) 
    => this.Messages.Add(new InfoMessage(message));

  private void WriteWarningLine(string message) 
    => this.Messages.Add(new WarningMessage(message));

  private void WriteErrorLine(string message) 
    => this.Messages.Add(new ErrorMessage(message));
}

MainWindow.xaml

<Window>
  <Window.Resources>
    <DataTemplate DataType="{x:Type local:InfoMessage}">
      <TextBlock Text="{Binding Message, Mode=OneTime}"
                 Foreground="LawnGreen" />
    </DataTemplate>

    <DataTemplate DataType="{x:Type local:WarningMessage}">
      <TextBlock Text="{Binding Message, Mode=OneTime}"
                 Foreground="Yellow" />
    </DataTemplate>

    <DataTemplate DataType="{x:Type local:ErrorMessage}">
      <TextBlock Text="{Binding Message, Mode=OneTime}"
                 Foreground="Red" />
    </DataTemplate>
  </Window.Resources>

  <ListBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Messages}">
    <ListBox.ItemContainerStyle>
      <Style TargetType="ListBoxItem">
        <Setter Property="IsHitTestVisible"
                Value="False" />
      </Style>
    </ListBox.ItemContainerStyle>
  </ListBox>
</Window>

请参阅 了解如何在添加新项目时将消息视图滚动到底部。您可以使用示例的 LogMessageBox 控件(一个 UserControl)并替换上面的 ListBox.