We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

100,000 hidden rows

We have a huge grid (about 100000 rows and 100000 columns). It works well until we hide rows and columns. If there are many hidden rows and columns, the grid control begins to work too slowly. There are some problems concerning hiding rows and columns. 1. GridModelHideRowColsIndexer.SetRange() method works too slowly. Initially our grid should have all rows and columns hidden and then we unhide only small areas. If range is about 100000, the method takes 30 - 40 seconds. Is it possible to create a grid with all rows and columns hidden (or almost all, except first ones)? We would like to do this because creating a huge grid, then hiding almost all cells takes lots of time. 2. GridPaint.DrawClientRowCol() method has a nested loop like this: for (colIndex = 0; colIndex < ds.nCols; colIndex++) { for (rowIndex = 0; rowIndex < ds.nRows; rowIndex++) { } } If bounds of hidden rows and columns are in a visible area, those loops iterate for them too. But if there are 100000 hidden rows and 100000 hidden columns, there will be 100 000 * 100 000 = 10 000 000 000 iterations. The program freezes. We have fixed this problem by overriding GridControlBase.OnDrawClientRowCol() method. Our method breaks the whole redrawn area to pieces with only non-hidden cells and calls method of base class only for those visible areas. The problem is: GridPaintSelectCellsInternal.PrepareClearSelection() method is called upon current cell change. It is called as a result of Model.PrepareClearSelection event call. It has the same nested loop. In contrast with GridPaint.DrawClientRowCol(), which accepts a drawing rectangle, GridPaintSelectCellsInternal.PrepareClearSelection() works for all cells currently present on screen, including the hidden ones. Can we bypass this?

7 Replies

AD Administrator Syncfusion Team August 19, 2003 02:45 PM UTC

I think it would be more efficient for you to maintain a custom mapping of Visible rows and for Visible columns. It could be something as simple as an ArrayList for each. The idea is that the array list would hold the visible indexes. So, if 50 of 100000 rows are visible, then the arraylist would hold the 50 visible indexes. Then you could handle QueryRowCount and QueryCellInfo, and provide the rowcount as the size of the arraylist (50) in QueryRowCount. In QueryCellInfo, you would use the e.EowIndex to retrieve the corresponding row in your data from the arraylist. This way the grid would only think it has 50 rows, and would display them very quickly.


EN Eugene N. Bogatyriov August 20, 2003 05:43 AM UTC

Thanks Clay. We've thought of this solution earlier, but unfortunately it won't work for us. Our grid contains formulas, and each formula can refer to any cell in the whole grid, so the grid MUST have all data completely, because visible cells can refer to hidden cells and vice versa. Moreover, we have other view of data and it should display all changes immediately, including recalculated formulas in hidden cells. So, we do need a huge grid. It was one of the critical points for us when we selected a grid control. The background of our needs is the following: we have the application which works with images and displays numerical RGB values in a grid. It is possible to change the image by typing values or formulas. When a part of the image is selected, we need to hide the rest. We also have a "special area", which always starts from 100,000 and can refer to the area where the image is displayed. Therefore, if we have a 100x100 image, we'll have the rows 1-100 visible, then 101-99,999 hidden, then 100,000-100,005 visible.


AD Administrator Syncfusion Team August 21, 2003 06:35 AM UTC

You might be able to do what you what using 2 grids. One grid (dataGrid) is the large 100000x100000 grid. The other grid(viewGrid) is a virtual grid bound to the the dataGrid's GridData object through QueryCellInfd, QueryRowCount, QueryColCount, and SaveCellInfo events. The idea is that viewGrid will only display the 'visible rows/cols' in dataGrid, and you will just keep dataGrid hidden. There are arraylists of visible rows/cols that are used to map the data from the dataGrid to the viewGrid. And the formula cells are handled exclusivesly through the dataGrid events so they update and reference out of that grid. You just see the calculated values in the dataView. Attached is a sample showing how this might be done. It os set just to use 1000x4 cells but 100000x4 behave the same way. There is one refresh problem that cannot not be efficiently handled in teh current code base. If you change a cell in the viewGrid that is used in a formula reference in another cell, the two cells get updated ok in the dataGrid, but the second cell does not get refreshed in the viewGrid. The sample works around this problem just be calling Invalidate on teh whole visible grid in this situation. In 2.0, there will be a formula event that you can catch to just update the dependent cells in this case.


AS Andrey Samsonov August 21, 2003 03:35 PM UTC

Thanks for explanation. We will try to implement this idea. May be some problems will appear, but now I see only one: If grid cell has a formula, we should show a formula text if cell is in edit mode and formula result otherwise. How we can detect in QueryCellInfo event handler whether the cell is in edit mode at the moment?


AD Administrator Syncfusion Team August 21, 2003 04:31 PM UTC

Try this. In viewGrid_SaveCellInfo, right after the call to RefreshRange, add this call: this.dataGridFormulaEngine.RecalculateRange(GridRangeInfo.Cell(row, col), true); Also, add this event handler.
private void viewGrid_CurrentCellInitializeControlText(object sender, GridCurrentCellInitializeControlTextEventArgs e)
{
	if(e.ColIndex > 0 && e.RowIndex > 0)
	{
		int row = (int) this.visibleRows[e.RowIndex];
		int col = (int) this.visibleCols[e.ColIndex];
		
		GridStyleInfo style = new GridStyleInfo(theData[row, col]);
		if(style.CellType == "FormulaCell" && !GridUtil.IsEmpty(style.Text) && style.Text[0] == '=')
		{
			e.ControlText = this.dataGrid[row, col].Text;
		}
	}
}


AS Andrey Samsonov August 22, 2003 02:45 PM UTC

Your example is very useful for us, but it has one issue: When I input a formula in a viewGrid, in a dataGrid this formula is not calculated. When I set a focus to the cell in dataGrid, it shows formula, but after focus is removed the cell displays an old value. Moreover, when I change value of cell, which is referred by this formula, the formula is not recalculated. Evidently, setting "dataGrid[row, col].Text" property is not enough to force formula to work correctly.


AD Administrator Syncfusion Team August 22, 2003 03:21 PM UTC

Did you add this line that I suggested earlier? this.dataGridFormulaEngine.RecalculateRange(GridRangeInfo.Cell(row, col), true);

Loader.
Live Chat Icon For mobile
Up arrow icon