VB2008のDataGridViewで表を作成したいと思っています。
表の左側の列に大分類があり、その右側に小分類の情報を表示したいと思っています。
この大分類が同じものが複数続くときには複数分の大分類を各行に表示せず、
Excelでいうセル結合をしてひとかたまりにして表示できればいいのですが、
色々検索しても方法が見つかりませんでした。
(DataGridが上記のようなことができないという記事は見つかったのですが。)
もしDataGridViewで上記のようなことが可能であれば、教えて頂きたいのですが、
宜しくお願いいたします。
こういう感じでよいのかな。
Public Class Form1
Private tbl As New DataTable()
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
tbl.Columns.Add("大分類", GetType(Integer))
tbl.Columns.Add("小分類", GetType(Integer))
tbl.Rows.Add(100, 1)
tbl.Rows.Add(100, 2)
tbl.Rows.Add(100, 3)
tbl.Rows.Add(200, 10)
tbl.Rows.Add(200, 15)
tbl.Rows.Add(300, 100)
tbl.Rows.Add(400, 1)
tbl.Rows.Add(400, 2)
tbl.Rows.Add(400, 3)
DataGridView1.DataSource = tbl
End Sub
Private Sub DataGridView1_CellPainting(ByVal sender As Object, ByVal e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
e.Handled = False
If e.ColumnIndex <> 0 OrElse e.RowIndex < 0 Then
Return '[大分類]列でなければ何もしない
ElseIf DataGridView1.Rows(e.RowIndex).IsNewRow Then
Return '新規行の時も何もしない
End If
'現在行の大分類値
Dim C As Object = DataGridView1(0, e.RowIndex).Value
'上の行の大分類値
Dim U As Object = Nothing
If e.RowIndex > 0 Then
U = DataGridView1(0, e.RowIndex - 1).Value
End If
'下の行の大分類値
Dim B As Object = Nothing
If e.RowIndex < DataGridView1.Rows.Count - 1 Then
B = DataGridView1(0, e.RowIndex + 1).Value
End If
'現在行=下の行なら、現在行の下枠線を消す
If Integer.Equals(C, B) Then
e.AdvancedBorderStyle.Bottom = DataGridViewAdvancedCellBorderStyle.None
End If
'現在行=上の行なら、現在行のテキストを消す
If Integer.Equals(C, U) Then
Dim selected As Boolean = CBool(e.State And DataGridViewElementStates.Selected)
e.PaintBackground(e.CellBounds, selected)
e.Handled = True
End If
End Sub
Private Sub DataGridView1_CellValueChanged(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
If e.ColumnIndex = 0 OrElse e.RowIndex > 0 Then
'大分類の値が変更された場合、上の行の大分類列を再描画して、
'枠線の表示/非表示が反映されるようにする
DataGridView1.InvalidateCell(0, e.RowIndex - 1)
End If
End Sub
End Class
魔界の仮面弁士様、ありがとうございました。
質問ですが、DataGridView1_CellPaintingイベント処理で、
最初の行でe.Handled = Falseとし、
最後のIf文でe.Handled = Trueとしていますが、
これは何か理由があるのでしょうか?
(そもそもe.Handledがどのような効果があるのか理解できておりません。。。)
教えて頂きたく、宜しくお願いいたします。
> 魔界の仮面弁士様、ありがとうございました。
期待する結果になっていましたか?
> そもそもe.Handledがどのような効果があるのか理解できておりません。。。
ユーザー定義描画を行った場合、Handled を True にします。
既定の描画処理に任せる場合は False です。
それと、最後のイベント部分を下記のように差し替えておいてください。
Private Sub DataGridView1_CellValueChanged(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
If e.ColumnIndex = 0 Then
'大分類の値が変更された場合、前後の行の大分類列を再描画して、
'枠線の表示/非表示が反映されるようにする
If e.RowIndex > 0 Then
DataGridView1.InvalidateCell(0, e.RowIndex - 1)
End If
Dim maxRowIndex As Integer = DataGridView1.Rows.Count - 1
If e.RowIndex < maxRowIndex Then
DataGridView1.InvalidateCell(0, e.RowIndex + 1)
End If
End If
End Sub
ツイート | ![]() |