DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ListViewの概観のカスタマイズ

環境/言語:[XP / VB.NET]
分類:[.NET]

またお世話になります。

ListViewの背景色を
1行おき(交互)に指定した色にしたいのです。
また、
GridLineを縦方向にだけ(こちらも指定した色で)
表示させたいのです。

前回、教えていただいたことを応用して
考えているのですが煮詰まってしまいました。

よろしくお願いします。
すみません、タイトル
○外観
×概観
でした。
引き続き、お願いします。
補足です。
縞々の範囲は
データのない行も含められれば
理想的なのですが。

よろしくお願いします。
■No26351に返信(jacoさんの記事)
> 補足です。
> 縞々の範囲は
> データのない行も含められれば
> 理想的なのですが。
>
> よろしくお願いします。


こんにちは。

どうしてもListViewでしょうか?
DataGridViewの方が比較的楽時にカスタマイズできると思います。
ヴァンさん、ありがとうございます。

> どうしてもListViewでしょうか?
> DataGridViewの方が比較的楽時にカスタマイズできると思います。

見た目の問題といえばそれまでなのですが
データのない行の範囲も表示したいのです。
DataDridViewの場合はデータ以下は表示されないようなので。

引き続きアドバイスを
よろしくお願いします。
お疲れ様です。
試してみてください。

Public Class Form_ListViewTest2
    Inherits Form

    Dim ListView1 As New ListViewEx

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
        Me.Text = Me.GetType.Name
        With Me.ListView1
            .Dock = DockStyle.Fill
            .Columns.Add("列1")
            .Columns.Add("列2")
            .Columns.Add("列3")
            .Scrollable = True
            For i As Integer = 0 To 20
                .Items.Add(New ListViewItem( _
                    New String() {"値1−" + i.ToString, "値2−" + i.ToString, "値3−" + i.ToString}))
            Next
        End With
        Me.Controls.Add(Me.ListView1)

        MyBase.OnLoad(e)
    End Sub


    Private Class ListViewEx
        Inherits ListView

        Private _alternatingRowBackColor As Color = Color.MintCream
        Private _defaultBackColor As Color = Color.LightGreen
        Private _selectionBackColor As Color = Color.Orange

        Public Sub New()
            Me.View = View.Details
            Me.OwnerDraw = True
            Me.DoubleBuffered = True
        End Sub

        Protected Overrides Sub OnColumnWidthChanged(ByVal e As System.Windows.Forms.ColumnWidthChangedEventArgs)
            Me.Invalidate()
            MyBase.OnColumnWidthChanged(e)
        End Sub

        Protected Overrides Sub OnSelectedIndexChanged(ByVal e As System.EventArgs)
            Me.Invalidate()
            MyBase.OnSelectedIndexChanged(e)
        End Sub

        Protected Overrides Sub OnDrawColumnHeader(ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs)
            e.DrawDefault = True
            MyBase.OnDrawColumnHeader(e)
        End Sub

        Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawListViewItemEventArgs)
            Me._drawItemCore(e.Graphics, e.Item)
            MyBase.OnDrawItem(e)
        End Sub

        Protected Overrides Sub OnDrawSubItem(ByVal e As System.Windows.Forms.DrawListViewSubItemEventArgs)
            ' 何もしない
            MyBase.OnDrawSubItem(e)
        End Sub

        Private Sub _drawItemCore(ByVal g As Graphics, ByVal item As ListViewItem)
            Using br As New SolidBrush(Me._defaultBackColor)
                If item.Selected Then
                    br.Color = Me._selectionBackColor
                ElseIf item.Index Mod 2 = 1 Then
                    br.Color = Me._alternatingRowBackColor
                End If

                Dim rowbounds As Rectangle = Me._getRowBoundsCore(item.Bounds)
                g.FillRectangle(br, rowbounds)
                If item.Index = Me.Items.Count - 1 Then
                    Me._drawNonItemAreaBackGroundAndGridCore(g, item)
                End If
                For Each subitem As ListViewItem.ListViewSubItem In item.SubItems
                    Me._drawSubItemTextCore(g, subitem)
                Next
                Me._drawGridLinesCore(g, rowbounds)

            End Using
        End Sub

        Private Sub _drawNonItemAreaBackGroundAndGridCore(ByVal g As Graphics, ByVal lastitem As ListViewItem)
            Using br As New SolidBrush(Me._defaultBackColor)
                Dim rowbounds As Rectangle = Me._getRowBoundsCore(lastitem.Bounds)
                Dim rowindex As Integer = lastitem.Index
                Do
                    rowindex += 1
                    rowbounds.Offset(0, lastitem.Bounds.Height)
                    If rowbounds.Top > Me.ClientSize.Height Then Exit Do
                    If rowindex Mod 2 = 0 Then
                        br.Color = Me._defaultBackColor
                    Else
                        br.Color = Me._alternatingRowBackColor
                    End If
                    g.FillRectangle(br, rowbounds)
                    Me._drawGridLinesCore(g, rowbounds)
                Loop
            End Using
        End Sub

        Private Sub _drawGridLinesCore(ByVal g As Graphics, ByVal rowbounds As Rectangle)
            Dim x As Integer = 0
            For i As Integer = 0 To Me.Columns.Count - 1
                x += Me.Columns(i).Width
                g.DrawLine(SystemPens.ControlLight, x, rowbounds.Top, x, rowbounds.Bottom)
            Next
        End Sub

        Private Sub _drawSubItemTextCore(ByVal g As Graphics, ByVal subitem As ListViewItem.ListViewSubItem)
            Using br As New SolidBrush(subitem.ForeColor)
                g.DrawString(subitem.Text, subitem.Font, br, subitem.Bounds)
            End Using
        End Sub

        Private Function _getRowBoundsCore(ByVal itembounds As Rectangle) As Rectangle
            Dim sz As Size = Me.ClientSize
            Return New Rectangle(0, itembounds.Top, sz.Width, itembounds.Height)
        End Function

    End Class
End Class

DOBON.NET | プログラミング道 | プログラミング掲示板