Windows フォーム DataGridView コントロールの列フィル モードColumn Fill Mode in the Windows Forms DataGridView Control

列フィル モードでは、DataGridView コントロールの列は、コントロールの表示領域の幅を満たすように自動的にサイズ変更されます。In column fill mode, the DataGridView control resizes its columns automatically so that they fill the width of the available display area. すべての列の幅を MinimumWidth プロパティの値以上にするために水平スクロール バーが必要な場合を除き、コントロールに水平スクロール バーは表示されません。The control does not display the horizontal scroll bar except when it is necessary to keep the width of every column equal to or greater than its MinimumWidth property value.

各列のサイズ変更動作は、InheritedAutoSizeMode プロパティによって異なります。The sizing behavior of each column depends on its InheritedAutoSizeMode property. このプロパティの値は、列の AutoSizeMode プロパティから継承されるか、または列の値が既定値の NotSet である場合はコントロールの AutoSizeColumnsMode プロパティから継承されます。The value of this property is inherited from the column's AutoSizeMode property or the control's AutoSizeColumnsMode property if the column value is NotSet (the default value).

列ごとに異なるサイズ変更モードを使用できます。ただし、サイズ変更モードが Fill であるすべての列は、それ以外の列が使用していない表示領域を共有します。Each column can have a different size mode, but any columns with a size mode of Fill will share the display-area width that is not used by the other columns. この領域の幅は、フィル モードの列の間で、それぞれの FillWeight プロパティの値の比率に基づいて分割されます。This width is divided among the fill-mode columns in proportions relative to their FillWeight property values. たとえば、FillWeight の値が 100 の列と 200 の列がある場合、最初の列はもう 1 つの列の半分の幅になります。For example, if two columns have FillWeight values of 100 and 200, the first column will be half as wide as the second column.

フィル モードでのユーザーによるサイズ変更User Resizing in Fill Mode

セルの内容に基づいてサイズが変更されるモードとは異なり、フィル モードでは、ユーザーは Resizable プロパティの値が true の列のサイズを変更できます。Unlike sizing modes that resize based on cell contents, fill mode does not prevent users from resizing columns that have Resizable property values of true. ユーザーが 1 つのフィル モード列のサイズを変更すると、サイズ変更した列より後のすべてのフィル モード列 (RightToLeftfalse の場合は右側の列、それ以外の場合は左側の列) のサイズも、表示に使用できる幅の変化とつりあうように変わります。When a user resizes a fill-mode column, any fill-mode columns after the resized column (to the right if RightToLeft is false; otherwise, to the left) are also resized to compensate for the change in the available width. サイズ変更した列より後にフィル モード列がない場合は、コントロール内の他のすべてのフィル モード列のサイズが変更されます。If there are no fill-mode columns after the resized column, then all other fill-mode columns in the control are resized to compensate. コントロール内に他のフィル モード列がない場合は、サイズ変更は無視されます。If there are no other fill-mode columns in the control, the resize is ignored. フィル モードでない列のサイズを変更した場合は、コントロール内のすべてのフィル モード列のサイズが、変更とつりあうように変わります。If a column that is not in fill mode is resized, all fill-mode columns in the control change sizes to compensate.

1 つのフィル モード列のサイズを変更すると、それに合わせて変更されたすべての列の FillWeight の値が比率に応じて調整されます。After resizing a fill-mode column, the FillWeight values for all columns that changed are adjusted proportionally. たとえば、FillWeight 値が 100 である 4 つのフィル モード列のうち、2 番目の列の幅を元の幅の半分にすると、各フィル モード列の FillWeight 値はそれぞれ 100、50、125、125 になります。For example, if four fill-mode columns have FillWeight values of 100, resizing the second column to half its original width will result in FillWeight values of 100, 50, 125, and 125. フィル モードでない列のサイズを変更しても、フィル モード列のサイズは同じ比率を維持するように変更されるだけなので、FillWeight 値は変わりません。Resizing a column that is not in fill mode will not change any FillWeight values because the fill-mode columns will simply resize to compensate while retaining the same proportions.

