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?
Related
I have a Silverlight 5 app with a PivotViewer in it. This is binding with the data source correctly, but I need to force a rebind on the templates without replacing the data source and re-setting the entire control. The results are.... interesting.
We are using a ValueConverter to determine what color a tile should be, and this value converter can be adjusted depending on an external selection. At this point the INotifyPropertyChange of all the records are fired and a rebind occurs, but only on the currently visible template. This leads to tiles changing colors when zooming in and out as the other views have no been refreshed.
Can anyone tell me if it is possible to implement this in such a way that it would affect all levels of zoom? And is it possible to trigger a rebind without firing the INotifyPropertyChange?
Thanks
After considerable investigation, I came across this issue in the microsoft bug tracker:
http://connect.microsoft.com/VisualStudio/feedback/details/768779/silverlight-forum-issue-with-changing-items-background-color-for-sl5-pivotviewer
The description:
Create a simple data class that implements INotifyPropertyChanged, change all the items' color every 5 secs, but some items have different background color with different zoom levels. This issue was reported from Silverlight forum: http://forums.silverlight.net/p/262082/654612.aspx/1?Re+PivotViewer+SL5+Dynamic+Collection+to+change+item+background+color
So I guess that explains what the problem was. Just waiting for a fix now.
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 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
Datagrid contains more than 200 rows and 15 columns some cell contains graph as well.
Virtualization is enable in datagrid so datagrid doesnt have entire viusal.
The wpf datagrid is great at some things. we haven't had much luck using it with large data sets, its a bit slow and clunky. there are other products such as the xCeed grid which is good for large data sets, however it has its drawbacks as well (its harder to use). We are hoping (hope - one of the tools in this developers arsenal) that they fix this issue in the next release.
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.