Datagridviewwidth/height消除灰色区域

Datagridview width/height to eliminate grey area

我正在尝试在表单上动态显示 datagridview 中的一些数据(以编程方式添加 DGV)。我几乎尝试了所有属性组合,但无法消除右侧和底部的灰色区域。

这是我在表单加载时设置的属性

With dgv
.DataSource = dTable
.Dock = DockStyle.None
.AllowUserToAddRows = False
.AllowUserToOrderColumns = False
.AllowUserToDeleteRows = False
.AllowUserToResizeColumns = False
.AllowUserToResizeRows = False
.EditMode = DataGridViewEditMode.EditProgrammatically
.RowHeadersVisible = False
.DefaultCellStyle.WrapMode = False
.ColumnHeadersVisible = True
.SelectionMode = DataGridViewSelectionMode.CellSelect
.MultiSelect = True
.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
.BorderStyle = BorderStyle.None
.ColumnHeadersDefaultCellStyle.Font = New Font("Segoe UI", 8)
.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing
width = 0
For i As Integer = 0 To .ColumnCount - 1
  .Columns(i).DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopLeft
  .Columns(i).SortMode = DataGridViewColumnSortMode.NotSortable
  .Columns(i).DefaultCellStyle.Font = New Font("Segoe UI", 8)
  width += .Columns(i).Width
Next i
.AutoResizeColumns()
.AutoResizeRows()
Dim height As Integer = .ColumnHeadersHeight
For i As Integer = 0 To .Rows.Count - 1
  height += .Rows(i).Height
  .Rows(i).Resizable = False
Next i
.AutoSize = True
.Width = width
.Height = height - 8
end width

有什么解决问题的建议吗?

O.K 所以我使用的是调整 datagridview 的大小: DataGridView1.Width = colwidth + DataGridView1.RowHeadersWidth

正如我评论的那样,我认为 DataGridView 没有“built-in”机制来自动调整行的大小以“填充”网格高度。我可能弄错了,但是,我相信您需要逐行设置行高。我看到的所有例子都在我的测试中失败了。显然我可能做错了,但是,我觉得在网格填充数据后粗略地“计算”行高应该不会太难。

对于总行数总是小于网格高度的网格,下面的代码应该可以填充网格高度并移除底部的“灰色”区域。

如果网格中有许多行已经填满或超出了网格高度,那么下面的代码将调整行的大小,使这些行应该均匀地适合(或接近适合)网格行区域。换句话说,它不应该在行的中间“砍掉”最后一行,它应该紧贴网格的底部。

获取行高可能类似于……

Dim rowHeightDouble As Double = (dgv.Height - dgv.ColumnHeadersHeight) / dgv.DisplayedRowCount(False)
Dim rowHeight As Int32 = CInt(Int(rowHeightDouble))
For Each row As DataGridViewRow In dgv.Rows
  row.Height = rowHeight
  row.MinimumHeight = rowHeight
Next

rowHeight 的计算方法是用网格的高度减去列 header 的高度,然后将该数字除以网格中“显示”的行数。然后我们遍历所有行并设置每一行的高度。

注意:很明显,这种从显示行数中得到rowHeight的划分可能并没有平均划分到网格的高度。示例:假设网格的行区域高度为 188,那么……如果有 9 行显示……那么,除法后 (188 / 9 = 20.88) 表示行高为 20,余数为 8。所以这将显示 8最后一行下方的“灰色”像素 space。

因此,为了让行尽可能靠近网格底部而不显示垂直滚动条,我们可以在网格的最后一行添加 8 个像素以消除“灰色” “ 区域。显然,您也可以在前 8 行添加 1 个像素,但我采取了偷懒的方式,将其全部添加到最后一行。这可能看起来像……

If (dgv.Rows.Count = dgv.DisplayedRowCount(False)) Then
  Dim lastRowBuff As Int32 = CInt(Int((dgv.Height - dgv.ColumnHeadersHeight) - (rowHeight * dgv.DisplayedRowCount(False))))
  dgv.Rows(dgv.DisplayedRowCount(False) - 1).Height = rowHeight + lastRowBuff
End If

我希望这是有道理的并且有所帮助。使用您发布的代码,我将网格 AutoSizeColumnsMode 更改为…

.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill

然后我在第一个 for 循环后转储所有内容并用上面的代码替换它。

With dgv
  .DataSource = dTable
  .Dock = DockStyle.None
  .AllowUserToAddRows = False
  .AllowUserToOrderColumns = False
  .AllowUserToDeleteRows = False
  .AllowUserToResizeColumns = False
  .AllowUserToResizeRows = False
  .EditMode = DataGridViewEditMode.EditProgrammatically
  .RowHeadersVisible = False
  .DefaultCellStyle.WrapMode = DataGridViewTriState.False
  .ColumnHeadersVisible = True
  .SelectionMode = DataGridViewSelectionMode.CellSelect
  .MultiSelect = True
  '.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
  .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
  .AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells
  .BorderStyle = BorderStyle.None
  .ColumnHeadersDefaultCellStyle.Font = New Font("Segoe UI", 8)
  .ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing
  'Width = 0
  For i As Integer = 0 To .ColumnCount - 1
    .Columns(i).DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopLeft
    .Columns(i).SortMode = DataGridViewColumnSortMode.NotSortable
    .Columns(i).DefaultCellStyle.Font = New Font("Segoe UI", 8)
    'Width += .Columns(i).Width
  Next i
  Dim rowHeightDouble As Double = (dgv.Height - dgv.ColumnHeadersHeight) / dgv.DisplayedRowCount(False)
  Dim rowHeight As Int32 = CInt(Int(rowHeightDouble))
  For Each row As DataGridViewRow In dgv.Rows
    row.Height = rowHeight
    row.MinimumHeight = rowHeight
  Next
  If (dgv.Rows.Count = dgv.DisplayedRowCount(False)) Then
    Dim lastRowBuff As Int32 = CInt(Int((dgv.Height - dgv.ColumnHeadersHeight) - (rowHeight * dgv.DisplayedRowCount(False))))
    dgv.Rows(dgv.DisplayedRowCount(False) - 1).Height = rowHeight + lastRowBuff
  End If
End With