Saturday, 3 July 2010

Martin's DataGrid VirtualizingPanel Epiphany

I have a View which looks a bit like this :

<DataGrid ItemSource={BindingToSomethingWithManyHundredRows} />

Now, you probably know a little about Virtualizing Panels.. Basically.. Rather than try to draw all 800 rows immediately, it’ll create the UI Elements for the rows actually visible on the screen (and a few extra to smooth scrolling), and then only create others as they’re scrolled into the visible area.

By default, DataGrid uses a VirtualizingPanel so all is happy and rendering takes about 0.3 secs. If I explicitly use a non virtualizing layout panel to display the rows, it’ll take about 15 seconds, so we don’t like this much.

Now.. I wanted to put a ComboBox above the DataGrid on the View, so while I was messing about with code I simply dropped a around the pair and carried on. So now I have :


Now.. I’ve done this before and I know that doing this will switch off the scrollbar of the Grid because the stackpanel has told the grid that it has as much space as it needs (so the rows disappear off the bottom of the page with no way to scroll to them).. But I was only testing some code I was working on, so I didn’t care..

What did surprise the heck out of me (which in hindsight it shouldn’t) is that it now took 15 seconds to render... So what’s happening? Well we’re still using a Virtualizing Panel, but it thinks all rows are visible because of the stackpanel, so it goes ahead and draws them all, even though they’re not actually visible..

So.. I’ve replaced my StackPanel with a Grid and all is happy again... But, I figured it was a worthwhile point to mention for you all – you don’t want to put StackPanels around ItemsControls which would Virtualize the layout panel for you.. A) you’ll lose scrolling unless you jump through various hoops, but B) you’ll lose all the performance benefits of using a Virtualizing Panel.. Which can be very dramatic..

Good luck & may all your panels be virtualizing

No comments: