I am running the ANTS profiler on my application and my code seems to be spending a lot of time on a line of code where I try to determine if a particular column exists on a row in the grid. I am currently using e.Row.Cells.Exists(XXX) where XXX is the column name. Is there a faster way to do this?
Hello,
The Exists method on the CellsCollection is inherited from our base collection class, so it would be looking for an UltraGridCell and not a column. Instead, you can use e.Row.Band.Columns.Exists(xxx).
Please try this out and let me know whether it improves the application's performance.
I misspoke. My code will get a cell and I can get the column from that cell. Just wondering if there is a better way to do this. Sounds like EXISTS is the way to go?
Hi Richard,
Exists is the way to go in this situation. However, it's not normally required to test whether a column exists. May I ask why you need to use this check? I will be able to provide a better recommendation if I learn more about your requirement.
Hi,
There are some objects that the grid will not create until they are needed, such as the rows and cells. But I am almost certain that all of the Column objects are created initially. At the very least, the Column object would have to be created if any cell or header from that column is displayed on the screen. So I wouldn't worry too much about forcing the cretion of columns.
The safest way to determine if a column exists would be to use the band.Columns.Exists method. But this method IS going to loop through the Columns collection, anyway. So it's less code, but it's no more efficient than if you looped through the columns yourself.
I'm not entirely sure if row.Cells.Exists is very efficient. It's possible that this method creates the cell objects, which would be inefficient, but it might just be calling into the band.Columns.Exists, which means it would be essentially the same.
A Try..Catch is the least efficient option. An exception that occurs and is caught causes a severe performance hit. But, of course, this only causes a problem if there is an exception occurring. If the column always exists, then this would be more efficient than calling band.Columns.Exists since you would avoid looping. On the other hand, if the exception never occurs, then the Try...Catch itself is irrelevant and unnecessary.
So what it really comes down to is... under what circumstances would the column not exist? The InitializeRow won't fire until you bind the grid to a data source. So if you are looking for a bound column, the column will always be there and there's no reason to check if it exists. The only way a bound column would not exist is if your grid is being bound to more than one data source and some data sources have the column and others don't. In a case like that, it would probably be best to simply keep track of which daat source you are currently bound to and use that the determine what to do.
If you have unbound columns in your grid, then it's possible that the InitializeRow will fire in some cases before that unbound column has been added. For example, if you bind the grid and the grid paints before the unbound column has been added. Typically, you bind the grid in Form_Load or some other early initialization event and then add the unbound column in the InitializeLayout event. As long as you don't do anything in between that forces the grid to paint or create the rows, then InitializeRow won't fire until after InitializeLayout and once again, everything will be fine.
If you do have a case where something in your code causes InitializeRow to fire before InitializeLayout and you therefore have an unbound column that doesn't yet exist, then that's the only case where you might need to check for the existence of the column. I typically use e.Row.Cells.Exists and it's usually okay - unless you have a tremendous number of columns. If you do have a very large number of columns and Exists is therefore causing a performance problem, then the absolutely best, most efficient method of handling this would be to use a flag. Just declare a boolean variable like 'unboundColumnsAreCreated'. Default the flag to false. When you add your unbound column(s), set it to true. Then you can check the flag inside InitializeRow.
I have a handler for the InitializeRow event of the grid and some of my grids have a lot of rows and/or columns. We have found that looping through the column collection of the grid band slows things down because it creates an instance of the column object. We were told we could improve performance by trying to avoid creating this instance until the last possible moment. As a result, I am looping through a separate collection of the keys in the column collection and when I need to finally get an instance of the column, I create the instance of the column object by using Row.Cells(strKey), where Row is the grid row. To avoid errors, I am first checking to see if the column exists. What I have settled on in the meantime is putting a TRY...CATCH block around this call and leaving the EXISTS check out. This seems to be working pretty well for me, but I was hoping to find a better way.