データグリッドビューの色分けについて への返答

投稿で使用できる特殊コードの説明。(別タブで開きます。)
本名は入力しないようにしましょう。
投稿した後で削除するときに使うパスワードです。返答があった後は削除できません。
返答する人が目安にします。相手が小学生か社会人かで返答の仕方も変わります。
最初の投稿が質問の場合、質問者が解決時にチェックしてください。(以降も追加書き込み・返信は可能です。)
※「過去ログ」について書くときはその過去ログのURLも書いてください。

以下の返答は逆順(新しい順)に並んでいます。

投稿者 河童  (社会人) 投稿日時 2014/1/2 10:29:51
おはようございます。
結果報告を忘れて、お返事が2年以上かかってしまいました。
申し訳ありませんでした。
魔界の仮面弁士さん、アドバイスありがとうございました。

(案1)2行で1レコードとするのではなく、1行内に2行分のデータを独自に描画する
という方法を取って現在もPGを使用しています。

社内ではACCESSを使うことが多いので、
私のVBのレベルはなかなか上がりません。

今年は、VBをがんばりたいです。
VBの参考書を見ながら、サンプルを作っています。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2011/11/17 02:36:50
行選択も2行1組単位で行わせるのだとすれば、
 (案1)2行で1レコードとするのではなく、1行内に2行分のデータを独自に描画する。
 (案2)行が選択されたタイミングで、隣の行の背景色を変更する。
 (案3)行が選択されたタイミングで、隣の行も一緒に選択させるようにする。
といった対処方法が思いあたります。

細かい動作チェックやパフォーマンス測定は行っていませんが、参考になれば。

'案2:隣接行の拝啓 
Public Class Form1
    Private WithEvents dgv As DataGridView

    Private Sub Form1_Load(ByVal sender As ObjectByVal e As EventArgs) Handles Me.Load
        dgv = New DataGridView()
        dgv.AllowUserToAddRows = False
        'dgv.EditMode = DataGridViewEditMode.EditOnEnter 
        dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect
        dgv.ColumnCount = 5
        dgv.RowCount = 100
        dgv.Dock = DockStyle.Fill
        Controls.Add(dgv)
    End Sub

    Private Sub dgv_CellFormatting(ByVal sender As Object
             ByVal e As DataGridViewCellFormattingEventArgs) Handles dgv.CellFormatting
        If e.RowIndex < 0 OrElse e.ColumnIndex < 0 Then
            Return
        End If

        Dim pos As Point = dgv.CurrentCellAddress
        Dim recordRows As New List(Of Integer)() From {pos.Y, pos.Y + If(pos.Y Mod 2 = 0, 1, -1)}
        If recordRows.Contains(e.RowIndex) Then
            e.CellStyle.BackColor = If((e.RowIndex \ 2) Mod 2 = 0, Color.LightGreen, Color.Khaki)
        Else
            e.CellStyle.BackColor = If((e.RowIndex \ 2) Mod 2 = 0, Color.GreenYellow, Color.Yellow)
        End If
        e.CellStyle.SelectionBackColor = e.CellStyle.BackColor
    End Sub

    Private Sub dgv_RowEnter(ByVal sender As ObjectByVal e As DataGridViewCellEventArgs) Handles dgv.RowEnter
        dgv.Invalidate()
    End Sub
End Class



'案3 
Public Class Form1
    Private WithEvents dgv As DataGridView

    Private Sub Form1_Load(ByVal sender As ObjectByVal e As EventArgs) Handles Me.Load
        dgv = New DataGridView()
        dgv.AllowUserToAddRows = False
        'dgv.EditMode = DataGridViewEditMode.EditOnEnter 
        dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect
        dgv.ColumnCount = 5
        dgv.RowCount = 100
        dgv.MultiSelect = True
        dgv.Dock = DockStyle.Fill
        dgv.DefaultCellStyle.BackColor = Color.Yellow
        dgv.DefaultCellStyle.SelectionBackColor = Color.Khaki
        Controls.Add(dgv)
    End Sub

    Private Sub dgv_CellFormatting(ByVal sender As Object, _
             ByVal e As DataGridViewCellFormattingEventArgs) Handles dgv.CellFormatting
        If e.RowIndex >= 0 AndAlso (e.RowIndex \ 2) Mod 2 = 0 Then
            e.CellStyle.BackColor = Color.GreenYellow
            e.CellStyle.SelectionBackColor = Color.LightGreen
        End If
    End Sub

    Private Sub dgv_RowEnter(ByVal sender As Object, _
            ByVal e As DataGridViewCellEventArgs) Handles dgv.RowEnter
        Dim pairRow As Integer = e.RowIndex + If(e.RowIndex Mod 2 = 0, 1, -1)
        dgv.ClearSelection()
        dgv.Rows(e.RowIndex).Selected = True
        dgv.Rows(pairRow).Selected = True
    End Sub
