不要使用
TextBlock
完成这项任务。这个
控件
优化为最多只显示几行。它不是为显示多行文档而设计的。
建议的解决方案是使用
ListBox
.它提供了虚拟化,以提供平滑的滚动体验。
您可以覆盖
ListBoxItem
移除鼠标并突出显示效果。这边
列表框
将看起来像纯文本文档或公共控制台输出。
不要使用
Dispatcher
在这种情况下也是如此。如果你需要更新
ObservableCollection
,这是
列表框
,在后台线程中,使用
BindingOperations.EnableCollectionSynchronization
.
留言。反恐精英
public class MessageLine : INotifyPropertyChanged
{
public MessageLine(string message) => this.Message = message;
public string Message { get; }
public event PropertyChangedEventHandler PropertyChanged;}
public override string ToString()
=> $"Formatted message content: {this.Message}.";
}
主窗口。xaml。反恐精英
partial class MainWindow : Window
{
public ObservableCollection<MessageLine> Messages { get; }
publiv MainWindow()
{
InitializeComponent();
this.Messages = new ObservableCollection<MessageLine>();
}
private void InsertLineAtBeginning(MessageLine message) => this.Messages.Insert(0, message);
private void AppendLine(MessageLine message) => this.Messages.Add(message);
private async Task ReadMessageAsync(TcpClient client, bool ownsClient)
{
await using NetworkStream stream = client.GetStream();
...
// Since we insert at the beginning but want to have a proper line order of the multi-line message,
// we must insert the last line first (reverse order - you can use a Stack to collect the lines)
string messageBody = Encoding.UTF8.GetString(buffer, 0, bytesRead);
InsertLineAtBeginning(new MessageLine(messageBody));
var messageHeader = $"-->{receptiontime}";
InsertLineAtBeginning(new MessageLine(messageHeader));
}
private async void SaveMessages_OnClick(object sender, EventArgs e)
{
await using var fileWriter = new StreamWriter("destination_file.txt", false);
foreach (var message in this.Messages)
{
// Call ToString() for a defined string representation of the instance.
// Requires to override ToString to get a useful value.
await fileWriter.WriteLineAsync(message.ToString());
// Alternatively, format message inline
await fileWriter.WriteLineAsync($"Formatted message content: {message.Message}");
}
}
}
主窗口。xaml
<Window>
<ListBox ItemsSource="{Binding RlativeSource={RelativeSource AncestorType Window}, Path=Messages}">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:MessageLine}">
<TextBlock Text="{Binding Message}" />
</DataTemplate>
</ListBox.ItemTemplate>
<!-- Remove interaction effects -->
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContenPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Window>
您还可以移动
列表框
到
UserControl
还是习俗
Control
.