DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

DataGridViewにProgressBarを表示する

注意:DataGridViewコントロールは、.NET Framework 2.0で新しく追加されました。

ここでは、DataGridViewのセルにプログレスバーを表示する方法を例に、カスタムセルクラス(DataGridViewCellクラスの派生クラス)と、そのセルのコレクションをホストするカスタム列クラス(DataGridViewColumnクラスの派生クラス)を作成する方法を紹介します。

DataGridViewProgressBarColumn

補足:ここで紹介するのは、独自にセルを描画することにより、.NET Frameworkに組み込まれているセルクラスとは違った外観となるカスタムセルクラスを作成する方法であり、セルの編集に使用するコントロールを独自に用意する方法ではありません。ここで作成するカスタムセルクラスはDataGridViewTextBoxCellクラスを継承したものであり、見た目はプログレスバーですが、セルの値の編集は従来どおりテキストボックスで行います。独自のコントロールをセルの編集に使用するカスタムセルクラスを作成する方法は、こちらで紹介します。

カスタムセルクラスはDataGridViewCellクラスを継承して作成しますが、ここではDataGridViewTextBoxCellクラスを継承してカスタムセルクラスを作成します。このようにすることにより、セルの編集等の処理を自分で実装する手間が省けます。必要な実装は、プログレスバーをセルに描画するために、DataGridViewTextBoxCellクラスのPaintメソッドをオーバーライドする程度に省略できます。

カスタム列クラスは、DataGridViewColumnクラスを継承して作成します。ここではDataGridViewTextBoxColumnクラスを継承していますが、DataGridViewColumnクラスを直接継承しても手間はあまり変わりません(DataGridViewColumnクラスを直接継承した例は、こちらにあります)。

補足:カスタム列クラスは必ず作成しなければならないということはありません。例えばDataGridViewTextBoxCellクラスから派生したカスタムセルならば、DataGridViewTextBoxColumn列に表示することもできます。このようにする場合は、DataGridViewTextBoxColumnオブジェクトのCellTemplateプロパティにカスタムセルクラスのインスタンスを設定します。

以下にDataGridViewにProgressBarを表示するためのカスタムセルクラス(DataGridViewProgressBarCellクラス)とカスタム列クラス(DataGridViewProgressBarColumnクラス)の例を示します。カスタムセルクラスを作成する例として書いたため、プログレスバーを表示するだけなら無駄と思われる部分もあえて入れています。

VB.NET
コードを隠すコードを選択
Imports System
Imports System.Drawing
Imports System.Windows.Forms

