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
close icon

Best Practices with ResizeToFit, VirtualGrid, millions of rows

Greetings, GridControl Wizards :-) I'm searching for the best way to optimize the presentation of our log file data. Assume that there are 4 columns of data and a million rows of data in an ArrayList, and the grid populates itself virtually (QueryRowCount, QueryColCount, QueryCellInfo are wired in correctly). Where and when is the optimal way to call Grid.RowHeights.ResizeToFit()? I added some code to the QueryCellInfo call that calculates the row's height and attempts to set the row height, but that resulted in poorly formatted rows. I'm thinking that I'll need to call ResizeToFit on the visible range (TopRowIndex...ViewLayout.LastVisibleRow) when the grid is first populated, and whenever the grid is scrolled/paged/arrow-key-navigated. If this is the best apporach, where are these events defined? Thanks, -Roy

11 Replies

AD Administrator Syncfusion Team October 10, 2003 11:39 AM UTC

Any chance you can save the row height within that array list? You could then override OnPaint, call BeginUpdate(), ResizeToFit(), EndUpdate(false) for the rows that are about to be painted and have not been resized yet. Key is that you only resize rows that have not been resized. Otherwise they get resized with every paint call and that's something you don't want. You should also override SaveRowHeight and QueryRowHeight. That let's you save and restore the row height from that array list. If you can't store anything in that array list try creating your own array list and set/restore heights in that. Stefan


RM Roy Muller October 10, 2003 03:34 PM UTC

Stefan- Thanks for the speedy reply. Unfortunately I'm unclear on the solution. I have a GridControl on a Form. When you say override OnPaint, do you mean override the Form's OnPaint handler or do you mean subclass the GridControl and override the derived GridControl's OnPaint Handler? What I did was override the Form's OnPaint method and addded event handlers to the GridControl's SaveRowHeight and QueryRowHeight events. What I'm seeing is that every single row is being resized before the form gets shown. Any ideas why OnPaint is trying to draw every row in the grid? Is the first line in my OnPaint handler the correct way to determine the rows that are about to be painted? Here are the pertinent handlers: protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { GridRangeInfo l_gri = m_gridControlLogFileContents.RectangleToRangeInfo( e.ClipRectangle ); // update the row sizes for any rows that are not already optimally sized m_gridControlLogFileContents.BeginUpdate(); for( int l_iRowIndex = l_gri.Top; l_iRowIndex <= l_gri.Bottom; l_iRowIndex++ ) { if( 0 == m_gridControlLogFileContents.RowHeights[ l_iRowIndex ]) { m_gridControlLogFileContents.RowHeights.ResizeToFit( GridRangeInfo.Row( l_iRowIndex )); System.Diagnostics.Debug.WriteLine(string.Format("Resizing row {0}", l_iRowIndex )); } } m_gridControlLogFileContents.EndUpdate(false); base.OnPaint( e ); } private void m_gridControlLogFileContents_SaveRowHeight(object sender, Syncfusion.Windows.Forms.Grid.GridRowColSizeEventArgs e) { if( e.Index > 0 ) { LogRecord l_record = (LogRecord)m_alLogRecords[ e.Index - 1 ]; if( null != l_record ) { l_record.RowHeight = e.Size; e.Handled = true; } } } private void m_gridControlLogFileContents_QueryRowHeight(object sender, Syncfusion.Windows.Forms.Grid.GridRowColSizeEventArgs e) { if( e.Index > 0 ) { if( null != m_alLogRecords ) { LogRecord l_record = (LogRecord)m_alLogRecords[ e.Index - 1 ]; if( null != l_record ) { e.Size = l_record.RowHeight; } else { e.Size = 0; } } else { e.Size = 0; } e.Handled = true; } } #region VirtualGrid Events private void m_gridControlLogFileContents_QueryColCount(object sender, Syncfusion.Windows.Forms.Grid.GridRowColCountEventArgs e) { e.Count = LogRecord.ColumnHeaders.Length; e.Handled = true; } private void m_gridControlLogFileContents_QueryRowCount(object sender, Syncfusion.Windows.Forms.Grid.GridRowColCountEventArgs e) { if( null != m_alLogRecords ) { e.Count = m_alLogRecords.Count; } else { e.Count = 0; } e.Handled = true; } private void m_gridControlLogFileContents_QueryCellInfo(object sender, Syncfusion.Windows.Forms.Grid.GridQueryCellInfoEventArgs e) { if( e.ColIndex > 0 ) { if( e.RowIndex == 0 ) { e.Style.Text = LogRecord.ColumnHeaders[ e.ColIndex - 1 ]; e.Handled = true; } else if( e.RowIndex < 0 ) { e.Handled = false; } else { LogRecord l_record = (LogRecord)m_alLogRecords[ e.RowIndex - 1 ]; e.Style.Text = l_record[ e.ColIndex - 1]; e.Style.BackColor = l_record.BackColor; e.Handled = true; } } } #endregion VirtualGrid Events Thanks for any insights, -Roy Muller


RM Roy Muller October 10, 2003 04:17 PM UTC

Hi Stefan- I changed the OnPaint handler to conditionally resize only the visible rows. Now it displays the first 22 rows ok but the vertical scrollbar seems to think there are only 22 rows instead of the 66,000 records that my ArrayList contains. Here's the modified OnPaint handler: protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) { // update the row sizes for any rows that are not already optimally sized m_gridControlLogFileContents.BeginUpdate(); for( int l_iRowIndex = m_gridControlLogFileContents.TopRowIndex; l_iRowIndex <= m_gridControlLogFileContents.ViewLayout.LastVisibleRow; l_iRowIndex++ ) { if( 0 == m_gridControlLogFileContents.RowHeights[ l_iRowIndex ]) { m_gridControlLogFileContents.RowHeights.ResizeToFit( GridRangeInfo.Row( l_iRowIndex )); System.Diagnostics.Debug.WriteLine(string.Format("Resizing row {0}", l_iRowIndex )); } } m_gridControlLogFileContents.EndUpdate(false); base.OnPaint( e ); } There are over 70 other posts in this forum that have ResizeToFit in the message text. This is not an easy problem to solve :-/ Thanks for your efforts. -Roy


AD Administrator Syncfusion Team October 10, 2003 04:44 PM UTC

One guess: Don't set e.Size = 0 when you don't have a row size yet. Instead set it to some value e.g. 20 or do not set e.Handled = true in that case. Stefan


RM Roy Muller October 13, 2003 11:31 AM UTC

Hello again Stafan, I just wanted to thank you for the suggestions. I had a situation where I called grid.Invalidate() followed by grid.Refresh() and the form containing the grid never had it's OnPaint method called. When I subclassed the grid and overrode the Grid's OnPaint handler everything worked out. Do I have to Invalidate a control's parent containers up to the TopLevel form in order to cause a Paint event to occur? Is this a bug in the 1.0 .Net Framework, the GridControl, or my own misconception? Thanks again for your excellent support. -Roy


AD Administrator Syncfusion Team October 13, 2003 12:07 PM UTC

The problem is that probably BeginUpdate() was called and then any attemps to call Refresh() were blocked. You can cancel the IsUpdating mode by calling CancelUpdate(). Then the Refresh call should work as expected. Stefan


RM Roy Muller October 13, 2003 03:46 PM UTC

Indeed, that is/was the problem. Subclassing the GridControl allows the resize to occur as it is rendered (faster, smoother) whereas using the grid with overriding the Form's OnPaint and calling CancelUpdate is, well, fun to watch as the cells resize ;-) Thanks again for your insights. I'mm looking forward to version 2.0 sometime soon :-) -Roy


AD Administrator Syncfusion Team March 17, 2006 10:29 PM UTC

Stefan, I am using Syncfusion v 2.0.5.1, .net v 1.1. I have data(6 columns and millions of rows) in a class, need to populate those values in the gridcontrol; I have implemented the virtual grid as mentioned above (including save/query rowheights). The problem is when populate the data to the grid, it loads the each row with default rowheight and then expand each row. Also, if I drag the vscroll bar to bottom the data did not resize correctly. Can you give me a sample code for Save/Query row height in the virtual grid?


AD Administrator Syncfusion Team March 21, 2006 12:56 PM UTC

Hi, Sorry for the delayed response. Here is the code snippet, explains how the row height from external data is set and save again to external data. private void gridControl1_QueryRowHeight(object sender, GridRowColSizeEventArgs e) { if(e.Index > 0) { e.Size = this._extData.RowHeight[e.Index - 1]; e.Handled = true; } } private void gridControl1_SaveRowHeight(object sender, GridRowColSizeEventArgs e) { if(e.Index > 0) { this._extData.RowHeight[e.Index - 1] = e.Size; e.Handled = true; } } Please refer to the demo sample for more details. Let us know if this helps. Best regards, Madhan.


DM Desis Machino March 28, 2006 08:23 PM UTC

I am trying to follow your approach in this email thread for saving row heights in a GridControl in Virtual Mode. I am using version 2.0.5.1 However I am experiencing some difficulties with my implementation. When I first open the form that has the grid with the data, the data is shown correctly. However, when I click on the scroll bar to page down, the newly displayed rows all as their default size. If I then minimize and redisplay the app, the grid shows all the rows sized correctly. I put some trace messages and this is what I observed. I logged the row value within QueryRowHeight and found that it was querying for the displayed rows from the top displayed row, to the last displayed row. And everything displayed correctly. Then when I paged down using the scrollbar, I saw that it properly queried the newly displayed rows, and then it queried the very last very last few of the grid that were not displayed. So lets say I have 200 rows and rows 20-30 are shown after paging down. I see the query for rows 20-30 and they show the correct height as calculated in SaveRowHeight, but then a query is done for rows 200-190 (it queries, 200,199,198...190) and since those rows heights have not been calculated, they have a height of 0 (in my row hashtable). And then the display shows the new rows, with the default heights (not those calculated in SaveRowHeight). In fact, in this scenario, the row heights used to display the currently displayed rows (20-30) seem like it is taken from the last few rows (200-190). If I minimize then bring up the application (force the view to refresh), everything looks fine, but then if I page down, the same sequence happens again. Have you or anyone experienced this kind of scenario. Is there a known problem with the version of Syncfusion we are using with GridControl in virtual mode, or is there something I am doing incorrectly. Any help is greatly appreciated. Thanks.


AD Administrator Syncfusion Team March 29, 2006 02:16 PM UTC

Hi Vikram, I have tried to reproduce the issue in our latest version, but couldn’t. Can you please try setting HScrollPixel and VScrollPixel property in the Form_Load event and see it helps to resolve the issue. this.gridControl1.VScrollPixel = true; this.gridControl1.HScrollPixel = true; Thanks for the patience. Best regards, Madhan

Loader.
Live Chat Icon For mobile
Up arrow icon