WPF DataGrid updates slowly after hiding

I am using .NET 4.0 WPF DataGrid bound to an ObservableCollection<T> . The collection contains rows added and deleted several times per second. DataGrid contained in TabControl / TabItem / Grid .

It works more or less OK, as long as I leave it visible. If I switch to another application tab, come back in a few minutes, the user interface stream will close within 30 seconds (about 1200 lines, about 40 of which are on the screen). All line data is already in memory, so there is no I / O. All related properties - either simple strings, numbers or dates, or the logic for creating them is very simple; nothing complicated or time consuming to calculate.

If the number of rows exceeds several hundred, selecting a new column for sorting is very slow. Adding a new line also seems slow. If I switch to another tab and then go back, the grid will reappear quickly.

Resizing the window is excellent.

Scrolling speed is slow at first, but after the grid is fully loaded; it is never wonderful. Without ScrollView.CanContentScroll="False" scrolling is so slow that it cannot be used. Using IsDeferredScrollingEnabled="True" instead causes a delay of 10+ seconds when rendering after the user releases the scroll bar - still an unacceptable user interface.

There are 17 DataGridTextColumns . Multiple columns use custom StringFormats , but nothing complicated. No TypeConverters .

Visual Studio tools / profiler were useless. This seems like a relatively simple / straightforward setup. Any suggestions on how to increase productivity would be appreciated.

I would also like to know WHY he is SO slow.

 <DataGrid x:Name="MyGrid" AutoGenerateColumns="False" Margin="3,35,3,20" VerticalContentAlignment="Center" Width="Auto" FontSize="12" FontFamily="Consolas" ScrollViewer.CanContentScroll="False" CanUserResizeRows="False" AlternationCount="2" AlternatingRowBackground="#FFE3F0FF" VirtualizingStackPanel.VirtualizationMode="Recycling" IsReadOnly="True"> <DataGrid.Columns> <DataGridTextColumn Header="XX" Binding="{Binding Path=XX}" /> <DataGridTextColumn Header="YY" Binding="{Binding Path=YY, StringFormat={}{0:0.0}}"> <DataGridTextColumn.ElementStyle> <Style> <Setter Property="TextBlock.TextAlignment" Value="Right" /> </Style> </DataGridTextColumn.ElementStyle> </DataGridTextColumn> . . . </DataGrid.Columns> </DataGrid> 
+4
source share
2 answers

Remove ScrollViewer.CanContentScroll = "False" . It will disable the default virtualization support for the WPI DataGrid.

See the answer here. Physical scrolling disables user interface virtualization .

From the answer -

"ScrollViewer currently allows you to use two scrolling modes: smooth pixel scrolling (CanContentScroll = false) or discrete scrolling for each element (CanContentScroll = true). Currently, WPF only supports user interface virtualization when scrolling through an element. Pixel based scrolling also called physical scrolling, and item-based scrolling is also called logical scrolling.

UPDATE

You can set IsDeferredScrollingEnabled to true in case you need a smooth operation while dragging the scroll bar. This will make the objects that will be displayed only after you release the finger of the scroll bar, instead of creating all the elements during the drag operation.

 <DataGrid ScrollViewer.IsDeferredScrollingEnabled="True"/> 

Also, this link from MSDN can help you.

+4
source

I recommend that you investigate the problem of TabControl in a state of maintaining a tab state when switching between tab elements.

TabControl has a certain behavior: when the tab element is not selected, its contents are destroyed and it needs to be recreated when the tab element is selected again, which means that the entire DataGrid and all its visible DataGridCells must be recreated.

Just google for "Persistent Visual Tree in WPF TabControl" or "Persist State in WPF TabControl".

0
source

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


All Articles