How to autosize column width in datagridview with large amount of rows in c#

Darryl Hoar 181 Reputation points
2023-06-29T14:01:08.14+00:00

I have created a Winform application. One of the forms has a datagridview component. It is bound to a binding source that contains a large amount of data. I need to autosize 2 columns to get the fit I need. When autosize for those columns is set to none, it renders the data in the datagridview relatively fast. If I set autosize for those columns to what I need, it takes forever.

How can I accomplish what I need?

Visual Studio 2019 Winform project c#

Developer technologies C#
{count} votes

Accepted answer
  1. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2023-06-29T19:20:48.3433333+00:00

    Here is something to try. Make sure AutoSizeColumnMode is set to None.

    internal static class DataGridViewExtensions
    {
        /// <summary>
        /// Provides very fast and basic column sizing for large data sets.
        /// </summary>
        public static void FastAutoSizeColumns(this DataGridView targetGrid, params string[] includeColumns)
        {
            // Cast out a DataTable from the target grid data source.
            // We need to iterate through all the data in the grid and a DataTable supports enumeration.
            var gridTable = (DataTable)targetGrid.DataSource;
    
            // Create a graphics object from the target grid. Used for measuring text size.
            using (var gfx = targetGrid.CreateGraphics())
            {
                // Iterate through the columns.
                for (int index = 0; index < gridTable.Columns.Count; index++)
                {
                    var test = gridTable.Columns[index];
                    if (includeColumns.Contains(gridTable.Columns[index].ColumnName))
                    {
                        // Leverage Linq enumerator to rapidly collect all the rows into a string array, making sure to exclude null values.
                        string[] colStringCollection = gridTable.AsEnumerable().Where(r => r.Field<object>(index) != null).Select(r => r.Field<object>(index).ToString()).ToArray();
    
                        // Sort the string array by string lengths.
                        colStringCollection = colStringCollection.OrderBy((x) => x.Length).ToArray();
    
                        // Get the last and longest string in the array.
                        string longestColString = colStringCollection.Last();
    
                        // Use the graphics object to measure the string size.
                        var colWidth = gfx.MeasureString(longestColString, targetGrid.Font);
    
                        // If the calculated width is larger than the column header width, set the new column width.
                        if (colWidth.Width > targetGrid.Columns[index].HeaderCell.Size.Width)
                        {
                            targetGrid.Columns[index].Width = (int)colWidth.Width;
                        }
                        else // Otherwise, set the column width to the header width.
                        {
                            targetGrid.Columns[index].Width = targetGrid.Columns[index].HeaderCell.Size.Width;
                        }
                    }
                }
            }
        }
    }
    

    Then after load data. In this case I want to manually size two columns.

    dataGridView1.FastAutoSizeColumns("ProductName", "CompanyName");
    
    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.