Hi,
We have a hierarchical UltraGrid that is bound to an UltraDataSource, which is in turn based off a hierarchical data structure of objects. When creating a new band for the UltraDataBand (and hence UltraGrid), we have a function that will reflectively loop through an object's type, get the appropriate properties, and then create columns based on those properties and their return types.
When building the grid for the first time, it works great. However the structure can change based on changes the user has made in other forms, and so rather than rebuilding the whole grid each time, we simply work out how the grid should change and add UltraDataBands and UltraDataRows so that those changes are reflected in the grids.
All this runs through exactly the same functions as the original 'bulk' load. However for some reason, adding columns to UltraDataBands once they have already been created like this takes A LOT longer. E.g. when building the original 5 band deep tree it takes 23 millisecs to create the columns. When trying to add 3 bands to the same grid, it takes 17543 millisecs.
I can't seem to track down why it is so much slower. Is it because there are events being thrown once the grid is displaying? I tried setting the EventManager.AllEventsEnabled to false but that didn't seem to make a difference.
Thanks, Dane.
Okay, so that tells us that the problem is the grid, not the UltraDataSource.
11 seconds seems like a really long time and it might indicate that there is some inefficiency in the grid code.
What version of the grid are you using?
Can you duplicate this in a small sample project and post it here so we can check it out?
By using the Begin/EndUpdate and Suspend/ResumeRowSynchronization, it reduced the time from 17 secs to 11 secs. I also found by setting the UseBindingSource property of the UltraDataSource to false while I am adding the columns to the band reduces the time further to 9 secs.
Unbinding, then rebinding, it takes 860 millisecs. However, as you said it loses all the row-specific information, which unfortunately isn't acceptable.
I need it to be the same as the original build while keeping the row information, so I'll have to keep looking. Thanks for your help.
Dane.
Hi Dane,
This is only a guess, but I think what may be happening is that when you add the bands initially, the grid hasn't painted, yet. So it probably doesn't respond to each individual notification from the data source.
When you do this the second time, the grid is already bound. So every change you make to the data source sends a separate individual notification to the grid and the grid has to respond to each one, one at a time.
To confirm that, just as a test, try unbinding the grid, then update the UltraDataSource, then re-bind the grid. At the very least, that will tell us whether the issue is with the grid or the UltraDataSource.
If that is the case, then you have a number of potential options. One is... in addition to using BeginUpdate to prevent the grid from painting, you can also use SuspendRowSynchronization/ResumeRowSynchronization.
If those don't help, then perhaps you can save the grid's layout and unbind it, then re-bind it and restore the layout. This is not ideal, as you will lose any kind of row-specific state information, such as the selected and expanded states of the rows. But it's better than waiting 17 seconds. :)
i believe you have to suspend also the painting of the grid and not only the Events so, try something like this
ultraGrid1.BeginUpdate();//suspends painting
//here add code that creates the new bands and columns
ultraGrid1.EndUpdate()//resume painting