内容に基づく FillWeight の調整Content-Based FillWeight Adjustment

フィル モード列の FillWeight の値は、DataGridView の自動サイズ変更メソッドを使用して初期化できます。たとえば、AutoResizeColumns メソッドがあります。You can initialize FillWeight values for fill-mode columns by using the DataGridView automatic resizing methods, such as the AutoResizeColumns method. このメソッドは、まず、列の内容を表示するのに必要な幅を計算します。This method first calculates the widths required by columns to display their contents. 次に、計算した幅の比率に一致するように、すべてのフィル モード列の FillWeight の値がコントロールによって調整されます。Next, the control adjusts the FillWeight values for all fill-mode columns so that their proportions match the proportions of the calculated widths. 最後に、この新しい FillWeight の比率を使用して、コントロール内のすべての列が水平方向に使用可能な領域を満たすようにフィル モード列のサイズがコントロールによって変更されます。Finally, the control resizes the fill-mode columns using the new FillWeight proportions so that all columns in the control fill the available horizontal space.

Example

説明Description

AutoSizeModeMinimumWidthFillWeight、および Resizable の各プロパティに適切な値を使用すると、さまざまなシナリオに応じて列のサイズ変更動作をカスタマイズできます。By using appropriate values for the AutoSizeMode, MinimumWidth, FillWeight, and Resizable properties, you can customize the column-sizing behaviors for many different scenarios.

次のデモ コードでは、AutoSizeModeFillWeight、および MinimumWidth の各プロパティのさまざまな値をさまざまな列で試すことができます。The following demonstration code enables you to experiment with different values for the AutoSizeMode, FillWeight, and MinimumWidth properties of different columns. この例では、DataGridView コントロールはそれ自体の Columns コレクションにバインドしており、それぞれの列は HeaderTextAutoSizeModeFillWeightMinimumWidth、および Width の各プロパティにバインドしています。In this example, a DataGridView control is bound to its own Columns collection, and one column is bound to each of the HeaderText, AutoSizeMode, FillWeight, MinimumWidth, and Width properties. 各列はコントロール内の行でも表されており、1 つの行で値を変更すると対応する列のプロパティも更新されるので、値の相互作用を確認できます。Each of the columns is also represented by a row in the control, and changing values in a row will update the properties of the corresponding column so that you can see how the values interact.

コードCode

using System;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Forms;

public class Form1 : Form
{
    [STAThread]
    public static void Main()
    {
        Application.Run(new Form1());
    }

    private DataGridView dataGridView1 = new DataGridView();

    public Form1()
    {
        dataGridView1.Dock = DockStyle.Fill;
        Controls.Add(dataGridView1);
        InitializeDataGridView();
        Width *= 2;
        Text = "Column Fill-Mode Demo";
    }

    private void InitializeDataGridView()
    {
        // Add columns to the DataGridView, binding them to the
        // specified DataGridViewColumn properties.
        AddReadOnlyColumn("HeaderText", "Column");
        AddColumn("AutoSizeMode");
        AddColumn("FillWeight");
        AddColumn("MinimumWidth");
        AddColumn("Width");

        // Bind the DataGridView to its own Columns collection.
        dataGridView1.AutoGenerateColumns = false;
        dataGridView1.DataSource = dataGridView1.Columns;

        // Configure the DataGridView so that users can manually change 
        // only the column widths, which are set to fill mode. 
        dataGridView1.AllowUserToAddRows = false;
        dataGridView1.AllowUserToDeleteRows = false;
        dataGridView1.AllowUserToResizeRows = false;
        dataGridView1.RowHeadersWidthSizeMode =
            DataGridViewRowHeadersWidthSizeMode.DisableResizing;
        dataGridView1.ColumnHeadersHeightSizeMode =
            DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
        dataGridView1.AutoSizeColumnsMode = 
            DataGridViewAutoSizeColumnsMode.Fill;

        // Configure the top left header cell as a reset button.
        dataGridView1.TopLeftHeaderCell.Value = "reset";
        dataGridView1.TopLeftHeaderCell.Style.ForeColor =
            System.Drawing.Color.Blue;

        // Add handlers to DataGridView events.
        dataGridView1.CellClick +=
            new DataGridViewCellEventHandler(dataGridView1_CellClick);
        dataGridView1.ColumnWidthChanged += new
            DataGridViewColumnEventHandler(dataGridView1_ColumnWidthChanged);
        dataGridView1.CurrentCellDirtyStateChanged +=
            new EventHandler(dataGridView1_CurrentCellDirtyStateChanged);
        dataGridView1.DataError +=
            new DataGridViewDataErrorEventHandler(dataGridView1_DataError);
        dataGridView1.CellEndEdit +=
            new DataGridViewCellEventHandler(dataGridView1_CellEndEdit);
        dataGridView1.CellValueChanged +=
            new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
    }

