Display rich text streaming using WPF

I have a WPF application that connects through a socket to a device and receives streaming text data (about 1 message per second). This data is then displayed in the user interface. The user can create rules such as "If the data contains" abc ", select the line" or "... make it bold", so plain text output will not be executed, it must be "rich" text.

My current solution for this is FlowDocument in my ViewModel model, which contains formatted output. The view has a FlowDocumentScrollViewer that is associated with a FlowDocument in the ViewModel.

This works, but when a FlowDocument gets large (~ 6000 lines), performance starts to deteriorate. The current algorithm limits the number of lines to 10,000, but then everything becomes even worse, until the moment when the application is unusable. When it reaches 10,000 rows, I delete the row for each row to be added, as a result of which FlowDocumentScrollViewer receives 2 update notifications for each new row.

I tried to find a way to batch delete (when we reach 10,000 rows, delete the oldest 1000 rows), but there is no bulk delete in FlowDocument. Looping 1000 times and performing removal results in 1000 update notifications and blocking the user interface.

Here is my problem, here is my question:

What is the best way to display streaming text content with WPF? I get ~ 1 message per second, each message is ~ 150 characters, and I want to save the last 10,000 messages. Am I really wrong? Are there other controls / objects that will work better?

EDIT : Here are a few more requirements

  • You must be able to print the output text.
  • You must be able to select and copy the output text so that it can be pasted into another document.
+3
source share
3 answers

, -, FlowDocument. , .

, Paragraph, 250 Runs Paragraph, Paragraph... 250 Runs... . .

, (10 000). , ( CPU), Paragraph 250 .

. , , 15%.

+5

FlowDocumentScrollViewers - .. , WPF RichTextBox ? , .NET 3.5 SP1? FlowDocuments 1: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a116da54-ce36-446a-8545-3f34e9b9038d.

0

, , , . , VirtualizingStackPanel . , VirtualizationStackPanel .

, .

EDIT: , ListBox VirtualizationStackPanel . , :

  • , .
  • , FlowDocument " "
  • ListBox .
  • ItemTemplate ListBox FlowDocumentScrollViewer, Document .

2: /: WPF (, VisualBrush?), . ZoomListBox, . XAML :

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

:

public partial class ZoomListBox
{
    public ZoomListBox()
    {
        this.InitializeComponent();
    }

    public double Zoom
    {
        get { return (double)GetValue(ZoomProperty); }
        set { SetValue(ZoomProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Zoom.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ZoomProperty =
        DependencyProperty.Register("Zoom", typeof(double), typeof(ZoomListBox), new UIPropertyMetadata(1.0));
}

:

<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>
0

Source: https://habr.com/ru/post/1706063/


All Articles