First off I have a datagrid on the main form which is populated with about 7000 rows. It is bound (to ItemsSource) in the forms constructor. Everything runs extremely fast and smooth when the app loads (less than 1 sec). However when I want to load that same datagrid in another window it takes > 1 min. There is no difference in the xaml between pages. What could be causing this. I am using Virtualizing Stack panel as well as turning on Cell and Row Virtualization on the DataGrid. I have profile my Sql Server and the query runs in the same time for both calls so it's not a database issue.
I got curious and set up a listview and bound it to the same source on the second form and the same scenario happens as well.
What could be the issue?
Thanks Andrew. I figured it out but I think it's a bug. In my main form the datagrid is in row 2 column 2. In my calling form it was in row 0, column 0. When I made another row and moved the datagrid to it it loaded just like it did in the main form. The datagrid obviously didn't like being in row 0. It works now so I won't be using reflector to look at it.
Related
I have a Winform that has 2 datagridviews (parent-child relationship) that I fill with data on form load. I then have a textbox that I put a date in and use it to filter the main grid's databindingSource (which appropriately filter the child grid).
Everything was working fine as I developed the form until it seem to not want to refresh the form... portions of the form would simply be white until I actually move the form around on the screen making it repainted. Now that the form is painted I select different rows in the grid with either the mouse or the navigationsource's next/back arrows. The grid again doesn't refresh unless I move the form around the screen again (grab the title bar and move it around).
I have code in the child form's RowPrePaint method which shouldn't affect anything right? That's the only method that could remotely distrupt the form painting.
I'm going to start reversing my steps but I don't think there is anything that's going to make sense.
Does any of this sound familiar?
I believe the problem is that I had conflicting code in the DataGridView_RowsAdded and the DataGridView_RowPrePaint. I've also switched from the DataGridView_RowPrePaint to DataGridView_RowStateChanged as suggested here: RowsAdded Event in DataGridView only firing for first 2 rows
Thanks for the suggestions
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
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)
Your problem is likely not rendering but layout - it has to instantiate a lot of UI elements to find the size of them so that it can properly size a number of UI elements (sliders), and this takes time. Rendering likely does not enter into this at all.
I have a WPF DataGrid that must have the row headers and columns added programmatically. I've implemented this successfully but the performance is not acceptable. Each time a column is added the ColumnCollection puts out a CollectionChangedEvent. I have not found a way to disable this event so I've investigated other ways of improving performance.
I have created the DataGrid on a background thread and attempted to add the grid to the UI, without success, getting the following message:
"UI Element is owned by a different thread"
I've created the DataGrid on the main UI thread and tried to add the columns in a background thread. Same issue. I cannot ask the UI thread to do it as that's the problem in the first place.
What other approaches are used to add a lot of columns to a DataGrid? (in one case 10,000 columns)
Janene
I ended up using this line of code to create the DataGrid in the Background and add it to the UI.
this.Dispatcher.BeginInvoke(DispatcherPriority.Background, new UpdateNodesDelegate(UpdateNodes));
Got this solution from the book WPF Recipes in C# 2008.
Janene
I have a Window with a DataGrid showing grouped Data.
I am loading around 4 x 300 items in the WPF DataGrid which are grouped in 4 groups.
Grouping disables Virtualization.
I set IsAsync="True" so my Window opens fast but the DataGrid is just filled AFTER 11 SECONDS ???
What can I do to speed up the loading/display of my data?
You stated it yourself - grouping disables virtualization; I think for now showing each group separately (in its own datagrid) is the way to go if at all possible... or some other similar trick to simply not show all the items using grouping.
Much later edit:
There's actually quite an interesting write-up at http://jerryclin.wordpress.com/2008/02/22/listbox-grouping-and-virtualization/ on how to go about doing things if you REALLY need ListBox grouping with virtualization. Not sure it's worth the pain, but it's possible.
Not sure if its related, but I had a similar problem with the DataGrid in which it took literally seconds to refresh after a window resize, column sort, etc. and locked up the window UI while it was doing so (1000 rows, 5 columns).
It came down to an issue (bug?) with the WPF sizing calculations. I had it in a grid with the RowDefinition Height="Auto" which was causing the rendering system to try and recalculate the size of the DataGrid at runtime by measuring the size of each and every column and row, presumably by filling the whole grid (as I understand it). It is supposed to handle this intelligently somehow but in this case it was not.
A quick check to see if this is a related problem is to set the Height and Width properties of the DataGrid to a fixed size for the duration of the test, and try running again. If your performance is restored, a permanent fix may be among these options:
Change the sizes of the containing elements to be relative (*) or
fixed values
Set MaxHeight and MaxWidth of the DataGrid to a fixed value larger
than it could get in normal use
Try another container type with different resizing strategy (Grid, DockPanel, etc)
In .NET 4.5.2 virtualizing grouped items is finally possible:
<DataGrid VirtualizingPanel.IsVirtualizingWhenGrouping="True" />
https://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingpanel.isvirtualizingwhengrouping%28v=vs.110%29.aspx
I got a DataGrid with 6 column, each column is a RadioButton so that user can select 1 in 6 option. There are about 100 row. I make a custom class with 6 bool datamember, then bind the datagrid with a list of about 100 custom class object. There are 2 problem:
The binding time is very slow
When I scroll the data grid, sometime the check value of some row disappear.
Are there any known issues with datagrid when bind to a large amount of data like this? And how to improve the performance. I'm using the June Release of WPF Toolkit
Thanks
P/S: You can download my sample app to understand exactly the problem
http://www.mediafire.com/file/jrmft4m4jwm/WpfApplication3.zip
Have you looked into using a VirtualizingStackPanel? This will improve performance for large collection of data for rendering on screen.
If you can, switch to the .NET 4.0 version of DataGrid.
For me it reduced binding time from 80 secs to <0.5secs on 10000 rows, 10 columns.
Also, make sure to use UI Virtualization (turned on by default, but sometimes it gets disabled)
WPF Toolkit DataGrid scrolling performance problems - why?