tell me the best way to get column width for a data gridview with padding?

Unfortunately, the out of the box DataGridView is not overly sophisticated when using the “auto size” option for the columns. Example, if you set the “grids” AutoSizeColumnsMode to Fill, it will obligingly cram 100 columns into a very small space.

In addition, things get more complicated when there are two (2) different AutoSizeColumn properties. The DataGridViewAutoSizeColumnsMode which can be used on the “GRID.” In addition to the DataGridViewAutoSizeColumnMode which can be used on the individual “COLUMNS”. NOTE: the difference with the missing “s” (Column) on the latter.

This can cause some confusion. Example in the case you are describing above, if you set the “grids” DataGridViewAutoSizeColumnsMode to .AllCells… then the grid will set each column to a specific width depending on what is displayed in the cells. If possible, the grid will determine the columns width based on the longest line of text in that column, including the header. This will override any individual column width setting. This is why, changing the “individual” columns width has no effect when the “grids” auto column size mode is set to AllCells.

My understanding is that the “individual” setting for each column will “override” the grids setting if there is a conflict. If the columns AutoSizeMode is NOT set, then the grids settings will apply. This comes from the documentation, however as seen from your question, this is not necessarily always the case. This will often depend on what the “GRIDS” auto column size setting is.

I have found that dropping the “GRIDS” auto column feature and instead setting “each” individual column to a specific auto size mode appears to work in a more intuitive manner. Granted it is more work, however, it gives you more control over the widths of the columns.

Therefore, the approach I have used in the past… assuming the columns “will” fit in the grid’s width, is to “fix” the column widths of the columns I want to be a particular width. Then to fill the grid, I will set one or two columns to “Fill.” This will pretty much guarantee the fixed width columns will NOT change and you can set the width to any valid value. However, the other non-fixed column widths may change.

Below is a full example of what is described above. There are five (5) columns. The inner three (3) columns are fixed widths and the outer columns are set to “fill.” Obviously, if you make all columns with a fixed width, then there may be a gap at the end and not fill the grids width. To fill the grid, at least one (1) column must be set to “Fill.”

enter image description here

Considering, your last question involved getting the columns to set the DataPropertyName, it seems appropriate to add these additional properties to that method. I may look like below…

private DataGridViewTextBoxColumn GetColumnForGrid2(string colName, string colHeader, string dataPropertyName, int width, DataGridViewAutoSizeColumnMode mode) {
  DataGridViewTextBoxColumn dgvc = new DataGridViewTextBoxColumn();
  dgvc.Name = colName;
  dgvc.HeaderText = colHeader;
  dgvc.DataPropertyName = dataPropertyName;
  dgvc.AutoSizeMode = mode;
  dgvc.Width = width;
  return dgvc;
}

Then to complete the example from the picture above.

BindingList<MoviesSingleTable> MovieList;

private void Form1_Load(object sender, EventArgs e) {
  MovieList = GetData();
  DataGridViewColumn col = GetColumnForGrid2("MovieTitle", "Title", "MovieTitle", 40, DataGridViewAutoSizeColumnMode.Fill);
  dataGridView1.Columns.Add(col);
  col = GetColumnForGrid2("IMDBRating", "IMDB", "IMDBRating", 40, DataGridViewAutoSizeColumnMode.None);
  dataGridView1.Columns.Add(col);
  col = GetColumnForGrid2("MPAARating", "MPAA", "MPAARating", 40, DataGridViewAutoSizeColumnMode.None);
  dataGridView1.Columns.Add(col);
  col = GetColumnForGrid2("Duration", "Duration", "durationInMinutes", 40, DataGridViewAutoSizeColumnMode.None);
  dataGridView1.Columns.Add(col);
  col = GetColumnForGrid2("Year", "Year", "YearReleased", 35, DataGridViewAutoSizeColumnMode.Fill);
  dataGridView1.Columns.Add(col);
  dataGridView1.AutoGenerateColumns = false;
  dataGridView1.DataSource = MovieList;
}

Sample Data…

private BindingList<MoviesSingleTable> GetData() {
  BindingList<MoviesSingleTable> bl = new BindingList<MoviesSingleTable>();
  MoviesSingleTable mgdc = new MoviesSingleTable {
    MovieTitle = "The Princess Bride",
    IMDBRating = 8.1,
    MPAARating = "PG",
    durationInMinutes = 98,
    YearReleased = "1987",
    genres = "g",
    actors = "a",
    directors = "d",
    screenwriters = "s"
  };
  bl.Add(mgdc);

  mgdc = new MoviesSingleTable() {
    MovieTitle = "Will Penny",
    IMDBRating = 7.1,
    MPAARating = "PG-13",
    durationInMinutes = 108,
    YearReleased = "1967",
    genres = "",
    actors = "",
    directors = "",
    screenwriters = ""
  };
  bl.Add(mgdc);

  mgdc = new MoviesSingleTable() {
    MovieTitle = "2001 A Space Odysee",
    IMDBRating = 7.1,
    MPAARating = "NR",
    durationInMinutes = 108,
    YearReleased = "1967",
    genres = "",
    actors = "",
    directors = "",
    screenwriters = ""
  };
  bl.Add(mgdc);

  mgdc = new MoviesSingleTable() {
    MovieTitle = "The Gods Must Be Crazy",
    IMDBRating = 7.1,
    MPAARating = "PG",
    durationInMinutes = 108,
    YearReleased = "1967",
    genres = "",
    actors = "",
    directors = "",
    screenwriters = ""
  };
  bl.Add(mgdc);
  return bl;
}

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top