投稿者 魔界の仮面弁士  (社会人) 投稿日時 2017/4/11 11:44:30
> (3) 「文字単位で着色する」

参考までに、「2 行目 1 列目」のセル内の文字列を、
文字ごとに別の色で描画するコードを書いてみました。

一文字ごとに、Red 成分 を+90、Green 成分を +25、Blue 成分を + 40 しています。


Private Sub DataGridView1_CellPainting(sender As Object, e As DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting
    '2 行目 1 列目 のみ、カスタム描画する 
    If e.RowIndex = 2 AndAlso e.ColumnIndex = 1 Then

        '背景は標準描画に任せる 
        e.PaintBackground(e.CellBounds, True)

        'セルに表示する文字列を取得 
        Dim sText As String = If(CStr(e.Value), "")

        '1 文字ごとの位置を切り出すための構造体配列 
        Dim cr(sText.Length - 1) As CharacterRange
        For i = 0 To sText.Length - 1
            cr(i) = New CharacterRange(i, 1)
        Next

        Using fmt As New StringFormat(StringFormat.GenericDefault)
            'セルスタイルの Alignment を、StringFormat の文字位置に変換 
            Dim align As DataGridViewContentAlignment = e.CellStyle.Alignment

            If (align And &HF) <> 0 Then
                fmt.LineAlignment = StringAlignment.Near
            ElseIf (align And &HF0) <> 0 Then
                fmt.LineAlignment = StringAlignment.Center
            ElseIf (align And &HF00) <> 0 Then
                fmt.LineAlignment = StringAlignment.Far
            End If
            If (align And &H111) <> 0 Then
                fmt.Alignment = StringAlignment.Near
            ElseIf (align And &H222) <> 0 Then
                fmt.Alignment = StringAlignment.Center
            ElseIf (align And &H444) <> 0 Then
                fmt.Alignment = StringAlignment.Far
            End If

            '折り返し調整など 
            fmt.FormatFlags = fmt.FormatFlags Or StringFormatFlags.NoClip
            If e.CellStyle.WrapMode = DataGridViewTriState.False Then
                fmt.FormatFlags = fmt.FormatFlags Or StringFormatFlags.NoWrap
            End If

            ''余白領域の調整 
            'Dim bounds As Rectangle = e.CellBounds 
            'bounds.X += e.CellStyle.Padding.Left 
            'bounds.Y += e.CellStyle.Padding.Top 
            'bounds.Width -= e.CellStyle.Padding.Horizontal 
            'bounds.Height -= e.CellStyle.Padding.Vertical 

            '各文字の位置を示す領域を構築 
            fmt.SetMeasurableCharacterRanges(cr)
            Dim regions() As Region = e.Graphics.MeasureCharacterRanges(sText, e.CellStyle.Font, bounds, fmt)

            '1文字ずつ色を変えて描画 
            Dim r, g, b As Integer
            For i = 0 To sText.Length - 1
                r = (r + 90) And &HFF
                g = (g + 25) And &HFF
                b = (b + 40) And &HFF
                Using sb As New SolidBrush(Color.FromArgb(r, g, b))
                    Dim rectF As RectangleF = regions(i).GetBounds(e.Graphics)
                    Dim rect As Rectangle = Rectangle.Truncate(rectF)

                    e.Graphics.DrawString(sText.Substring(i, 1), e.CellStyle.Font, sb, rect, fmt)
                End Using
            Next
        End Using

        'カスタム描画を行ったときは、Handled を True にして 
        '標準描画が行われることを抑制する 
        e.Handled = True

    End If
End Sub



長いコードになりましたが、これでも手抜き実装です。

行末の三点リーダー(ellipsis)などは省いているので、
長すぎる文字列の表示、特に Alignment が右寄せに
なっている場合の処理などは、もう少し見直しが必要です。