''' <summary>
''' DataGridViewProgressBarCellオブジェクトの列
''' </summary>
Public Class DataGridViewProgressBarColumn
    Inherits DataGridViewTextBoxColumn

    'コンストラクタ
    Public Sub New()
        Me.CellTemplate = New DataGridViewProgressBarCell()
    End Sub

    'CellTemplateの取得と設定
    Public Overrides Property CellTemplate() As DataGridViewCell
        Get
            Return MyBase.CellTemplate
        End Get
        Set(ByVal value As DataGridViewCell)
            'DataGridViewProgressBarCell以外はホストしない
            If Not TypeOf value Is DataGridViewProgressBarCell Then
                Throw New InvalidCastException( _
                    "DataGridViewProgressBarCellオブジェクトを" + _
                    "指定してください。")
            End If
            MyBase.CellTemplate = value
        End Set
    End Property

    ''' <summary>
    ''' ProgressBarの最大値
    ''' </summary>
    Public Property Maximum() As Integer
        Get
            Return CType(Me.CellTemplate, DataGridViewProgressBarCell).Maximum
        End Get
        Set(ByVal value As Integer)
            If Me.Maximum = value Then
                Return
            End If
            'セルテンプレートの値を変更する
            CType(Me.CellTemplate, DataGridViewProgressBarCell).Maximum = value
            'DataGridViewにすでに追加されているセルの値を変更する
            If Me.DataGridView Is Nothing Then
                Return
            End If
            Dim rowCount As Integer = Me.DataGridView.RowCount
            Dim i As Integer
            For i = 0 To rowCount - 1
                Dim r As DataGridViewRow = Me.DataGridView.Rows.SharedRow(i)
                CType(r.Cells(Me.Index), DataGridViewProgressBarCell).Maximum = _
                    value
            Next i
        End Set
    End Property

    ''' <summary>
    ''' ProgressBarの最小値
    ''' </summary>
    Public Property Mimimum() As Integer
        Get
            Return CType(Me.CellTemplate, DataGridViewProgressBarCell).Mimimum
        End Get
        Set(ByVal value As Integer)
            If Me.Mimimum = value Then
                Return
            End If
            'セルテンプレートの値を変更する
            CType(Me.CellTemplate, DataGridViewProgressBarCell).Mimimum = value
            'DataGridViewにすでに追加されているセルの値を変更する
            If Me.DataGridView Is Nothing Then
                Return
            End If
            Dim rowCount As Integer = Me.DataGridView.RowCount
            Dim i As Integer
            For i = 0 To rowCount - 1
                Dim r As DataGridViewRow = Me.DataGridView.Rows.SharedRow(i)
                CType(r.Cells(Me.Index), DataGridViewProgressBarCell).Mimimum = _
                    value
            Next i
        End Set
    End Property
End Class

''' <summary>
''' ProgressBarをDataGridViewに表示する
''' </summary>
Public Class DataGridViewProgressBarCell
    Inherits DataGridViewTextBoxCell

    'コンストラクタ
    Public Sub New()
        Me.maximumValue = 100
        Me.mimimumValue = 0
    End Sub

    Private maximumValue As Integer

    Public Property Maximum() As Integer
        Get
            Return Me.maximumValue
        End Get
        Set(ByVal value As Integer)
            Me.maximumValue = value
        End Set
    End Property

    Private mimimumValue As Integer

    Public Property Mimimum() As Integer
        Get
            Return Me.mimimumValue
        End Get
        Set(ByVal value As Integer)
            Me.mimimumValue = value
        End Set
    End Property

    'セルの値のデータ型を指定する
    'ここでは、整数型とする
    Public Overrides ReadOnly Property ValueType() As Type
        Get
            Return GetType(Integer)
        End Get
    End Property

    '新しいレコード行のセルの既定値を指定する
    Public Overrides ReadOnly Property DefaultNewRowValue() As Object
        Get
            Return 0
        End Get
    End Property

    '新しいプロパティを追加しているため、
    ' Cloneメソッドをオーバーライドする必要がある
    Public Overrides Function Clone() As Object
        Dim cell As DataGridViewProgressBarCell = _
            CType(MyBase.Clone(), DataGridViewProgressBarCell)
        cell.Maximum = Me.Maximum
        cell.Mimimum = Me.Mimimum
        Return cell
    End Function

    Protected Overrides Sub Paint(ByVal graphics As Graphics, _
        ByVal clipBounds As Rectangle, _
        ByVal cellBounds As Rectangle, _
        ByVal rowIndex As Integer, _
        ByVal cellState As DataGridViewElementStates, _
        ByVal value As Object, _
        ByVal formattedValue As Object, _
        ByVal errorText As String, _
        ByVal cellStyle As DataGridViewCellStyle, _
        ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, _
        ByVal paintParts As DataGridViewPaintParts)

        '値を決定する
        Dim intValue As Integer = 0
        If TypeOf value Is Integer Then
            intValue = CInt(value)
        End If
        If intValue < Me.mimimumValue Then
            intValue = Me.mimimumValue
        End If
        If intValue > Me.maximumValue Then
            intValue = Me.maximumValue
        End If
        '割合を計算する
        Dim rate As Double = CDbl(intValue - Me.mimimumValue) / _
            (Me.maximumValue - Me.mimimumValue)

        'セルの境界線(枠)を描画する
        If (paintParts And DataGridViewPaintParts.Border) = _
                DataGridViewPaintParts.Border Then
            Me.PaintBorder(graphics, clipBounds, cellBounds, _
                cellStyle, advancedBorderStyle)
        End If

        '境界線の内側に範囲を取得する
        Dim borderRect As Rectangle = Me.BorderWidths(advancedBorderStyle)
        Dim paintRect As New Rectangle(cellBounds.Left + borderRect.Left, _
            cellBounds.Top + borderRect.Top, _
            cellBounds.Width - borderRect.Right, _
            cellBounds.Height - borderRect.Bottom)

        '背景色を決定する
        '選択されている時とされていない時で色を変える
        Dim isSelected As Boolean = _
            ((cellState And DataGridViewElementStates.Selected) = _
                DataGridViewElementStates.Selected)
        Dim bkColor As Color
        If isSelected AndAlso _
            (paintParts And DataGridViewPaintParts.SelectionBackground) = _
                DataGridViewPaintParts.SelectionBackground Then
            bkColor = cellStyle.SelectionBackColor
        Else
            bkColor = cellStyle.BackColor
        End If

        '背景を描画する
        If (paintParts And DataGridViewPaintParts.Background) = _
            DataGridViewPaintParts.Background Then
            Dim backBrush As New SolidBrush(bkColor)
            Try
                graphics.FillRectangle(backBrush, paintRect)
            Finally
                backBrush.Dispose()
            End Try
        End If

        'Paddingを差し引く
        paintRect.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top)
        paintRect.Width -= cellStyle.Padding.Horizontal
        paintRect.Height -= cellStyle.Padding.Vertical

        'ProgressBarを描画する
        If (paintParts And DataGridViewPaintParts.ContentForeground) = _
            DataGridViewPaintParts.ContentForeground Then
            If ProgressBarRenderer.IsSupported Then
                'visualスタイルで描画する

                'ProgressBarの枠を描画する
                ProgressBarRenderer.DrawHorizontalBar(graphics, paintRect)
                'ProgressBarのバーを描画する
                Dim barBounds As New Rectangle(paintRect.Left + 3, _
                    paintRect.Top + 3, _
                    paintRect.Width - 4, _
                    paintRect.Height - 6)
                barBounds.Width = CInt(Math.Round((barBounds.Width * rate)))
                ProgressBarRenderer.DrawHorizontalChunks(graphics, barBounds)
            Else
                'visualスタイルで描画できない時
                graphics.FillRectangle(Brushes.White, paintRect)
                graphics.DrawRectangle(Pens.Black, paintRect)
                Dim barBounds As New Rectangle(paintRect.Left + 1, _
                    paintRect.Top + 1, _
                    paintRect.Width - 1, _
                    paintRect.Height - 1)
                barBounds.Width = CInt(Math.Round((barBounds.Width * rate)))
                graphics.FillRectangle(Brushes.Blue, barBounds)
            End If
        End If

        'フォーカスの枠を表示する
        If Me.DataGridView.CurrentCellAddress.X = Me.ColumnIndex AndAlso _
            Me.DataGridView.CurrentCellAddress.Y = Me.RowIndex AndAlso _
            (paintParts And DataGridViewPaintParts.Focus) = _
                DataGridViewPaintParts.Focus AndAlso _
            Me.DataGridView.Focused Then

            'フォーカス枠の大きさを適当に決める
            Dim focusRect As Rectangle = paintRect
            focusRect.Inflate(-3, -3)
            ControlPaint.DrawFocusRectangle(graphics, focusRect)
            '背景色を指定してフォーカス枠を描画する時
            'ControlPaint.DrawFocusRectangle(
            '    graphics, focusRect, Color.Empty, bkColor);
        End If

        'テキストを表示する
        If (paintParts And DataGridViewPaintParts.ContentForeground) = _
            DataGridViewPaintParts.ContentForeground Then
            '表示するテキストを決定
            Dim txt As String = String.Format("{0}%", Math.Round((rate * 100)))
            'string txt = formattedValue.ToString();
            '本来は、cellStyleによりTextFormatFlagsを決定すべき
            Dim flags As TextFormatFlags = _
                TextFormatFlags.HorizontalCenter Or _
                    TextFormatFlags.VerticalCenter
            '色を決定
            Dim fColor As Color = cellStyle.ForeColor
            'if (isSelected)
            '    fColor = cellStyle.SelectionForeColor;
            'else
            '    fColor = cellStyle.ForeColor;
            'テキストを描画する
            paintRect.Inflate(-2, -2)
            TextRenderer.DrawText( _
                graphics, txt, cellStyle.Font, paintRect, fColor, flags)
        End If

        'エラーアイコンの表示
        If (paintParts And DataGridViewPaintParts.ErrorIcon) = _
                DataGridViewPaintParts.ErrorIcon AndAlso _
            Me.DataGridView.ShowCellErrors AndAlso _
            Not String.IsNullOrEmpty(errorText) Then

            'エラーアイコンを表示させる領域を取得
            Dim iconBounds As Rectangle = _
                Me.GetErrorIconBounds(graphics, cellStyle, rowIndex)
            iconBounds.Offset(cellBounds.X, cellBounds.Y)
            'エラーアイコンを描画
            Me.PaintErrorIcon(graphics, iconBounds, cellBounds, errorText)
        End If
    End Sub
