14
votes

I am testing WPF DataGrid in hopes of replacing some winforms controls, and so far have been very pleased with the development process. Performance seems to be my biggest concern right now. My development workstation has just about the best cpu on the market running windows 7, with 6 gigs of DDR3 memory. The windows control i am replacing is considerably more responsive which is worrisome.

My test is a basic implementation of DataGrid bound to ObservableCollection which gets updated once per second. It also includes Details area which is expandable to reveal more info about each row. Details area is just a stackpanel with a ItemsControl wrapping TextBlock (which repeats 6 times)

My complaint is that if i try to scroll this collection, it is often jerky with lag, and if i try to expand each row as they come in, about 15% of clicks do not trigger buttons click event (DataGridTmplateColumn > CellTemplate > DataTemplate > Button) Also scrolling is more jittery if some rows detail is expanded (with scroll bar that resizes it self as it goes up/down)

what are some things to look for / optimize / avoid ?

update

here are some points i found helpful so far:

  • rely as little as possible on dynamic layout. as each component contains many subcomponents and in dynamic layout world, all of them have to call Measure and Layout methods which can be cpu intensive. so instead of column width Auto (or no width specified), use fixed widths

  • install WPF Performance Suite and get in touch with how your app is rendered. trully awesome app

  • as Andrew pointed out ListView is a great alternative, for when you don't need advanced DataGrid features, such as updating the data back, or possibly Details View (which i am still hoping to reproduce)

  • also SuspendableObservableCollection is ideal for when you're adding multiple items in very short period of time (i.e. 100 items in 0.01 second etc)

  • after lots of testing, i found that BindingList is much faster than ObservableCollection . I posted performance profiler snapshots here of the same load handled by BindingList vs Observable collection, and the former takes less than half cpu time. (keep in mind that this is not just collection performance, but when paired with a ListView)

my search still continues as something appears to be leaking memory in my app and slows it down to a halt after couple hours.

3
What gets updated once per second? The ObservableCollection? How is it being updated (item added, all replaced, item removed, etc.)?Jay
_myObservableCollection.Insert(0, newItem)Sonic Soul

3 Answers

2
votes

A general tip for DataGrid performance issues: I had a 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)
1
votes

You mean DataGrid from WPF Toolkit? If yes, In my opinion it's pretty slow, so I ended up using ListView with GridView.

1
votes

More general tips:

For scrolling, what we have done is tried to use Deferred Scrolling.

To improve the Filtering performance you could consider filtering the bound collection yourself.

For grids with large number of columns apply ColumnVirtualization as well. This tends to affect the horizontal scrolling a little bit adversely but you could test your scenario and apply improvements. For us it did work perfectly. It helped us on Refresh, Reload, Render scenarios for large grids.

Performance is also impacted by the styling applied.