C#: DataGridView's extra space on right-hand side and scrollbar

回眸只為那壹抹淺笑 提交于 2019-12-11 07:24:38

问题


I have a DataGridView control, and the number of columns changes depending on the input from the user every 10 minutes. What needs to be achieved is:

  1. The DataGridView needs to show all columns without a horizontal scrollbar unless it affects the readability of any cell contents. If it starts hiding a cell content, a horizontal scrollbar needs to appear.
  2. Regardless of how many columns are currently shown, and regardless of whether the horizontal scrollbar is shown or not, the right-hand side of the DataGridView's data must be filled so there is no unused space.
  3. Regardless of the length of the cell contents, all of the column widths need to be the same. (A cell can have an integer from 10 up to 9999)

All of these 3 requirements need to be satisfied at the same time, but if I try to meet one requirement, the other(s) falls apart. I know for sure that there are always at least 16 columns no matter what. It is really up to the user if there will be more columns or not.

Can someone tell me what is wrong with the following?

int countVisible = 0; //Count the number of columns displayed
foreach(DataGridViewColumn col in myDGV.Columns)
    if(col.Visible) countVisible++;

//By default, use Fill mode
DataGridViewAutoSizeColumnMode mode = DataGridViewAutoSizeColumnMode.Fill;

//I am trying to show up to 20 columns without a scrollbar
//A horizontal scrollbar required for more than 20 columns
//If there are more than 20 columns, use DisplayedCells mode
if(countVisible > 20)
    mode = DataGridViewAutoSizeColumnMode.DisplayedCells;

//Apply the mode to all columns
for(int i = 0; i < myDGV.Columns.Count; i++)
    myDGV.Columns[i].AutoSizeMode = mode;  

This code works if the number of columns is less than a certain value, but in the case of greater than the certain value, it shrinks the width of columns that only have 2-digit numbers in all rows, and it violates the requirement #3. By shrinking some column widths, it creates extra space on the right-hand side, and it violates the requirement #2.

I am so lost and stuck. Can someone please help? Any advice will be greatly appreciated.


回答1:


The requirements appear to be somewhat obscure to me. One issue would be requirement 3…

”3. Regardless of the length of the cell contents, all of the column widths need to be the same. (A cell can have an integer from 10 up to 9999)”

If ALL columns have to be the same width and at least ONE (1) cell has a value of “9999” then ALL the columns will be this width regardless of how many digits it has.

It does appear a requirement is to have all the data display in a cell, in addition… have all the columns the same width. This will require going through each cell and find the cell with the largest width to display all its data and make ALL columns this width to keep with the previous requirement.

The point being, that requiring all the columns to be the same size AND make sure ALL the contents of every cell is displayed leaves little to question… Each column will have to be the width of the largest value. Any other situation will break one of the requirements.

Assuming the above is correct, the other requirement

”2. Regardless of how many columns are currently shown, and regardless of whether the horizontal scrollbar is shown or not, the right-hand side of the DataGridView's data must be filled so there is no unused space.”

I am confident YOU will have to control this. Unfortunately, the grids column “Fill” property will gladly cram a hundred columns into a small space. This suggest that you will have to get the grids displayed width, count how many columns there are, find the width for the columns and check to see if it fits in the grids display.

This implies a MINIMUM value for a columns width. If each columns width is set to a minimum value AND the total width from all columns is greater than the grids width, then obviously you are going to need a horizontal scroll bar.

Given this, to find the total width of all the columns is easy enough. If this value is greater than the grids width, then the horizontal scroll bar will appear automatically, nothing else needs to be done unless you want to avoid the possible splitting of a column which would most likely involve resizing the grid. If the total width of the columns is less than the grids width… then simply set the columns to fill. Below is an example.

A global variable minWidth is used to ensure all columns are at least this value. This is a value you could get some other way; in this case, its purpose is to set a columns minimum width.

First, a check is made to see if the width is less than the minimum and if so set it to the minimum. Next, set each columns width to the given value. Finally check to see if the total width of all columns is greater than the grids width. If the columns will not fit in the grids width then simply set the grid to DisplayedCells and the horizontal scroll bar will pop up. .If the columns do fit, then simply set the grids AutoColumnSizeMode to Fill. Hope this helps.

int minWidth = 40;

private int YourMethodToGetColumnWidth() {
  return myDGV.Width / myDGV.Columns.Count;
}

private void SetColumnWidths() {
  int columnWidth = YourMethodToGetColumnWidth();
  if (columnWidth < minWidth)
    columnWidth = minWidth;
  foreach (DataGridViewColumn col in myDGV.Columns)
    col.Width = columnWidth;
  int allColumnsWidth = columnWidth * myDGV.Columns.Count;
  if (allColumnsWidth > myDGV.Width) {
    myDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
  }
  else {
    myDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
  }
}



回答2:


I read your interesting question yesterday. Thinking about it, in my opinion the best solution is to get rid of AutoSizeMode at all and create a variable ColMinWidth for a minimum width of a column. Then get DataGridView.Width and divide it by the number of required columns (with a little tweak, perhaps 2px less). If the calculated width of the column is greater then ColMinWidth, then this will be a width of the column, otherwise use ColMinWidth. Finally set that width to all columns.

I think that this is minimal solution and unlike AutoSize with hidden catches, reliable.



来源:https://stackoverflow.com/questions/46777399/c-datagridviews-extra-space-on-right-hand-side-and-scrollbar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!