End Class
C#
コードを隠すコードを選択
using System;
using System.Drawing;
using System.Windows.Forms;

/// <summary>
/// DataGridViewProgressBarCellオブジェクトの列
/// </summary>
public class DataGridViewProgressBarColumn : DataGridViewTextBoxColumn
{
    //コンストラクタ
    public DataGridViewProgressBarColumn()
    {
        this.CellTemplate = new DataGridViewProgressBarCell();
    }

    //CellTemplateの取得と設定
    public override DataGridViewCell CellTemplate
    {
        get
        {
            return base.CellTemplate;
        }
        set
        {
            //DataGridViewProgressBarCell以外はホストしない
            if (!(value is DataGridViewProgressBarCell))
            {
                throw new InvalidCastException(
                    "DataGridViewProgressBarCellオブジェクトを" +
                    "指定してください。");
            }
            base.CellTemplate = value;
        }
    }

    /// <summary>
    /// ProgressBarの最大値
    /// </summary>
    public int Maximum
    {
        get
        {
            return ((DataGridViewProgressBarCell)this.CellTemplate).Maximum;
        }
        set
        {
            if (this.Maximum == value)
                return;
            //セルテンプレートの値を変更する
            ((DataGridViewProgressBarCell)this.CellTemplate).Maximum =
                value;
            //DataGridViewにすでに追加されているセルの値を変更する
            if (this.DataGridView == null)
                return;
            int rowCount = this.DataGridView.RowCount;
            for (int i = 0; i < rowCount; i++)
            {
                DataGridViewRow r = this.DataGridView.Rows.SharedRow(i);
                ((DataGridViewProgressBarCell)r.Cells[this.Index]).Maximum =
                    value;
            }
        }
    }

