データグリッドビューの色分けについて への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2011/11/17 02:36:50
行選択も2行1組単位で行わせるのだとすれば、
(案1)2行で1レコードとするのではなく、1行内に2行分のデータを独自に描画する。
(案2)行が選択されたタイミングで、隣の行の背景色を変更する。
(案3)行が選択されたタイミングで、隣の行も一緒に選択させるようにする。
といった対処方法が思いあたります。
細かい動作チェックやパフォーマンス測定は行っていませんが、参考になれば。
> しかし、レコードを選択したときの偶数行のとき背景色が変わりません。
各行の SelectionBackColor および BackColor の設定を見直してみては如何でしょう。
(案1)2行で1レコードとするのではなく、1行内に2行分のデータを独自に描画する。
(案2)行が選択されたタイミングで、隣の行の背景色を変更する。
(案3)行が選択されたタイミングで、隣の行も一緒に選択させるようにする。
といった対処方法が思いあたります。
細かい動作チェックやパフォーマンス測定は行っていませんが、参考になれば。
'案2:隣接行の拝啓
Public Class Form1
Private WithEvents dgv As DataGridView
Private Sub Form1_Load(ByVal sender As Object, ByVal 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 Object, ByVal 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 Object, ByVal 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が選択されて背景色が青色に変わります。
これが背景色が変わらない原因だと思います。
私はまだこの部分のコードがわかっていないので、
調べてみます。
また質問させてください。
魔界の仮面弁仕さん、お返事ありがとうございます。
経費削減のため、素人ながら既存のプログラムを修正しています。
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
いろいろな方法がありますが、一例として。
上記のほか、「dgv.Rows( 行位置 ).DefaultCellStyle」をループ処理でセットするという方法もあります。
(ただしこの場合、ソート機能を使う場合は、並び替え処理後にスタイルの再セットが必要です)
あるいはスタイルを使う代わりに、RowPrePaint イベントに背景の描画処理を記述することも
できます。(この方法は、背景色をグラデーション表示させたい場合などに適しています)
Public Class Form1
Private WithEvents dgv As DataGridView
Private Sub Form1_Load(ByVal sender As Object, ByVal 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行は緑色に設定するため、
どのように繰り返し処理をすればよいでしょうか?
レコード数は何件あるかは状況によって異なります。
アドバイスの程、よろしくお願い致します。
いつも大変お世話になっております。
データグリッドビューで一覧を表示させています。
その一覧でレコードごとに色分けをしたいと思っています。
困っていることは、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行は緑色に設定するため、
どのように繰り返し処理をすればよいでしょうか?
レコード数は何件あるかは状況によって異なります。
アドバイスの程、よろしくお願い致します。
結果報告を忘れて、お返事が2年以上かかってしまいました。
申し訳ありませんでした。
魔界の仮面弁士さん、アドバイスありがとうございました。
(案1)2行で1レコードとするのではなく、1行内に2行分のデータを独自に描画する
という方法を取って現在もPGを使用しています。
社内ではACCESSを使うことが多いので、
私のVBのレベルはなかなか上がりません。
今年は、VBをがんばりたいです。
VBの参考書を見ながら、サンプルを作っています。