Windows フォーム DataGridView コントロールの列フィル モード
更新 : 2007 年 11 月
列フィル モードでは、DataGridView コントロールの列は、コントロールの表示領域の幅を満たすように自動的にサイズ変更されます。すべての列の幅を MinimumWidth プロパティの値と同じかそれよりも大きくする必要がある場合を除き、コントロールに水平スクロール バーは表示されません。
各列のサイズ変更動作は、InheritedAutoSizeMode プロパティによって異なります。このプロパティの値は、列の AutoSizeMode プロパティから継承されますが、列の値が既定の NotSet の場合はコントロールの AutoSizeColumnsMode プロパティから継承されます。
列ごとに異なるサイズ変更モードを使用できます。ただし、サイズ変更モードが Fill であるすべての列は、それ以外の列が使用していない表示領域を共有します。この領域の幅は、フィル モードの列の間で、それぞれの FillWeight プロパティの値の比率に基づいて分割されます。たとえば、FillWeight の値が 100 の列と 200 の列がある場合、最初の列はもう 1 つの列の半分の幅になります。
フィル モードでのユーザーによるサイズ変更
セルの内容に基づくサイズ変更モードとは異なり、フィル モードでは、ユーザーは Resizable プロパティが true の列のサイズを変更できます。ユーザーが 1 つのフィル モード列のサイズを変更すると、サイズ変更された列以降のすべてのフィル モード列 (RightToLeft が false の場合は右側の列、それ以外の場合は左側の列) のサイズも、表示に使用できる幅の変化とつりあうように変わります。サイズ変更された列以降にフィル モード列がない場合は、コントロール内の他のすべてのフィル モード列のサイズが変更されます。コントロール内に他のフィル モード列がない場合は、サイズ変更は無視されます。フィル モードでない列のサイズが変更された場合は、コントロール内のすべてのフィル モード列のサイズが、変更とつりあうように変わります。
1 つのフィル モード列のサイズを変更すると、変更されたすべての列の FillWeight の値が比率に応じて調整されます。たとえば、FillWeight 値が 100 である 4 つのフィル モード列のうち、2 番目の列の幅を半分にすると、各フィル モード列の FillWeight 値はそれぞれ 100、50、125、125 になります。フィル モードでない列のサイズを変更しても、フィル モード列のサイズは同じ比率を維持するように変更されるだけなので、FillWeight 値は変わりません。
内容に基づく FillWeight の調整
フィル モード列の FillWeight の値は、DataGridView の自動サイズ変更メソッドを使用して初期化できます。たとえば、AutoResizeColumns メソッドです。このメソッドは、まず、列の内容を表示するのに必要な幅を計算します。次に、計算された幅の比率に一致するように、すべてのフィル モード列の FillWeight の値が調整されます。最後に、この新しい FillWeight の比率を使用して、コントロール内のすべての列が水平方向に使用可能なスペースを満たすようにフィル モード列のサイズが変更されます。
例
説明
AutoSizeMode、MinimumWidth、FillWeight、および Resizable の各プロパティに適切な値を使用すると、さまざまなシナリオに応じて列のサイズ変更動作をカスタマイズできます。
次のデモ コードは、AutoSizeMode、FillWeight、および MinimumWidth の各プロパティのさまざまな値をさまざまな列で試すことができます。この例では、DataGridView コントロールはそれ自体の Columns コレクションにバインドしており、それぞれの列は HeaderText、AutoSizeMode、FillWeight、MinimumWidth、および Width の各プロパティにバインドしています。各列はコントロール内の行でも表されており、行で値を変更すると対応する列のプロパティも更新されるので、値どうしの作用も確認できます。
コード
Imports System
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
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);
}
}
コメント
このデモ アプリケーションを使用するには
フォームのサイズを変更します。FillWeight プロパティの値で示される比率が維持されたまま、列の幅が変わることを確認します。
マウスで列の区分線をドラッグして列幅を変更します。FillWeight 値がどのように変わるかを確認します。
1 つの列の MinimumWidth 値を変更してから、フォームのサイズをドラッグで変更します。フォームを十分小さくしても Width 値が MinimumWidth 値を下回らないことを確認します。
すべての列の MinimumWidth 値を大きくして、その合計がコントロールの幅を上回るようにします。水平スクロール バーが表示されることを確認します。
一部の列の AutoSizeMode 値を変更します。列またはフォームのサイズの変更によって何が起きたかを確認します。
コードのコンパイル
この例には、次の項目が必要です。
- System、System.Drawing、System.Windows.Forms の各アセンブリへの参照。
Visual Basic または Visual C# のコマンド ラインからこの例をビルドする方法の詳細については、「コマンド ラインからのビルド (Visual Basic)」または「csc.exe を使用したコマンド ラインからのビルド」を参照してください。Visual Studio で新しいプロジェクトにコードを貼り付けてこの例をビルドすることもできます。 方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する
方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する
方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する
方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する
方法 : 完成した Windows フォーム コードの例を Visual Studio を使ってコンパイルして実行する
参照
参照
DataGridView.AutoResizeColumns
DataGridView.AutoSizeColumnsMode
DataGridViewAutoSizeColumnsMode
DataGridViewColumn.InheritedAutoSizeMode
DataGridViewColumn.AutoSizeMode
DataGridViewAutoSizeColumnMode
DataGridViewColumn.MinimumWidth