    /// <summary>
    /// ProgressBarの最小値
    /// </summary>
    public int Mimimum
    {
        get
        {
            return ((DataGridViewProgressBarCell)this.CellTemplate).Mimimum;
        }
        set
        {
            if (this.Mimimum == value)
                return;
            //セルテンプレートの値を変更する
            ((DataGridViewProgressBarCell)this.CellTemplate).Mimimum =
                value;
            //DataGridViewにすでに追加されているセルの値を変更する
            if (this.DataGridView == null)
                return;
            int rowCount = this.DataGridView.RowCount;
            for (int i = 0; i < rowCount; i++)
            {
                DataGridViewRow r = this.DataGridView.Rows.SharedRow(i);
                ((DataGridViewProgressBarCell)r.Cells[this.Index]).Mimimum =
                    value;
            }
        }
    }
}

/// <summary>
/// ProgressBarをDataGridViewに表示する
/// </summary>
public class DataGridViewProgressBarCell : DataGridViewTextBoxCell
{
    //コンストラクタ
    public DataGridViewProgressBarCell()
    {
        this.maximumValue = 100;
        this.mimimumValue = 0;
    }

    private int maximumValue;
    public int Maximum
    {
        get
        {
            return this.maximumValue;
        }
        set
        {
            this.maximumValue = value;
        }
    }

    private int mimimumValue;
    public int Mimimum
    {
        get
        {
            return this.mimimumValue;
        }
        set
        {
            this.mimimumValue = value;
        }
    }

    //セルの値のデータ型を指定する
    //ここでは、整数型とする
    public override Type ValueType
    {
        get
        {
            return typeof(int);
        }
    }

    //新しいレコード行のセルの既定値を指定する
    public override object DefaultNewRowValue
    {
        get
        {
            return 0;
        }
    }

    //新しいプロパティを追加しているため、
    // Cloneメソッドをオーバーライドする必要がある
    public override object Clone()
    {
        DataGridViewProgressBarCell cell =
            (DataGridViewProgressBarCell)base.Clone();
        cell.Maximum = this.Maximum;
        cell.Mimimum = this.Mimimum;
        return cell;
    }