    private void AddReadOnlyColumn(String dataPropertyName, String columnName)
    {
        AddColumn(typeof(DataGridViewColumn), dataPropertyName, true,
            columnName);
    }

    private void AddColumn(String dataPropertyName)
    {
        AddColumn(typeof(DataGridViewColumn), dataPropertyName, false,
            dataPropertyName);
    }

    // Adds a column to the DataGridView control, binding it to specified 
    // property of the specified type and optionally making it read-only.
    private void AddColumn(
        Type type,
        String dataPropertyName,
        Boolean readOnly,
        String columnName)
    {
        // Retrieve information about the property through reflection.
        PropertyInfo property = type.GetProperty(dataPropertyName);

        // Confirm that the property exists and is accessible.
        if (property == null) throw new ArgumentException("No accessible " +
            dataPropertyName + " property was found in the " + type.Name + " type.");

        // Confirm that the property is browsable.
        BrowsableAttribute[] browsables = (BrowsableAttribute[])
            property.GetCustomAttributes(typeof(BrowsableAttribute), false);
        if (browsables.Length > 0 && !browsables[0].Browsable)
        {
            throw new ArgumentException("The " + dataPropertyName + " property has a " +
            "Browsable(false) attribute, and therefore cannot be bound.");
        }

        // Create and initialize a column, using a combo box column for 
        // enumeration properties, a check box column for Boolean properties,
        // and a text box column otherwise.
        DataGridViewColumn column;
        Type valueType = property.PropertyType;
        if (valueType.IsEnum)
        {
            column = new DataGridViewComboBoxColumn();

            // Populate the drop-down list with the enumeration values.
            ((DataGridViewComboBoxColumn)column).DataSource
                = Enum.GetValues(valueType);
        }
        else if (valueType.Equals(typeof(Boolean)))
        {
            column = new DataGridViewCheckBoxColumn();
        }
        else
        {
            column = new DataGridViewTextBoxColumn();
        }

        // Initialize and bind the column.
        column.ValueType = valueType;
        column.Name = columnName;
        column.DataPropertyName = dataPropertyName;
        column.ReadOnly = readOnly;

        // Add the column to the control.
        dataGridView1.Columns.Add(column);
    }

    private void ResetDataGridView()
    {
        dataGridView1.CancelEdit();
        dataGridView1.Columns.Clear();
        dataGridView1.DataSource = null;
        InitializeDataGridView();
    }

    private void dataGridView1_CellClick(
        object sender, DataGridViewCellEventArgs e)
    {
        if (e.ColumnIndex == -1 && e.RowIndex == -1)
        {
            ResetDataGridView();
        }
    }

    private void dataGridView1_ColumnWidthChanged(
        object sender, DataGridViewColumnEventArgs e)
    {
        // Invalidate the row corresponding to the column that changed
        // to ensure that the FillWeight and Width entries are updated.
        dataGridView1.InvalidateRow(e.Column.Index);
    }

