C# 使用WPF显示流式富文本
我有一个WPF应用程序,它通过一个套接字连接到一个设备,并获取流式文本数据(大约每秒1条消息)。然后,该数据将显示在UI上。用户可以创建规则,如“如果数据包含'abc'突出显示行”或“…使其加粗”,因此纯文本输出将不起作用,它需要是“富”文本 我目前的解决方案是在我的ViewModel中有一个包含格式化输出的。该视图具有绑定到ViewModel中的FlowDocument的 这是可行的,但当FlowDocument变大(约6000行)时,性能开始下降。目前的算法将行数限制在10000行,但情况变得更糟,应用程序无法使用。当它达到10000行时,我会为添加的每一行删除一行,从而使FlowDocumentScrollViewer为每一新行获得2个更新通知 我试图找到一种批量删除的方法(当我们达到10000行时,删除最旧的1000行),但是在FlowDocument上没有批量删除。循环1000次并执行删除操作将导致1000次更新通知并锁定UI 这是我的问题,我的问题是: 使用WPF显示流式富文本内容的最佳方式是什么?我每秒收到约1条消息,每条消息约150个字符,我想保留最后10000条消息。我走错方向了吗?是否有其他性能更好的控件/对象 编辑:这里还有一些要求C# 使用WPF显示流式富文本,c#,.net,wpf,flowdocument,C#,.net,Wpf,Flowdocument,我有一个WPF应用程序,它通过一个套接字连接到一个设备,并获取流式文本数据(大约每秒1条消息)。然后,该数据将显示在UI上。用户可以创建规则,如“如果数据包含'abc'突出显示行”或“…使其加粗”,因此纯文本输出将不起作用,它需要是“富”文本 我目前的解决方案是在我的ViewModel中有一个包含格式化输出的。该视图具有绑定到ViewModel中的FlowDocument的 这是可行的,但当FlowDocument变大(约6000行)时,性能开始下降。目前的算法将行数限制在10000行,但情况变
- 需要能够打印输出文本
- 需要能够选择并复制输出文本,以便将其粘贴到另一个文档中
<ListBox
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Test.ZoomListBox"
d:DesignWidth="640" d:DesignHeight="480"
x:Name="ThisControl">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True">
<VirtualizingStackPanel.LayoutTransform>
<ScaleTransform ScaleX="{Binding ElementName=ThisControl, Path=Zoom}" ScaleY="{Binding ElementName=ThisControl, Path=Zoom}" />
</VirtualizingStackPanel.LayoutTransform>
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
以及一个使用它的示例:
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<l:ZoomListBox x:Name="ZoomList">
<Button>Foo</Button>
<Button>Foo</Button>
<Button>Foo</Button>
<Button>Foo</Button>
<Button>Foo</Button>
<Button>Foo</Button>
<Button>Foo</Button>
</l:ZoomListBox>
<Slider Grid.Row="1" Value="{Binding ElementName=ZoomList, Path=Zoom}" Minimum="0.5" Maximum="5" />
</Grid>
福
福
福
福
福
福
福
性能崩溃似乎是由FlowDocument中的大量块造成的。对于收到的每一条消息,我都在创建一个运行,将该运行添加到一个段落,并将该段落添加到文档中
我改变了算法,所以现在它创建了一个段落,然后在该段落中添加250次,然后创建一个新段落。。。添加250次运行。。。等等这实际上将块的数量减少了一半
当我达到最大行数(10000)时,这还有一个额外的好处。我可以删除最旧的段落,而不是为每增加一行删除一行(并固定CPU),这会立即删除最旧的250行
这一相对简单的改变使性能在可接受的范围内。不再固定CPU和锁定UI,现在CPU保持相对较低,峰值约为15%。它最初是一个RichTextBox,但我将其更改为打印、缩放。。。免费的。根据我所做的测试,大约一半的性能影响来自FlowDocumentScrollViewer,另一半来自FlowDocument本身?另外,有关进一步的文本优化技巧,请参阅。有趣的想法,感谢您“跳出框框”。我将研究类似的内容,但我需要能够从输出区域选择/复制数据。另外,我现在可以免费打印和缩放,所以我需要想出一个解决方案。我可以在我的机器上使用类似的场景,而不会出现显著的性能问题(例如,它将数据作为字符串。我创建一个带有字符串的运行,然后创建一个带有运行的段落。然后我将其命名为.MyFlowDoc.Blocks.Add)(第段);
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<l:ZoomListBox x:Name="ZoomList">
<Button>Foo</Button>
<Button>Foo</Button>
<Button>Foo</Button>
<Button>Foo</Button>
<Button>Foo</Button>
<Button>Foo</Button>
<Button>Foo</Button>
</l:ZoomListBox>
<Slider Grid.Row="1" Value="{Binding ElementName=ZoomList, Path=Zoom}" Minimum="0.5" Maximum="5" />
</Grid>