    protected override void Paint(Graphics graphics,
        Rectangle clipBounds, Rectangle cellBounds,
        int rowIndex, DataGridViewElementStates cellState,
        object value, object formattedValue, string errorText,
        DataGridViewCellStyle cellStyle,
        DataGridViewAdvancedBorderStyle advancedBorderStyle,
        DataGridViewPaintParts paintParts)
    {
        //値を決定する
        int intValue = 0;
        if (value is int)
            intValue = (int)value;
        if (intValue < this.mimimumValue)
            intValue = this.mimimumValue;
        if (intValue > this.maximumValue)
            intValue = this.maximumValue;
        //割合を計算する
        double rate = (double)(intValue - this.mimimumValue) /
            (this.maximumValue - this.mimimumValue);

        //セルの境界線(枠)を描画する
        if ((paintParts & DataGridViewPaintParts.Border) ==
            DataGridViewPaintParts.Border)
        {
            this.PaintBorder(graphics, clipBounds, cellBounds,
                cellStyle, advancedBorderStyle);
        }

        //境界線の内側に範囲を取得する
        Rectangle borderRect = this.BorderWidths(advancedBorderStyle);
        Rectangle paintRect = new Rectangle(
            cellBounds.Left + borderRect.Left,
            cellBounds.Top + borderRect.Top,
            cellBounds.Width - borderRect.Right,
            cellBounds.Height - borderRect.Bottom);

        //背景色を決定する
        //選択されている時とされていない時で色を変える
        bool isSelected =
            (cellState & DataGridViewElementStates.Selected) ==
            DataGridViewElementStates.Selected;
        Color bkColor;
        if (isSelected &&
            (paintParts & DataGridViewPaintParts.SelectionBackground) ==
                DataGridViewPaintParts.SelectionBackground)
        {
            bkColor = cellStyle.SelectionBackColor;
        }
        else
        {
            bkColor = cellStyle.BackColor;
        }
        //背景を描画する
        if ((paintParts & DataGridViewPaintParts.Background) ==
            DataGridViewPaintParts.Background)
        {
            using (SolidBrush backBrush = new SolidBrush(bkColor))
            {
                graphics.FillRectangle(backBrush, paintRect);
            }
        }

        //Paddingを差し引く
        paintRect.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top);
        paintRect.Width -= cellStyle.Padding.Horizontal;
        paintRect.Height -= cellStyle.Padding.Vertical;

        //ProgressBarを描画する
        if ((paintParts & DataGridViewPaintParts.ContentForeground) ==
            DataGridViewPaintParts.ContentForeground)
        {
            if (ProgressBarRenderer.IsSupported)
            {
                //visualスタイルで描画する

                //ProgressBarの枠を描画する
                ProgressBarRenderer.DrawHorizontalBar(graphics, paintRect);
                //ProgressBarのバーを描画する
                Rectangle barBounds = new Rectangle(
                    paintRect.Left + 3, paintRect.Top + 3,
                    paintRect.Width - 4, paintRect.Height - 6);
                barBounds.Width = (int)Math.Round(barBounds.Width * rate);
                ProgressBarRenderer.DrawHorizontalChunks(graphics, barBounds);
            }
            else
            {
                //visualスタイルで描画できない時

                graphics.FillRectangle(Brushes.White, paintRect);
                graphics.DrawRectangle(Pens.Black, paintRect);
                Rectangle barBounds = new Rectangle(
                    paintRect.Left + 1, paintRect.Top + 1,
                    paintRect.Width - 1, paintRect.Height - 1);
                barBounds.Width = (int)Math.Round(barBounds.Width * rate);
                graphics.FillRectangle(Brushes.Blue, barBounds);
            }
        }

        //フォーカスの枠を表示する
        if (this.DataGridView.CurrentCellAddress.X == this.ColumnIndex &&
            this.DataGridView.CurrentCellAddress.Y == this.RowIndex &&
            (paintParts & DataGridViewPaintParts.Focus) ==
                DataGridViewPaintParts.Focus &&
            this.DataGridView.Focused)
        {
            //フォーカス枠の大きさを適当に決める
            Rectangle focusRect = paintRect;
            focusRect.Inflate(-3, -3);
            ControlPaint.DrawFocusRectangle(graphics, focusRect);
            //背景色を指定してフォーカス枠を描画する時
            //ControlPaint.DrawFocusRectangle(
            //    graphics, focusRect, Color.Empty, bkColor);
        }

        //テキストを表示する
        if ((paintParts & DataGridViewPaintParts.ContentForeground) ==
            DataGridViewPaintParts.ContentForeground)
        {
            //表示するテキストを決定
            string txt = string.Format("{0}%", Math.Round(rate * 100));
            //string txt = formattedValue.ToString();

            //本来は、cellStyleによりTextFormatFlagsを決定すべき
            TextFormatFlags flags = TextFormatFlags.HorizontalCenter |
                TextFormatFlags.VerticalCenter;
            //色を決定
            Color fColor = cellStyle.ForeColor;
            //if (isSelected)
            //    fColor = cellStyle.SelectionForeColor;
            //else
            //    fColor = cellStyle.ForeColor;
            //テキストを描画する
            paintRect.Inflate(-2, -2);
            TextRenderer.DrawText(graphics, txt, cellStyle.Font,
                paintRect, fColor, flags);
        }