    private void dataGridView1_CurrentCellDirtyStateChanged(
        object sender, EventArgs e)
    {
        // For combo box and check box cells, commit any value change as soon
        // as it is made rather than waiting for the focus to leave the cell.
        if (!dataGridView1.CurrentCell.OwningColumn.GetType()
            .Equals(typeof(DataGridViewTextBoxColumn)))
        {
            dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }
    }

    private void dataGridView1_DataError(
        object sender, DataGridViewDataErrorEventArgs e)
    {
        if (e.Exception == null) return;

        // If the user-specified value is invalid, cancel the change 
        // and display the error icon in the row header.
        if ((e.Context & DataGridViewDataErrorContexts.Commit) != 0 &&
            (typeof(FormatException).IsAssignableFrom(e.Exception.GetType()) ||
            typeof(ArgumentException).IsAssignableFrom(e.Exception.GetType())))
        {
            dataGridView1.Rows[e.RowIndex].ErrorText =
                "The specified value is invalid.";
            e.Cancel = true;
        }
        else
        {
            // Rethrow any exceptions that aren't related to the user input.
            e.ThrowException = true;
        }
    }

    private void dataGridView1_CellEndEdit(
        object sender, DataGridViewCellEventArgs e)
    {
        // Ensure that the error icon in the row header is hidden.
        dataGridView1.Rows[e.RowIndex].ErrorText = "";
    }

    private void dataGridView1_CellValueChanged(
        object sender, DataGridViewCellEventArgs e)
    {
        // Retrieve the property to change.
        String nameOfPropertyToChange =
            dataGridView1.Columns[e.ColumnIndex].Name;
        PropertyInfo propertyToChange =
            typeof(DataGridViewColumn).GetProperty(nameOfPropertyToChange);

        // Retrieve the column to change.
        String nameOfColumnToChange =
            (String)dataGridView1["Column", e.RowIndex].Value;
        DataGridViewColumn columnToChange =
            dataGridView1.Columns[nameOfColumnToChange];

        // Use reflection to update the value of the column property. 
        propertyToChange.SetValue(columnToChange,
            dataGridView1[nameOfPropertyToChange, e.RowIndex].Value, null);
    }

}
Imports System.ComponentModel
Imports System.Reflection
Imports System.Windows.Forms