End Class



> しかし、レコードを選択したときの偶数行のとき背景色が変わりません。
各行の SelectionBackColor および BackColor の設定を見直してみては如何でしょう。
投稿者 河童  (社会人) 投稿日時 2011/11/16 23:41:14
こんばんは。
魔界の仮面弁仕さん、お返事ありがとうございます。

経費削減のため、素人ながら既存のプログラムを修正しています。
VB2008についてはまだまだ勉強不足です。

教えて頂いたコードで試しました。
すると2行1レコードごとに色分けすることが出来ました。
しかし、レコードを選択したときの偶数行のとき背景色が変わりません。
レコード:3件(A、B、C)
行数
1       レコードA黄色 
2       レコードA黄色
3       レコードB緑色
4       レコードB緑色
5       レコードC黄色
6       レコードC黄色

既存のプログラムだと
dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect
が設定されていて、
行数1のセルを選択すると、
行数の1と2が選択されて背景色が青色に変わります。
これが背景色が変わらない原因だと思います。

私はまだこの部分のコードがわかっていないので、
調べてみます。

また質問させてください。
投稿者 魔界の仮面弁士  (社会人) 投稿日時 2011/11/16 19:48:40
いろいろな方法がありますが、一例として。

Public Class Form1
    Private WithEvents dgv As DataGridView

    Private Sub Form1_Load(ByVal sender As ObjectByVal e As EventArgs) Handles Me.Load
        dgv = New DataGridView()
        dgv.AllowUserToAddRows = False
        'dgv.EditMode = DataGridViewEditMode.EditOnEnter 
        dgv.ColumnCount = 5
        dgv.RowCount = 100
        dgv.Dock = DockStyle.Fill
        dgv.DefaultCellStyle.BackColor = Color.Yellow
        dgv.DefaultCellStyle.SelectionBackColor = Color.Khaki
        Controls.Add(dgv)
    End Sub

    Private Sub dgv_CellFormatting(ByVal sender As Object, _
            ByVal e As DataGridViewCellFormattingEventArgs) Handles dgv.CellFormatting
        If e.RowIndex >= 0 AndAlso (e.RowIndex \ 2) Mod 2 = 0 Then
            e.CellStyle.BackColor = Color.GreenYellow
            e.CellStyle.SelectionBackColor = Color.LightGreen
        End If
    End Sub
End Class



上記のほか、「dgv.Rows( 行位置 ).DefaultCellStyle」をループ処理でセットするという方法もあります。
(ただしこの場合、ソート機能を使う場合は、並び替え処理後にスタイルの再セットが必要です)

あるいはスタイルを使う代わりに、RowPrePaint イベントに背景の描画処理を記述することも
できます。(この方法は、背景色をグラデーション表示させたい場合などに適しています)
投稿者 河童  (社会人) 投稿日時 2011/11/16 18:18:30
こんばんは。
いつも大変お世話になっております。

データグリッドビューで一覧を表示させています。
その一覧でレコードごとに色分けをしたいと思っています。

困っていることは、2行で1レコードになっているので、
1レコード内で色分けがされていることです。

やりたいことは、
2行1レコードで色分けをすることです。
例えば、
行数  背景色 
1       黄色
2       黄色
3       緑色
4       緑色
5       黄色
6       黄色

現在のコード(VB2008)は、
一覧を全てのセルを黄色にした後に、
奇数行を緑色に設定しています。

'色分け
'すべてのセルを背景色
wdgvHyoji.DefaultCellStyle.BackColor = Color.Yellow 
'奇数行のセルの背景色
wdgvHyoji.AlternatingRowsDefaultCellStyle.BackColor = Color.GreenYellow

わからないことは、
1,2行は黄色に設定して、3,4行は緑色に設定するため、
どのように繰り返し処理をすればよいでしょうか?
レコード数は何件あるかは状況によって異なります。

アドバイスの程、よろしくお願い致します。