I'm trying to improve the performance of my treeview in WPF, when you open a node with 6000 children, it takes about 13 seconds currently to display this. I am using an observablecollection for the child collection, with a datatemplate bound to the TransactionViewModel type which has about 7 columns, each pulling in a piece of data from the view model.
The transactionviewmodels for the 6000 children are created and instantiated, but as you haven't displayed any of them visually yet, the first time you expand the node, it takes the 13 seconds to display. if you then contract and expand the node, it displays instantly with zero time to display/load. The only difference I can see is that the first time each of the bound dependency properties of the TransactionviewModel has it's getter called by the XAML binding, and when you re-expand the second time, none of this happens as nothing has changed so WPF doesnt call the getters again and presumably just holds the bound information in memory for when you expand it the second time.
So the visual drawing of the control is instant, but the first time you open it (even though the 6000 transactionviewmodel objects are already fully loaded into the child collection), purely the rendering of the rows is what's taking the time.
Interestingly if I alter the datatemplate to not bind to ANY dependency properties on the viewmodel object and just output a blank grid, it still takes 8 seconds to load. So even without any data binding calls, the tree viewer takes 8 seconds to render 6000 rows. 5 seconds extra then gives you about 5 bound data columns per row, so that is a small cost compared to the basic rendering.
8s to render 6000 blank rows seems very high to me. Are there any major reasons why this might be happening or things to be aware of in rendering XAML into a treeview from data templates? Ive tried using just an empty datatemplate - ie not even a blank grid inside it and it still takes 7 seconds.
Given that it then collapses and expands instantly, why is it taking so long the first time when it isn't even rendering any XAML or calling any data bindings?
Also asynch calls are not a solution as my problem is not GUI responsitivy but time taken to load data. The user needs to have the data quicker than they are getting it right now.
Many thanks
WPF performance depends heavily on the quality of the video card in the machine more that the processor/memory. Bad video card = bad WPF performance. Save this answer.
The WPF system defines three rendering tiers: Rendering Tier 0 No graphics hardware acceleration. All graphics features use software acceleration. The DirectX version level is less than version 9.0.
Try this: Open the task manager, go to the processes tab, go to view, select collums and check the box that says VM size. Notice that when you minimize or restore a program or application the memory changes from what's in Memory Usage to VM size.
WPF uses vector graphics as its rendering data format. Vector graphics—which include Scalable Vector Graphics (SVG), Windows metafiles (. wmf), and TrueType fonts—store rendering data and transmit it as a list of instructions that describe how to recreate an image using graphics primitives.
It looks to me like you need to enable virtualization in the TreeView.
From Optimizing Performance: Controls:
By default, UI virtualization is enabled for the ListView and ListBox controls when their list items are bound to data. TreeView virtualization can be enabled by setting the VirtualizingStackPanel::IsVirtualizing attached property to true
If a TreeView contains many items, the amount of time it takes to load may cause a significant delay in the user interface. You can improve the load time by setting the VirtualizingStackPanel.IsVirtualizing attached property to true. The UI might also be slow to react when a user scrolls the TreeView by using the mouse wheel or dragging the thumb of a scrollbar. You can improve the performance of the TreeView when the user scrolls by setting the VirtualizingStackPanel.VirtualizationMode attached property to Recycling.
How to: Improve the Performance of a TreeView
XAML:
<TreeView Height="200" ItemsSource="{Binding Source={StaticResource dataItems}}" x:Name="myTreeView"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"/>
Programmatically:
myTreeView.SetValue(VirtualizingStackPanel.IsVirtualizingProperty, true);
myTreeView.SetValue(VirtualizingStackPanel.VirtualizationModeProperty, VirtualizationMode.Recycling)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With