        //エラーアイコンの表示
        if ((paintParts & DataGridViewPaintParts.ErrorIcon) ==
            DataGridViewPaintParts.ErrorIcon &&
            this.DataGridView.ShowCellErrors &&
            !string.IsNullOrEmpty(errorText))
        {
            //エラーアイコンを表示させる領域を取得
            Rectangle iconBounds = this.GetErrorIconBounds(
                graphics, cellStyle, rowIndex);
            iconBounds.Offset(cellBounds.X, cellBounds.Y);
            //エラーアイコンを描画
            this.PaintErrorIcon(graphics, iconBounds, cellBounds, errorText);
        }
    }
}

このように作成したDataGridViewProgressBarColumnの使用法は、例えば次のようになります。詳しくは、こちらなどをご覧ください。

VB.NET
コードを隠すコードを選択
'DataGridViewProgressBarColumnを作成する
Dim pbColumn As New DataGridViewProgressBarColumn()
'データソースの"Column1"をバインドする
pbColumn.DataPropertyName = "Column1"
'列を追加する
DataGridView1.Columns.Add(pbColumn)
C#
コードを隠すコードを選択
//DataGridViewProgressBarColumnを作成する
DataGridViewProgressBarColumn pbColumn =
    new DataGridViewProgressBarColumn();
//データソースの"Column1"をバインドする
pbColumn.DataPropertyName = "Column1";
//列を追加する
DataGridView1.Columns.Add(pbColumn);

基本的な説明は上記のコードにコメントとして記述していますが、少し分かりにくいと思われる箇所を以下に補足します。

DataGridViewProgressBarCellクラス

Paintメソッド

Paintメソッドをオーバーライドして、セルを描画します。

この例では、フォーカスを示す枠線を表示していますが、通常はプログレスバーには必要ないでしょう。ここでは背景部分にフォーカス枠を表示するのではなく、プログレスバーの上に表示しているため、ControlPaint.DrawFocusRectangleメソッドに背景色を指定していません。通常は、ControlPaint.DrawFocusRectangleメソッドにセルの背景色を指定すべきでしょう。(Rectangle.Inflateはフォーカス枠をプログレスバーの上に表示するためのものなので、これも通常は不要です。)

テキストを表示している箇所も、普通はプログレスバーには必要ないでしょう。ここではパーセンテージを表示していますが、通常はformattedValueを表示することになるでしょう。

テキストの描画にはGraphics.DrawStringメソッドではなく、TextRenderer.DrawTextメソッドを使用していますが、DataGridViewは内部でTextRendererを使用しているようなので、このようにしています。

Cloneメソッド

カスタムセルクラスに新しいプロパティ(MaximumとMimimum)を追加しているため、Cloneメソッドをオーバーライドする必要があります。カスタムセルクラスに新しいプロパティを追加しないのであれば、その必要はありません。

列クラスにプロパティを追加する

DataGridViewProgressBarColumnクラスでは、MaximumとMimimumプロパティを独自に追加して、DataGridViewProgressBarCellの同プロパティを設定できるようにしています。ここではCellTemplateを変更して、さらにDataGridViewのすべてのDataGridViewProgressBarCellを変更しています。つまり、プロパティの値を保持しているのは列ではなく、セルです。

列クラスに独自のプロパティを追加する場合、上記のようにセルが値を保持する方法以外に、列が保持する方法もあります。この場合、セルクラスからこのプロパティの値を取得するには、セルクラスのOwningColumnプロパティで列オブジェクトを取得して、プロパティの値を取得します。

プロパティの値をセルで保持する場合、セルクラスのCloneメソッドをオーバーライドして、プロパティの内容が正しくコピーされるようにする必要があります。プロパティの値を列で保持する場合は、列クラスのCloneメソッドをオーバーライドする必要があります。(もちろん両方で保持する場合は、両方のCloneメソッドをオーバーライドする必要があります。)

プロパティの値を列で保持するケースは、その列の全てのセルが同じ設定でなければならないという場合です。例えば、DataGridViewButtonColumnクラスのTextプロパティなどです。それ以外は、セルでプロパティの値を保持します。

プロパティの値を列で保持する例は、こちらで紹介します。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • .NET Tipsをご利用いただく際は、注意事項をお守りください。