Public Class Form1
    Inherits Form

    <STAThread()> _
    Public Shared Sub Main()
        Application.Run(New Form1())
    End Sub

    Private WithEvents dataGridView1 As New DataGridView()

    Public Sub New()
        dataGridView1.Dock = DockStyle.Fill
        Controls.Add(dataGridView1)
        InitializeDataGridView()
        Width = Width * 2
        Text = "Column Fill-Mode Demo"
    End Sub

    Private Sub InitializeDataGridView()

        ' Add columns to the DataGridView, binding them to the
        ' specified DataGridViewColumn properties.
        AddReadOnlyColumn("HeaderText", "Column")
        AddColumn("AutoSizeMode")
        AddColumn("FillWeight")
        AddColumn("MinimumWidth")
        AddColumn("Width")

        ' Bind the DataGridView to its own Columns collection.
        dataGridView1.AutoGenerateColumns = False
        dataGridView1.DataSource = dataGridView1.Columns

        ' Configure the DataGridView so that users can manually change 
        ' only the column widths, which are set to fill mode. 
        dataGridView1.AllowUserToAddRows = False
        dataGridView1.AllowUserToDeleteRows = False
        dataGridView1.AllowUserToResizeRows = False
        dataGridView1.RowHeadersWidthSizeMode = _
            DataGridViewRowHeadersWidthSizeMode.DisableResizing
        dataGridView1.ColumnHeadersHeightSizeMode = _
            DataGridViewColumnHeadersHeightSizeMode.DisableResizing
        dataGridView1.AutoSizeColumnsMode = _
            DataGridViewAutoSizeColumnsMode.Fill

        ' Configure the top left header cell as a reset button.
        dataGridView1.TopLeftHeaderCell.Value = "reset"
        dataGridView1.TopLeftHeaderCell.Style.ForeColor = _
            System.Drawing.Color.Blue

    End Sub

    Private Sub AddReadOnlyColumn(ByVal dataPropertyName As String, _
        ByVal columnName As String)

        AddColumn(GetType(DataGridViewColumn), dataPropertyName, True, _
            columnName)
    End Sub

    Private Sub AddColumn(ByVal dataPropertyName As String)
        AddColumn(GetType(DataGridViewColumn), dataPropertyName, False, _
            dataPropertyName)
    End Sub

    ' Adds a column to the DataGridView control, binding it to specified 
    ' property of the specified type and optionally making it read-only.
    Private Sub AddColumn( _
        ByVal type As Type, _
        ByVal dataPropertyName As String, _
        ByVal isReadOnly As Boolean, _
        ByVal columnName As String)

        ' Retrieve information about the property through reflection.
        Dim propertyInfo1 As PropertyInfo = type.GetProperty(dataPropertyName)

        ' Confirm that the property exists and is accessible.
        If propertyInfo1 Is Nothing Then
            Throw New ArgumentException("No accessible " & dataPropertyName & _
            " property was found in the " & type.Name & " type.")
        End If

        ' Confirm that the property is browsable.
        Dim browsables As BrowsableAttribute() = CType( _
            propertyInfo1.GetCustomAttributes(GetType(BrowsableAttribute), _
            False), BrowsableAttribute())
        If browsables.Length > 0 AndAlso Not browsables(0).Browsable Then
            Throw New ArgumentException("The " & dataPropertyName & " property has a " & _
            "Browsable(false) attribute, and therefore cannot be bound.")
        End If

        ' Create and initialize a column, using a combo box column for 
        ' enumeration properties, a check box column for Boolean properties,
        ' and a text box column otherwise.
        Dim column As DataGridViewColumn
        Dim valueType As Type = propertyInfo1.PropertyType

        If valueType.IsEnum Then

            column = New DataGridViewComboBoxColumn()

            ' Populate the drop-down list with the enumeration values.
            CType(column, DataGridViewComboBoxColumn).DataSource = _
                [Enum].GetValues(valueType)

        ElseIf valueType.Equals(GetType(Boolean)) Then
            column = New DataGridViewCheckBoxColumn()
        Else
            column = New DataGridViewTextBoxColumn()
        End If

        ' Initialize and bind the column.
        column.ValueType = valueType
        column.Name = columnName
        column.DataPropertyName = dataPropertyName
        column.ReadOnly = isReadOnly

        ' Add the column to the control.
        dataGridView1.Columns.Add(column)

    End Sub

    Private Sub ResetDataGridView()
        dataGridView1.CancelEdit()
        dataGridView1.Columns.Clear()
        dataGridView1.DataSource = Nothing
        InitializeDataGridView()
    End Sub

    Private Sub dataGridView1_CellClick( _
        ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) _
        Handles dataGridView1.CellClick

        If e.ColumnIndex = -1 AndAlso e.RowIndex = -1 Then
            ResetDataGridView()
        End If

    End Sub

    Private Sub dataGridView1_ColumnWidthChanged( _
        ByVal sender As Object, ByVal e As DataGridViewColumnEventArgs) _
        Handles dataGridView1.ColumnWidthChanged

        ' Invalidate the row corresponding to the column that changed
        ' to ensure that the FillWeight and Width entries are updated.
        dataGridView1.InvalidateRow(e.Column.Index)

    End Sub

    Private Sub dataGridView1_CurrentCellDirtyStateChanged( _
        ByVal sender As Object, ByVal e As EventArgs) _
        Handles dataGridView1.CurrentCellDirtyStateChanged

        ' For combo box and check box cells, commit any value change as soon
        ' as it is made rather than waiting for the focus to leave the cell.
        If Not dataGridView1.CurrentCell.OwningColumn.GetType() _
            .Equals(GetType(DataGridViewTextBoxColumn)) Then

            dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)

        End If

    End Sub

    Private Sub dataGridView1_DataError( _
        ByVal sender As Object, ByVal e As DataGridViewDataErrorEventArgs) _
        Handles dataGridView1.DataError

        If e.Exception Is Nothing Then Return

        ' If the user-specified value is invalid, cancel the change 
        ' and display the error icon in the row header.
        If Not (e.Context And DataGridViewDataErrorContexts.Commit) = 0 AndAlso _
            (GetType(FormatException).IsAssignableFrom(e.Exception.GetType()) Or _
            GetType(ArgumentException).IsAssignableFrom(e.Exception.GetType())) Then

            dataGridView1.Rows(e.RowIndex).ErrorText = e.Exception.Message
            e.Cancel = True

        Else
            ' Rethrow any exceptions that aren't related to the user input.
            e.ThrowException = True
        End If

    End Sub

    Private Sub dataGridView1_CellEndEdit( _
        ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) _
        Handles dataGridView1.CellEndEdit

        ' Ensure that the error icon in the row header is hidden.
        dataGridView1.Rows(e.RowIndex).ErrorText = ""

    End Sub

    Private Sub dataGridView1_CellValueChanged( _
        ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) _
        Handles dataGridView1.CellValueChanged

        ' Ignore the change to the top-left header cell.
        If e.ColumnIndex < 0 Then Return

        ' Retrieve the property to change.
        Dim nameOfPropertyToChange As String = _
            dataGridView1.Columns(e.ColumnIndex).Name
        Dim propertyToChange As PropertyInfo = _
            GetType(DataGridViewColumn).GetProperty(nameOfPropertyToChange)

        ' Retrieve the column to change.
        Dim nameOfColumnToChange As String = _
            CStr(dataGridView1("Column", e.RowIndex).Value)
        Dim columnToChange As DataGridViewColumn = _
            dataGridView1.Columns(nameOfColumnToChange)

        ' Use reflection to update the value of the column property. 
        propertyToChange.SetValue(columnToChange, _
            dataGridView1(nameOfPropertyToChange, e.RowIndex).Value, Nothing)

    End Sub

