Reputation: 53
I have a datagridview with many columns in it, AutoSizeColumnsMode ist set to AllCells. Now my question is, why is there so much empty space next to most of the column headers? For example the empty space for the column header with "HBW 5/250" is nearly the same space as needed for the text. Is there a reason behind it? The problem I have that the whole datagridview should be visible on one screen (24 inch), and I don't know how I can get those columns to only be as large as the longest text is.
It's a C# WinForms application.
I've also looked into all the other options of the AutoSizeColumnsMode Property, but nothing worked for me.
Best regards.
Upvotes: 2
Views: 1574
Reputation: 7155
If your columns are sortable, then there will be extra white space on the right side where the sorting arrow appears. If you don't need your columns to be sortable, then set the column sort mode to NotSortable and you will save a bit of space.
dataGridView1.Columns[0].SortMode = DataGridViewColumnSortMode.NotSortable;
Unfortunately, this will not get rid of all the excess white space in the header. Windowsforms is not great at managing column width when it has to automatically wrap text. If you replace the space in your column header with a new line as seen below, you will notice that all of the white space is gone and it sizes the column perfectly since no wrapping is required.
dataGridView1.Columns[0].HeaderText = "HBW 2,5/62,5";
dataGridView1.Columns[0].HeaderText = "HBW\n2,5/62,5"; //White space gone
Upvotes: 1
Reputation: 2499
For more accurate and faster way of auto sizing cells in datagridview i have found somewhere (do not know where) and modified some function so here is how it looks now:
public static void FastAutoSizeColumns(this DataGridView targetGrid)
{
//If targeted datagridview doesn't have rows just return
if (targetGrid.Columns.Count < 1)
return;
var gridTable = new DataTable();
// Cast out a DataTable from the target grid datasource.
// We need to iterate through all the data in the grid and a DataTable supports enumeration.
gridTable = (DataTable)targetGrid.DataSource;
targetGrid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
// Create a graphics object from the target grid. Used for measuring text size.
using (var gfx = targetGrid.CreateGraphics())
{
// Iterate through the columns.
for (int i = 0; i < gridTable.Columns.Count; i++)
{
// 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>(i) != null).Select(r => r.Field<object>(i).ToString()).ToArray();
// Sort the string array by string lengths.
colStringCollection = colStringCollection.OrderBy((x) => x.Length).ToArray();
if (colStringCollection.Length > 0)
{
// 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[i].HeaderCell.Size.Width)
{
targetGrid.Columns[i].Width = (int)colWidth.Width;
}
else // Otherwise, set the column width to the header width.
{
targetGrid.Columns[i].Width = targetGrid.Columns[i].HeaderCell.Size.Width;
}
}
else
{
targetGrid.Columns[i].Width = targetGrid.Columns[i].HeaderCell.Size.Width;
}
}
}
}
Import this function somewhere in file (i use separate file for custom extensions) and just call it with:
yourDataGridView.FastAutoSizeCoulmns();
Important note: DataSource need to be type of DataTable (so it cannot be IList or something other so when binding datasource first convert to datatable or modify this function a little)
Upvotes: 1