bigLiBox

備忘録だったり。読書メモだったり。ところで仕事が終わりそうにないんですが。

DataGridViewの列幅を内容に合わせ、かつ最後の列はコントロール幅に合わせる

以下のようなDataGridViewを表示したい。

  1. 列幅は可変
  2. 初期表示時の列幅はヘッダーセルを含むすべてのセルの内容に合わせて調整する
  3. セルの内容に合わせた時、すべての列を合わせた幅がDataGridViewの幅(垂直スライドバーの部分除く)より短い場合、背景色見えるのかっこ悪いので最後の列の幅を広げて調整する(※でもその列も表示した後は列幅可変)
  4. すべての列がReadOnly

f:id:bigLiBox:20160928185235p:plain

3.の条件を実現するのがなんかややこしかった。

'日時
Dim txtDataTime As New DataGridViewTextBoxColumn()
txtDataTime.HeaderText = "日時"
txtDataTime.Name = "txtDataTime"
txtDataTime.ReadOnly = True
dgvInformation.Columns.Add(txtDataTime)

'メッセージID
Dim txtMessageID As New DataGridViewTextBoxColumn()
txtMessageID.HeaderText = "メッセージID"
txtMessageID.Name = "inputDataCheckInfo_MessageID"
txtMessageID.ReadOnly = True
dgvInformation.Columns.Add(txtMessageID)

'行
Dim txtColumn As New DataGridViewTextBoxColumn()
txtColumn.HeaderText = "行"
txtColumn.Name = "txtColumn"
txtColumn.ReadOnly = True
dgvInformation.Columns.Add(txtColumn)

'列
Dim txtRow As New DataGridViewTextBoxColumn()
txtRow.HeaderText = "列"
txtRow.Name = "txtColumn"
txtRow.ReadOnly = True
dgvInformation.Columns.Add(txtRow)

'メッセージ
Dim txtMessage As New DataGridViewTextBoxColumn()
txtMessage.HeaderText = "メッセージ"
txtMessage.Name = "txtMessage"
txtMessage.ReadOnly = True
dgvInformation.Columns.Add(txtMessage)

'ユーザーが列の幅を変更できる
dgvInformation.AllowUserToResizeColumns = True

Dim index As Integer

dgvInformation.Rows.Add()
index = dgvInformation.RowCount - 1
dgvInformation.Rows(index).Cells(0).Value = "2016/07/13 11:43:26"
dgvInformation.Rows(index).Cells(1).Value = "E0001"
dgvInformation.Rows(index).Cells(2).Value = "2"
dgvInformation.Rows(index).Cells(3).Value = "列番号4"
dgvInformation.Rows(index).Cells(4).Value = "必須項目が入力されていません。"

dgvInformation.Rows.Add()
index = dgvInformation.RowCount - 1
dgvInformation.Rows(index).Cells(0).Value = "2016/07/13 11:43:26"
dgvInformation.Rows(index).Cells(1).Value = "E0001"
dgvInformation.Rows(index).Cells(2).Value = "3"
dgvInformation.Rows(index).Cells(3).Value = "列番号1"
dgvInformation.Rows(index).Cells(4).Value = "必須項目が入力されていません。"

dgvInformation.Rows.Add()
index = dgvInformation.RowCount - 1
dgvInformation.Rows(index).Cells(0).Value = "2016/07/13 11:43:26"
dgvInformation.Rows(index).Cells(1).Value = "E0002"
dgvInformation.Rows(index).Cells(2).Value = "3"
dgvInformation.Rows(index).Cells(3).Value = "列番号8"
dgvInformation.Rows(index).Cells(4).Value = "半角英数字以外の文字が入力されています。"

'一旦、列幅をヘッダーセルを含む列内のすべてのセルの内容に合わせて調整
dgvInformation.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells)

'表示列の幅を取得する
Dim allWidth As Integer = dgvInformation.Columns.GetColumnsWidth(DataGridViewElementStates.Visible)

If allWidth <= dgvInformation.Width - SystemInformation.VerticalScrollBarWidth Then
    '表示されているすべての列幅がデータグリッドビュー幅より狭い場合、最後の列幅を広げる
    dgvInformation.Columns.GetLastColumn(DataGridViewElementStates.Visible, Nothing).Width =
        dgvInformation.Width -
        (allWidth -
        dgvInformation.Columns.GetLastColumn(DataGridViewElementStates.Visible, Nothing).Width +
        SystemInformation.VerticalScrollBarWidth)
End If

とりあえず時間ないのでコードだけ記録。

ちなみに列幅がDataGridViewの幅を超える場合は最後の列の幅はセル内容に合わせた幅になる。
f:id:bigLiBox:20160928190806p:plain

参考: