This demonstration program has a form with a DataGridView drawn on it
I have filled the DataGridView with some data
There are some answers here that suggest that one can calculate the total width of all the columns and add two, and then you have the smallest possible width for the DataGridView without getting scrollbars.
I am finding that in this situation, for some reason, that calculated width is too small, and scrollbars still exist.
After I give the datagridview its data, I then use these 3 lines.
fix_dgvw_efficientbutnotworking_wrongpadding();
dgvw stands for datagridview width.
That method uses the answer mentioned by "BOS" fit dataGridView size to row's and columns's total size However, it doesn't seem to be working in this case.
By the way, interestingly, if the datagridview only has one line of data, then BOS's method works, the padding is then two. But anyhow, i'm interested in this case, where the datagridview has 2 lines of data.. and the method doesn't work, since the padding isn't two.
You can see visually(particularly if you stop here and just comemnt out the next two lines), you see at this point, the datagridview has scroll bars.
MessageBox.Show(test_if_horizontal_scrollbars().ToString());
This messagebox from the line above, says True, to indocate that there are horizontal scroll bars.
MessageBox.Show(fix_dgvw_inefficientbutworks().ToString());
The line above runs a method that rather inefficiently, keeps increasing the width of the datagridview until there are no more scrollbars. It does first use BOS's method which gets the width to a decent width, but sometimes there are still scrollbars, as is the case here, and so that method will increase the width one increment at a time, until there are no more horizontal scroll bars.
In this case we see that the padding had to be increased another 15 times, we see the messagebox shows 15. But this seems like a very inefficient way of finding out and fixing it.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace paddingfind
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//dimensions of one i drew though this doesn't matter
//dataGridView1.Width = 240;
//dataGridView1.Height = 150;
dataGridView1.AllowUserToAddRows = false;
dataGridView1.ColumnHeadersDefaultCellStyle.Font = new System.Drawing.Font("Courier New", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
for (int i = 0; i < dataGridView1.Rows.Count; i++)
dataGridView1.Rows[i].DefaultCellStyle.Font = new Font("Courier New", 30, FontStyle.Bold);
//https://stackoverflow.com/questions/9507614/is-it-possible-to-prevent-a-multi-line-headertext-in-a-datagridview
dataGridView1.ColumnHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.False;
List<List<string>> colHeaders = new List<List<string>>();
colHeaders.AddRange(new[]
{
new List<string> {"Column1","Column1"},
});
List<List<string>> lst = new List<List<string>>();
lst.AddRange(new[]
{
new List<string> { "abc"},
new List<string> {"abc"}
});
AddColumns(colHeaders);
dataGridView1.Rows.Add(lst.Count);
dataGridView1.ColumnHeadersDefaultCellStyle.Font = new System.Drawing.Font("Courier New", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView1.Font = new Font("Courier New", 30, FontStyle.Bold);
for (int i = 0; i < lst.Count; i++)
dataGridView1.Rows[i].Cells[0].Value = lst.ElementAt(i).ElementAt(0);
fix_dgvw_efficientbutnotworking_wrongpadding();
MessageBox.Show(test_if_horizontal_scrollbars().ToString());
MessageBox.Show(fix_dgvw_inefficientbutworks().ToString());
}
private void AddColumns(List<List<string>> colHeaders)
{
for (int i = 0; i < colHeaders.Count; i++)
dataGridView1.Columns.Add(colHeaders[i][0], colHeaders[i][1]);
}
private bool test_if_horizontal_scrollbars()
{
foreach (var scroll in dataGridView1.Controls.OfType<HScrollBar>())
if (scroll.Visible) return true;
return false;
}
private void fix_dgvw_efficientbutnotworking_wrongpadding()
{
// it's not too bad, it sometimes makes it the correct width and sometimes not quite enough, and so it's worth then running the next method that increments the width until there are no more horizontal scroll bars.
int padding = 2; // clearly wrong here, it seems
int tw = dataGridView1.Columns.GetColumnsWidth(DataGridViewElementStates.None) + dataGridView1.RowHeadersWidth + padding;
int th = dataGridView1.Rows.GetRowsHeight(DataGridViewElementStates.None) + dataGridView1.ColumnHeadersHeight;
dataGridView1.Width = tw;
}
private int fix_dgvw_inefficientbutworks()
{
// not that inefficient when you run the above method first
int minpadding = 2; //min or at least the min that default can possibly be
int tw = dataGridView1.Columns.GetColumnsWidth(DataGridViewElementStates.None) + dataGridView1.RowHeadersWidth + minpadding + 2;
int th = dataGridView1.Rows.GetRowsHeight(DataGridViewElementStates.None) + dataGridView1.ColumnHeadersHeight;
//int dgvw = dgv.Width;
//int dgvh = dgv.Height;
dataGridView1.Width = tw;
int count = 0;
while (true)
{
bool done = false;
foreach (var scroll in dataGridView1.Controls.OfType<HScrollBar>())
if (scroll.Visible) { dataGridView1.Width += 1; count++; } else done = true;
if (done == true) break;
}
return count; // not important to return coutn but anyhow.
}
}
}
See Question&Answers more detail:
os