The purpose of this article is to provide some general programming practice guidelines and troubleshooting tips to improve performance when using the UltraWinGrid control. Not all of the tips provided here will apply to every application, but it should help with the most common performance issues a developer is likely to encounter.
If you are concerned about reducing the amount of memory used by the grid, then there are several important things you can do to reduce it.
The grid does not create UltraGridCell objects for every row of data. Cells are only created as neccessary. So whenever possible, you should avoid accessed a cell. For example, suppose your code is using the InitializeRow event of the grid in order to calculate a total. For example:
}
This code references three cells in each row of the grid, thus creating a lot of objects which are potentially unneccessary. This can be avoided using methods on the row to deal with cell values, rather than the cell objects themselves. Like so:
By using the GetCellValue method, we can eliminate 2 cells per row in this example and save memory.
Another common use for the InitializeRow event is to apply an appearance to a cell based on the Value of that cell. Applying an appearance to a cell requires getting a reference to the UltraGridCell, so that is unavoidable. But you can save memory by re-using the same appearance object for multiple cells. Suppose, for example, that you want to change the ForeColor of a cell to red for negative numbers and black for positive numbers. You might do something like this:
This code will create a cell for every row. That is unavoidable, since the cell must be created in order to have an Appearance. The bigger problem here is that the Appearance property on the cell is lazily created. That means that we are not only creating a cell for each row, but a new Appearance object for each row. And since there are only two possible colors, we end up creating a large number of identical appearance objects.
A better way to do this is to create the Appearances we need up front and then re-use the same appearance wherever it is needed.
Another benefit to this approach is that you can change the appearance everywhere en masse. For example, suppose your users want to use Green instead of Black for positive appearances. You could, at run-time, set the ForeColor of the “Positive” Appearance object, and every cell in the grid that was using that appearance would update automatically.
We are using windgrids a lot our applications, and in most cases we have a grid which has the first column as a driver for the values in the second which are dynamically added to a value list and then the value list is added to the e.Cell.ValueList. In section 3) value list - Make sure every grid cell value exists on the list, We have a problem as the grid would search every row for the column being changed to find out that the none of the values exist in the currently returned options in the valuelist. We Have noticed that with 40 rows their is a marked delay from when the new value list is returned and when we set the e.Cell.ValueList property to when it display's to the user. Is there a way to stop the windgrid from searching all the cells in the column? And if not then why does it do this search each time?
ADASDev said:We Have noticed that with 40 rows their is a marked delay from when the new value list is returned and when we set the e.Cell.ValueList property to when it display's to the user.
Are you talking about 40 rows in the ValueList? Or 40 rows in the grid?
If you mean the ValueList has 40 items, then this should be practically instantaneous and I can't see how it could possibly cause a performance problem, unless there are exceptions occuring.
If you mean 40 rows in the grid and your ValueList has a lot more rows, then the grid has to search the list to find the matching value in order to convert the DataValue into the corresponding DisplayText. There's no way around this.
Perhaps instead of assigning a new ValueList to each cell, you should just use a Filtered UltraDropDown that contains a list of all possible values.
There is an article describing this technique here.
I have a similar issue in that the grid appears to loop through all the columns and bands at design time. I have a grid that represents the tasks in a project plan. The max band depth is set to 5 to prevent the grid from looping through 100X itterations through the recursive table.
The grid is painfully slow to work with at design time, but I am okay with that since it has added code to create all the fields and band objects. But since this code is already there, and the behavior for both new bands and new columns is set to hide, why does it loop through again at run time? This causes an unacceptable delay when loading the grid even with an empty task collection.
I'm hoping for my sake that there is a way to turn off this behavior or I'm going to have to redo this using something else.