End Class

コメントComments

このデモ アプリケーションは、次のようにして使用します。To use this demonstration application:

  • フォームのサイズを変更します。Change the size of the form. FillWeight プロパティの値で示される比率が維持されたまま、列の幅が変わることを確認します。Observe how columns change their widths while retaining the proportions indicated by the FillWeight property values.

  • マウスで列の区分線をドラッグして、列のサイズを変更します。Change the column sizes by dragging the column dividers with the mouse. FillWeight 値がどのように変わるかを確認します。Observe how the FillWeight values change.

  • 1 つの列の MinimumWidth 値を変更してから、フォームのサイズをドラッグで変更します。Change the MinimumWidth value for one column, then drag to resize the form. フォームをどれだけ小さくしても Width 値が MinimumWidth 値を下回らないことを確認します。Observe how, when you make the form small enough, the Width values do not go below the MinimumWidth values.

  • すべての列の MinimumWidth 値を大きくして、その合計値がコントロールの幅を上回るようにします。Change the MinimumWidth values for all columns to large numbers so that the combined values exceed the width of the control. 水平スクロール バーが表示されることを確認します。Observe how the horizontal scroll bar appears.

  • 一部の列の AutoSizeMode 値を変更します。Change the AutoSizeMode values for some columns. 列またはフォームのサイズの変更によって何が起きるかを確認します。Observe the effect when you resize columns or the form.

コードのコンパイルCompiling the Code

この例で必要な要素は次のとおりです。This example requires:

  • System、System.Drawing、および System.Windows.Forms の各アセンブリへの参照。References to the System, System.Drawing, and System.Windows.Forms assemblies.

関連項目See also