Columns

SfDataGrid allows to add or remove columns using SfDataGrid.Columns property. The columns to be added can be chosen from built-in column types or own column can be created and add to the SfDataGrid.Columns.
Below are the built-in column types supported in SfDataGrid. Each column has its own properties to handle different types of data.

Column Type

        Description

GridTextColumn

        
Use to display the string data

GridNumericColumn

Use to display the numeric data

GridDateTimeColumn

Use to display the date time value

GridCheckBoxColumn

        
Use to display the Boolean type data

GridComboBoxColumn

Use to display combobox in each row

GridImageColumn

Use to display the image in each row

GridHyperlinkColumn

Use to display the Uri data

GridButtonColumn

Use to display button in each row

Defining Columns

SfDataGrid provides support for creating columns automatically or manually. Below sections explains both the ways,
SfDataGrid provides support for generating

  1. Automatically generating columns
  2. Manually defining columns

Automatically Generating Columns

The automatic column generation based on properties of data object can be enabled or disabled by setting SfDataGrid.AutoGenerateColumns. Default value is true. The columns will be automatically generated based on its column type from the underlying data source.

It is also possible to generate columns for custom type properties in the data object by setting the SfDataGrid.AutoGenerateColumnsForCustomType property to true. The default value is false.

Data Type

        Column

string, object, dynamic GridTextColumn
int, float, double, decimal and also it’s nullable         GridNumericColumn
DateTime, DateTimeOffset and also it’s nullable GridDateTimeColumn
Uri, Uri?         GridHyperLinkColumn
bool, bool?         GridCheckBoxColumn

NOTE

The order of columns in the collection will determine the order of that they will appear in SfDataGrid.

AutoGenerateColumns with Different Modes

The column auto generation is controlled using the SfDataGrid.AutoGenerateColumnsMode property. Default value is AutoGenerateColumnsMode.Reset.
The SfDataGrid.AutoGenerateColumnsMode includes the following modes.

Mode

Behavior

When DataSource changed

None Generates the columns based on the explicit column definition. Keeps old columns in DataGrid.Columns collection.
Reset Generates the columns based on the properties defined in the underlying data object and explicit column definition. Keeps the columns added manually. Clears the columns which are auto generated before and creates new columns based on new DataSource.
ResetAll Generates the columns based on the properties defined in the underlying data object. Clear all the columns including the columns defined manually and creates new columns based on new DataSource.
RetainOld Generates the columns based on the properties defined in the underlying data object, when the SfDataGrid doesn’t have an explicit column definition. The same columns will be maintained when changing DataSource also. So sorting and grouping settings will be maintained.
SmartReset Generates the columns and retains data operation based on the properties defined in underlying data object. Keeps the columns which matches in the current data source and the data operation performed in it.

Customize Auto-generated Columns

The auto generated column can be customized by handling the AutoGeneratingColumn event. AutoGeneratingColumn event occurs when the column is auto generated.
AutoGeneratingColumnArgs provides the information about the auto-generated column to the AutoGeneratingColumn event. AutoGeneratingColumnArgs.Column property returns the auto-generated column.

this.sfDataGrid1.AutoGeneratingColumn += SfDataGrid1_AutoGeneratingColumn;

private void SfDataGrid1_AutoGeneratingColumn(object sender, AutoGeneratingColumnArgs e)
{
    e.Column.HeaderText = "AutoGenerated";
    e.Column.HeaderStyle.BackColor = Color.LightSkyBlue;
}
AddHandler sfDataGrid1.AutoGeneratingColumn, AddressOf SfDataGrid1_AutoGeneratingColumn

Private Sub SfDataGrid1_AutoGeneratingColumn(ByVal sender As Object, ByVal e As AutoGeneratingColumnArgs)
	e.Column.HeaderText = "AutoGenerated"
	e.Column.HeaderStyle.BackColor = Color.LightSkyBlue
End Sub

Cancel Column Generation for Particular Property

The auto generation of the specific column can be canceled by handling the AutoGeneratingColumn event. The column generation can be canceled by setting the Cancel property to true.

this.sfDataGrid1.AutoGeneratingColumn += SfDataGrid1_AutoGeneratingColumn;
private void SfDataGrid1_AutoGeneratingColumn(object sender, AutoGeneratingColumnArgs e)
{
     if (e.Column.MappingName == "OrderID")
        e.Cancel = true;
}
AddHandler sfDataGrid1.AutoGeneratingColumn, SfDataGrid1_AutoGeneratingColumn;

Private Sub SfDataGrid1_AutoGeneratingColumn(ByVal sender As Object, ByVal e As AutoGeneratingColumnArgs)
	 If e.Column.MappingName = "OrderID" Then
		e.Cancel = True
	 End If
End Sub

Changing Column Type

The type of column adding to SfDataGrid can be changed by setting the instance of column that has to be added in AutoGeneratingColumn event.
In the below code, column type for UnitPrice property is changed to GridTextColumn by setting instance of GridTextColumn to Column property.

this.sfDataGrid1.AutoGeneratingColumn += SfDataGrid1_AutoGeneratingColumn;
private void SfDataGrid1_AutoGeneratingColumn(object sender, AutoGeneratingColumnArgs e)
{
    if (e.Column.MappingName == "UnitPrice")
    {
        if (e.Column is GridNumericColumn)
        {
            e.Column = new GridTextColumn() { MappingName = "UnitPrice", HeaderText = "Unit    Price" };
        }
    }
}
AddHandler sfDataGrid1.AutoGeneratingColumn, AddressOf SfDataGrid1_AutoGeneratingColumn
Private Sub SfDataGrid1_AutoGeneratingColumn(ByVal sender As Object, ByVal e As AutoGeneratingColumnArgs)
If e.Column.MappingName = "UnitPrice" Then
If TypeOf e.Column Is GridNumericColumn Then
e.Column = New GridTextColumn() With {.MappingName = "UnitPrice", .HeaderText = "Unit    Price"}
End If
End If
End Sub

Changing Property Settings

The properties of the auto generating column can be changed by handling the AutoGeneratingColumn event.

this.sfDataGrid1.AutoGeneratingColumn += SfDataGrid1_AutoGeneratingColumn;
private void SfDataGrid1_AutoGeneratingColumn(object sender, AutoGeneratingColumnArgs e)
{
    if (e.Column.MappingName == "OrderID")
    {
        e.Column.AllowSorting = true;
        e.Column.AllowGrouping = false;
        e.Column.HeaderStyle.BackColor = Color.LightSkyBlue;
        e.Column.CellStyle.BackColor = Color.MediumBlue;
    }
}
AddHandler sfDataGrid1.AutoGeneratingColumn, AddressOf SfDataGrid1_AutoGeneratingColumn

Private Sub SfDataGrid1_AutoGeneratingColumn(ByVal sender As Object, ByVal e As AutoGeneratingColumnArgs)
	If e.Column.MappingName = "OrderID" Then
		e.Column.AllowSorting = True
		e.Column.AllowGrouping = False
		e.Column.HeaderStyle.BackColor = Color.LightSkyBlue
		e.Column.CellStyle.BackColor = Color.MediumBlue
	End If
End Sub

Data Annotations with AutoGenerateColumns

SfDataGrid support to generate the columns based on built-in Data Annotation Attributes. Data Annotations ignored, when the AutoGenerateColumns is set to false.

Exclude Column

The column generation can be skipped by using AutoGenerateField property or by setting the Bindable attribute to false.

[Display(AutoGenerateField = false, Description = "OrderID field is not generated in UI")]

public int OrderID
{
    get { return orderID; }
    set { orderID = value; }
}
<Display(AutoGenerateField := False, Description := "OrderID field is not generated in UI")>
Public Property OrderID() As Integer
	Get
		Return orderID
	End Get
	Set(ByVal value As Integer)
		orderID = value
	End Set
End Property

Filtering

Filtering can be enabled automatically for the field by using Display.AutoGenerateFilter property

[Display(AutoGenerateFilter = true, Description = "Filter enabled for CustomerID column")]

public string CustomerID
{
    get { return customerId; }
    set { customerId = value; }
}
<Display(AutoGenerateFilter := True, Description := "Filter enabled for CustomerID column")>
Public Property CustomerID() As String
	Get
		Return customerId
	End Get
	Set(ByVal value As String)
		customerId = value
	End Set
End Property

Editing

The value of the property can be changed by using Editable attribute.

[Editable(true)]

public string Country
{
    get { return country; }
    set { country = value; }
}
<Editable(True)>
Public Property Country() As String
	Get
		Return country
	End Get
	Set(ByVal value As String)
		country = value
	End Set
End Property

Change the HeaderText of Column

The Header text of column can be customized by using Display.Name property.

[Display(Name="Name of the Customer",Description="CustomerName is necessary for identification ")]

public string CustomerName
{
    get { return customerName; }
    set { customerName = value; }
}
<Display(Name:="Name of the Customer",Description:="CustomerName is necessary for identification ")>
Public Property CustomerName() As String
	Get
		Return customerName
	End Get
	Set(ByVal value As String)
		customerName = value
	End Set
End Property

Change the Order of the Columns

The columns order can be changed by using DisplayAttribute.Order property.

[Display(Order=0)]

public int OrderID
{
    get { return orderID; }
    set { orderID = value; }
}

[Display(Order=-1)]

public string CustomerID
{
    get { return customerId; }
    set { customerId = value; }
}
<Display(Order:=0)>
Public Property OrderID() As Integer
	Get
		Return orderID
	End Get
	Set(ByVal value As Integer)
		orderID = value
	End Set
End Property

<Display(Order:=-1)>
Public Property CustomerID() As String
	Get
		Return customerId
	End Get
	Set(ByVal value As String)
		customerId = value
	End Set
End Property

The OrderID and CustomerID column rearranged based on specified order.
Windows form datagrid showing columns with specified order

Customizing Data Format

The data format can be customized using DataTypeAttribute.DataType property.

[DataType(DataType.Currency)]        

public double  UnitPrice
{
    get { return unitPrice; }
    set { unitPrice = value; }
}
<DataType(DataType.Currency)>
Public Property UnitPrice() As Double
	Get
		Return unitPrice
	End Get
	Set(ByVal value As Double)
		unitPrice = value
	End Set
End Property

Setting Read-only Column

The editing for a column can be disabled by using ReadOnly attribute..

[ReadOnly(true)]

public string Country
{
    get { return country; }
    set { country = value; }
}
<ReadOnly(True)>
Public Property Country() As String
	Get
		Return country
	End Get
	Set(ByVal value As String)
		country = value
	End Set
End Property

Manually Defining Columns

The SfDataGrid allows to define the columns manually by adding the desired column to the SfDataGrid.Columns collection.

this.sfDataGrid1.AutoGenerateColumns = false;
this.sfDataGrid1.DataSource = collection.OrdersListDetails;

this.sfDataGrid1.Columns.Add(new GridTextColumn() { MappingName = "OrderID", HeaderText = "Order ID" });
this.sfDataGrid1.Columns.Add(new GridTextColumn() { MappingName = "CustomerID", HeaderText = "Customer ID" });
this.sfDataGrid1.Columns.Add(new GridTextColumn() { MappingName = "CustomerName", HeaderText = "Customer Name" });
this.sfDataGrid1.Columns.Add(new GridTextColumn() { MappingName = "Country", HeaderText = "Country" });
this.sfDataGrid1.Columns.Add(new GridTextColumn() { MappingName = "ProductName", HeaderText = "Product Name" });
Me.sfDataGrid1.AutoGenerateColumns = False
Me.sfDataGrid1.DataSource = collection.OrdersListDetails

Me.sfDataGrid1.Columns.Add(New GridTextColumn() With {.MappingName = "OrderID", .HeaderText = "Order ID"})
Me.sfDataGrid1.Columns.Add(New GridTextColumn() With {.MappingName = "CustomerID", .HeaderText = "Customer ID"})
Me.sfDataGrid1.Columns.Add(New GridTextColumn() With {.MappingName = "CustomerName", .HeaderText = "Customer Name"})
Me.sfDataGrid1.Columns.Add(New GridTextColumn() With {.MappingName = "Country", .HeaderText = "Country"})
Me.sfDataGrid1.Columns.Add(New GridTextColumn() With {.MappingName = "ProductName", .HeaderText = "Product Name"})

Column Manipulation

The columns (added or auto-generated) can be retrieved from SfDataGrid.Columns property.

Adding Column

The column can be added to the SfDataGrid by adding the instance of the column to SfDataGrid.Columns property.

this.sfDataGrid1.Columns.Add(new GridTextColumn() { MappingName = "OrderID", HeaderText = "Order ID" });
Me.sfDataGrid1.Columns.Add(New GridTextColumn() With {.MappingName = "OrderID", .HeaderText = "Order ID"})

Accessing Column

The column can be accessed through its column index or GridColumnBase.MappingName property from the SfDataGrid.Columns collection.

GridColumn column = this.sfDataGrid1.Columns[1];
// Or
GridColumn column = this.sfDataGrid1.Columns["OrderID"];
Dim column As GridColumn = Me.sfDataGrid1.Columns(1)
' Or
Dim column As GridColumn = Me.sfDataGrid1.Columns("OrderID")

Clearing or Removing Column

All the columns can be removed by clearing the SfDataGrid.Columns collection.

this.sfDataGrid1.Columns.Clear();
Me.sfDataGrid1.Columns.Clear()

A column can be removed using the Remove and RemoveAt methods.

this.sfDataGrid1.Columns.Remove(gridColumn);
// Or
this.sfDataGrid1.Columns.RemoveAt(1);
Me.sfDataGrid1.Columns.Remove(gridColumn)
' Or
Me.sfDataGrid1.Columns.RemoveAt(1)

Column under a stacked column can be removed from StackedHeaderRow.

var childColumns = this.sfDataGrid1.StackedHeaderRows[0].StackedColumns[0].ChildColumns.Split(',');
foreach(var name in childColumns)
{
    var column = this.sfDataGrid1.Columns[name];
    this.sfDataGrid1.Columns.Remove(column);
}
Dim childColumns = Me.sfDataGrid1.StackedHeaderRows(0).StackedColumns(0).ChildColumns.Split(","c)
For Each name In childColumns
	Dim column = Me.sfDataGrid1.Columns(name)
	Me.sfDataGrid1.Columns.Remove(column)
Next name

Changing the order of a column

The order of a column can be changed by using the SfDataGrid.Columns.Move method.

sfDataGrid.Columns.Move(0, 5);
sfDataGrid.Columns.Move(0, 5)

Resizing Columns

SfDataGrid allows to resize the columns like in excel by resizing column header.
This can be enabled or disabled by setting SfDataGrid.AllowResizingColumns 
or GridColumnBase.AllowResizing property.

NOTE

Resizing considers MinimumWidth and MaximumWidth of column.

this.sfDataGrid1.AllowResizingColumns = true;
Me.sfDataGrid1.AllowResizingColumns = True

The column width can be changed by clicking and dragging the resizing cursor at the edge of column header. The resizing cursor appears when you hover the line exists between two columns.
windows forms datagrid showing resize the column

Hidden Column Resizing

SfDataGrid shows indication for hidden columns in column header and also allows end-users to resize the hidden columns when setting SfDataGrid.AllowResizingHiddenColumns property to true.
windows forms datagrid showing hidden column resizing

Disable Resizing

Resizing of particular column can be canceled by setting GridColumnBase.AllowResizing property to false.

In another way, the resizing can be canceled by handling SfDataGrid.ColumnResizing event. The ColumnResizing event occurs when start dragging by resizing cursor on headers.
ColumnResizingEventArgs of ColumnResizing provides information about the column’s index and width.

this.sfDataGrid.ColumnResizing += SfDataGrid_ColumnResizing;

void SfDataGrid_ColumnResizing(object sender, ColumnResizingEventArgs e)
{
    if (e.ColumnIndex == 1)
        e.Cancel = true;
}
AddHandler sfDataGrid.ColumnResizing, AddressOf SfDataGrid_ColumnResizing

Private Sub SfDataGrid_ColumnResizing(ByVal sender As Object, ByVal e As ColumnResizingEventArgs)
	If e.ColumnIndex = 1 Then
		e.Cancel = True
	End If
End Sub

Hiding Columns

You can hide any column in SfDataGrid by using GridColumnBase.Visible property. Refer to the following code example.

this.sfDataGrid.Columns["ProductName"].Visible = false;
Me.sfDataGrid.Columns("ProductName").Visible = False

ProductName column is hidden in winforms datagrid

Column Drag and Drop

SfDataGrid allow end-users to rearrange the columns by drag and drop the column headers by setting SfDataGrid.AllowDraggingColumns to true.

sfDataGrid.AllowDraggingColumns = true;
sfDataGrid.AllowDraggingColumns = True

Windows form datagrid showing drag-and-drop the column

The drag and drop operation for particular column can be enabled or disabled using the AllowDragging property.

sfDataGrid.Columns[0].AllowDragging = false;
sfDataGrid.Columns(0).AllowDragging = False

Disable Column Reordering

The ColumnDragging event occurs when start dragging the column header. The dragging operation of the particular column can canceled by handling the ColumnDragging event. ColumnDraggingEventArgs of ColumnDragging event provides information about the column triggered this event.

Cancel Dragging Operation

SfDataGrid allow to cancel dragging operation for particular column by handling the ColumnDragging event when the e.Reason is ColumnDraggingAction.DragStarting.

sfDataGrid.ColumnDragging += sfDataGrid_ColumnDragging;

void sfDataGrid_ColumnDragging(object sender, Syncfusion.WinForms.DataGrid.Events.ColumnDraggingEventArgs e)
{
    var column = sfDataGrid.Columns[e.From];
    if (column.MappingName == "OrderID" && e.Reason == ColumnDraggingAction.DragStarting)
    {
        e.Cancel = true;
    }
}
AddHandler sfDataGrid.ColumnDragging, AddressOf sfDataGrid_ColumnDragging

Private Sub sfDataGrid_ColumnDragging(ByVal sender As Object, ByVal e As Syncfusion.WinForms.DataGrid.Events.ColumnDraggingEventArgs)
	Dim column = sfDataGrid.Columns(e.From)

	If column.MappingName = "OrderID" AndAlso e.Reason = ColumnDraggingAction.DragStarting Then
		e.Cancel = True
	End If
End Sub

Cancel Column Reordering

SfDataGrid allow to cancel dropping a column at particular column by handling the ColumnDragging event with e.Reason is ColumnDraggingAction.Dropping.

sfDataGrid.ColumnDragging += sfDataGrid_ColumnDragging;

void sfDataGrid_ColumnDragging(object sender, Syncfusion.WinForms.DataGrid.Events.ColumnDraggingEventArgs e)
{
    if (e.Reason == ColumnDraggingAction.Dropping)
    {
        var column = sfDataGrid.Columns[e.To];
        if (column.MappingName == "ProductName")
        {
            e.Cancel = true;
        }
    }
}
AddHandler sfDataGrid.ColumnDragging, AddressOf sfDataGrid_ColumnDragging

Private Sub sfDataGrid_ColumnDragging(ByVal sender As Object, ByVal e As Syncfusion.WinForms.DataGrid.Events.ColumnDraggingEventArgs)
	If e.Reason = ColumnDraggingAction.Dropping Then
		Dim column = sfDataGrid.Columns(e.To)

		If column.MappingName = "ProductName" Then
			e.Cancel = True
		End If
	End If
End Sub

Drag and Drop Customization

The drag-and-drop operations can be changed by overriding the virtual methods of ColumnDragDropController class and assigning it to SfDataGrid.ColumnDragDropController.

sfDataGrid.ColumnDragDropController = new CustomDragAndDropController(sfDataGrid.TableControl, sfDataGrid.GroupPanel);

public class CustomDragAndDropController : ColumnDragDropController
{
    public CustomDragAndDropController(TableControl tableControl, GroupPanel groupPanel)
        : base(tableControl, groupPanel)
    {
    }

    protected override bool CanShowPopup(GridColumn column)
    {
        if (column.MappingName == "UnitPrice")
            return false;
        return base.CanShowPopup(column);
    }

    protected override void PopupDroppedOnHeaderRow(int oldIndex, int newIndex)
    {
        if (newIndex == 0)
            return;
        base.PopupDroppedOnHeaderRow(oldIndex, newIndex);
    }

    protected override void PopupDroppedOnGroupDropArea(GridColumn draggingColumn, MouseEventArgs e)
    {
        if (draggingColumn.MappingName == "OrderID")
            return;
        base.PopupDroppedOnGroupDropArea(draggingColumn, e);
    }
}
sfDataGrid.ColumnDragDropController = New CustomDragAndDropController(sfDataGrid.TableControl, sfDataGrid.GroupPanel)

public class CustomDragAndDropController : ColumnDragDropController
	public CustomDragAndDropController(TableControl tableControl, GroupPanel groupPanel)
		MyBase.New(tableControl, groupPanel)


	protected override Boolean CanShowPopup(GridColumn column)
		If column.MappingName = "UnitPrice" Then
			Return False
		End If
		Return MyBase.CanShowPopup(column)

	protected override void PopupDroppedOnHeaderRow(Integer oldIndex, Integer newIndex)
		If newIndex = 0 Then
			Return
		End If
		MyBase.PopupDroppedOnHeaderRow(oldIndex, newIndex)

	protected override void PopupDroppedOnGroupDropArea(GridColumn draggingColumn, MouseEventArgs e)
		If draggingColumn.MappingName = "OrderID" Then
			Return
		End If
		MyBase.PopupDroppedOnGroupDropArea(draggingColumn, e)

Disabling Drag and Drop between Frozen and Non-frozen Columns

By default, the columns re-ordering performed between any column regions of columns. The dropping action can cancel between the frozen and non-frozen columns by handling SfDataGrid.ColumnDragging event.

sfDataGrid.ColumnDragging += sfDataGrid_ColumnDragging;

void sfDataGrid_ColumnDragging(object sender, Syncfusion.WinForms.DataGrid.Events.ColumnDraggingEventArgs e)
{
    if (e.Reason == ColumnDraggingAction.Dropping)
    {
        var frozenColIndex = this.sfDataGrid.FrozenColumnCount + this.sfDataGrid.TableControl.ResolveToStartColumnIndex();
        if (e.From < frozenColIndex && e.To > frozenColIndex - 1)
            e.Cancel = true;
        if (e.From > frozenColIndex && e.To < frozenColIndex || (e.From == frozenColIndex && e.To < frozenColIndex))
            e.Cancel = true;
    }
}
AddHandler sfDataGrid.ColumnDragging, AddressOf sfDataGrid_ColumnDragging

Private Sub sfDataGrid_ColumnDragging(ByVal sender As Object, ByVal e As Syncfusion.WinForms.DataGrid.Events.ColumnDraggingEventArgs)
	If e.Reason = ColumnDraggingAction.Dropping Then
		Dim frozenColIndex = Me.sfDataGrid.FrozenColumnCount + Me.sfDataGrid.TableControl.ResolveToStartColumnIndex()
		If e.From < frozenColIndex AndAlso e.To > frozenColIndex - 1 Then
			e.Cancel = True
		End If
		If e.From > frozenColIndex AndAlso e.To < frozenColIndex OrElse (e.From Is frozenColIndex AndAlso e.To < frozenColIndex) Then
			e.Cancel = True
		End If
	End If
End Sub

NOTE

FrozenColumnCount and FooterColumnCount should be lesser than the number of columns that can be displayed in view.

Stacked Headers

SfDataGrid supports additional unbound header rows known as StackedHeaderRows that span across the DataGrid columns using StackedHeaderRows. SfDataGrid allows to group one or more columns under each stacked header. Each StackedHeaderRow contains the StackedColumns where each StackedColumn contains a number of child columns.
StackedColumn.ChildColumns property returns the columns which are grouped under the stacked header row. StackedColumn.HeaderText returns the text that displays in stacked header row.

Adding Stacked header

The stacked headers can be added by using the below steps,

  1. Create an object of StackedHeaderRow for adding stacked columns.

  2. Add the columns using ChildColumns property of StackedColumn.

  3. Add the StackedColumn to StackedColumns collection.

  4. Finally add the StackedHeaderRow to StackedHeaderRows collection of the SfDataGrid.

//Creating object for a stacked header row.
var stackedHeaderRow1 = new StackedHeaderRow();

//Adding stacked column to stacked columns collection available in stacked header row object.
stackedHeaderRow1.StackedColumns.Add(new StackedColumn() { ChildColumns = "OrderID,OrderDate", HeaderText = "Order Details" });
stackedHeaderRow1.StackedColumns.Add(new StackedColumn() { ChildColumns = "CustomerID,ContactNumber,", HeaderText = "Customer Details" });
stackedHeaderRow1.StackedColumns.Add(new StackedColumn() { ChildColumns = "ProductName,Quantity,UnitPrice,ShipCountry", HeaderText = "Product Details" });

//Adding stacked header row object to stacked header row collection available in SfDataGrid.
sfDataGrid.StackedHeaderRows.Add(stackedHeaderRow1);
'Creating object for a stacked header row.
Dim stackedHeaderRow1 = New StackedHeaderRow()

'Adding stacked column to stacked columns collection available in stacked header row object.
stackedHeaderRow1.StackedColumns.Add(New StackedColumn() With {.ChildColumns = "OrderID,OrderDate", .HeaderText = "Order Details"})
stackedHeaderRow1.StackedColumns.Add(New StackedColumn() With {.ChildColumns = "CustomerID,ContactNumber,", .HeaderText = "Customer Details"})
stackedHeaderRow1.StackedColumns.Add(New StackedColumn() With {.ChildColumns = "ProductName,Quantity,UnitPrice,ShipCountry", .HeaderText = "Product Details"})

'Adding stacked header row object to stacked header row collection available in SfDataGrid.
sfDataGrid.StackedHeaderRows.Add(stackedHeaderRow1)

Windows form datagrid showing stacked header

Adding Child Columns

SfDataGrid allows to add the child columns in a particular stacked header directly.

//Previous Child columns.
string previousChild = this.sfDataGrid.StackedHeaderRows[0].StackedColumns[0].ChildColumns;

//Adding ChildColumns to stacked header rows with additional child column. 
this.sfDataGrid.StackedHeaderRows[0].StackedColumns[0].ChildColumns = previousChild + ",CustomerID";
'Previous Child columns.
Dim previousChild As String = Me.sfDataGrid.StackedHeaderRows(0).StackedColumns(0).ChildColumns

'Adding ChildColumns to stacked header rows with additional child column. 
Me.sfDataGrid.StackedHeaderRows(0).StackedColumns(0).ChildColumns = previousChild & ",CustomerID"

Windows form datagrid showing child columns

Removing Child Columns

SfDataGrid allows to remove the child columns from particular stacked header directly.

//Removing ChildColumns from the stacked header row.
 var removingColumns = this.sfDataGrid.StackedHeaderRows[0].StackedColumns[0].ChildColumns.Split(',').ToList<string>();
string childColumns = string.Empty;
foreach (var stackedColumnName in removingColumns.ToList())
{
    if (stackedColumnName.Equals("OrderID"))
    {
        removingColumns.Remove(stackedColumnName);
    }
    else
        childColumns = childColumns + stackedColumnName + ",";
}
this.sfDataGrid.StackedHeaderRows[0].StackedColumns[0].ChildColumns = childColumns;
'Removing ChildColumns from the stacked header row.
 Dim removingColumns = Me.sfDataGrid.StackedHeaderRows(0).StackedColumns(0).ChildColumns.Split(","c).ToList(Of String)()
Dim childColumns As String = String.Empty
For Each stackedColumnName In removingColumns.ToList()
	If stackedColumnName.Equals("OrderID") Then
		removingColumns.Remove(stackedColumnName)
	Else
		childColumns = childColumns & stackedColumnName & ","
	End If
Next stackedColumnName
Me.sfDataGrid.StackedHeaderRows(0).StackedColumns(0).ChildColumns = childColumns

Windows form datagrid showing removing child columns

Multi Stacked Headers

Multiple stacked headers can be added to SfDataGrid by adding the required number of StackedHeaderRow to SfDataGrid.StackedHeaderRowsproperty.

//Creating instance for StackedHeaderRow
StackedHeaderRow stackedHeaderRow1 = new StackedHeaderRow();
StackedHeaderRow stackedHeaderRow2 = new StackedHeaderRow();

//Adding columns to StackedColumns collection to StackedHeaderRow object.
stackedHeaderRow1.StackedColumns.Add(new StackedColumn() { ChildColumns = "OrderID,CustomerID,ContactNumber,OrderDate,ProductName,Quantity", HeaderText = "Sales Details" });

stackedHeaderRow2.StackedColumns.Add(new StackedColumn() { ChildColumns = "OrderID", HeaderText = "Order Details" });
stackedHeaderRow2.StackedColumns.Add(new StackedColumn() { ChildColumns = "CustomerID,ContactNumber", HeaderText = "Customer Details" });
stackedHeaderRow2.StackedColumns.Add(new StackedColumn() { ChildColumns = "OrderDate,ProductName,Quantity", HeaderText = "Product Details" });


//Adding StackedHeaderRow object to StackedHeaderRows collection of SfDatagrid.
this.sfDataGrid.StackedHeaderRows.Add(stackedHeaderRow1);
this.sfDataGrid.StackedHeaderRows.Add(stackedHeaderRow2);
'Creating instance for StackedHeaderRow
Dim stackedHeaderRow1 As New StackedHeaderRow()
Dim stackedHeaderRow2 As New StackedHeaderRow()

'Adding columns to StackedColumns collection to StackedHeaderRow object.
stackedHeaderRow1.StackedColumns.Add(New StackedColumn() With {.ChildColumns = "OrderID,CustomerID,ContactNumber,OrderDate,ProductName,Quantity", .HeaderText = "Sales Details"})

stackedHeaderRow2.StackedColumns.Add(New StackedColumn() With {.ChildColumns = "OrderID", .HeaderText = "Order Details"})
stackedHeaderRow2.StackedColumns.Add(New StackedColumn() With {.ChildColumns = "CustomerID,ContactNumber", .HeaderText = "Customer Details"})
stackedHeaderRow2.StackedColumns.Add(New StackedColumn() With {.ChildColumns = "OrderDate,ProductName,Quantity", .HeaderText = "Product Details"})


'Adding StackedHeaderRow object to StackedHeaderRows collection of SfDatagrid.
Me.sfDataGrid.StackedHeaderRows.Add(stackedHeaderRow1)
Me.sfDataGrid.StackedHeaderRows.Add(stackedHeaderRow2)

Windows form datagrid showing multi stacked headers

Appearance

Stacked Header Row Appearance

The appearance of stacked header row can be customized by setting the StackedHeaderStyle property. The StackedHeaderStyle property contains all the settings that are needed for the stacked header row appearance customization.

this.sfDataGrid.Style.StackedHeaderStyle.BackColor = Color.DarkCyan;
this.sfDataGrid.Style.StackedHeaderStyle.TextColor = Color.White;
Me.sfDataGrid.Style.StackedHeaderStyle.BackColor = Color.DarkCyan
Me.sfDataGrid.Style.StackedHeaderStyle.TextColor = Color.White

Windows form datagrid showing stacked header row appearance

Changing the Stacked Header Appearance based on Column

An appearance of the stacked header row can be customized by using DrawCell event. SfDataGrid allow to check the row type for stacked header row by getting the property from (e.DataRow as DataRowBase).RowType of DrawCellEventArgs.
SfDataGrid allows to check the stacked column by its cell value which is available in DrawCellEventArgs ​and apply styling using ‘e.Style’ property of DrawCellEventArgs

this.sfDataGrid.DrawCell += SfDataGrid_DrawCell;

private void SfDataGrid_DrawCell(object sender, DrawCellEventArgs e)
{
    if ((e.DataRow as DataRowBase).RowType == RowType.StackedHeaderRow)
    {
        if (e.CellValue == "Order Details")
        {
            e.Style.BackColor = Color.DarkCyan;
            e.Style.TextColor = Color.White;
        }
        if (e.CellValue == "Customer Details")
        {
            e.Style.BackColor = Color.LightCyan;
        }
        if (e.CellValue == "Product Details")
        {
            e.Style.BackColor = Color.DarkGray;
            e.Style.TextColor = Color.White;
        }
    }
}
AddHandler sfDataGrid.DrawCell, AddressOf SfDataGrid_DrawCell

Private Sub SfDataGrid_DrawCell(ByVal sender As Object, ByVal e As DrawCellEventArgs)
	If (TryCast(e.DataRow, DataRowBase)).RowType = RowType.StackedHeaderRow Then
		If e.CellValue = "Order Details" Then
			e.Style.BackColor = Color.DarkCyan
			e.Style.TextColor = Color.White
		End If
		If e.CellValue = "Customer Details" Then
			e.Style.BackColor = Color.LightCyan
		End If
		If e.CellValue = "Product Details" Then
			e.Style.BackColor = Color.DarkGray
			e.Style.TextColor = Color.White
		End If
	End If
End Sub

Windows form datagrid showing stacked header column appearance

Font orientation for stacked headers

Font orientation of the stacked header cells can be set by using the StackedHeaderStyle.Font.Orientation property.

//Creating object for a stacked header row.
var stackedHeaderRow1 = new StackedHeaderRow();

//Adding stacked column to stacked columns collection available in stacked header row object.
stackedHeaderRow1.StackedColumns.Add(new StackedColumn() { ChildColumns = "OrderID,OrderDate", HeaderText = "Order" });
stackedHeaderRow1.StackedColumns.Add(new StackedColumn() { ChildColumns = "CustomerID,ContactNumber,", HeaderText = "Customer" });
stackedHeaderRow1.StackedColumns.Add(new StackedColumn() { ChildColumns = "ProductName,Quantity,UnitPrice,ShipCountry", HeaderText = "Product" });

//Adding stacked header row object to stacked header row collection available in SfDataGrid.
sfDataGrid1.StackedHeaderRows.Add(stackedHeaderRow1);

this.sfDataGrid1.HeaderRowHeight = 60;

//Set the font orientation for the stacked headers
this.sfDataGrid1.Style.StackedHeaderStyle.Font.Orientation = 45;
'Creating object for a stacked header row.
Dim stackedHeaderRow1 = New StackedHeaderRow()

'Adding stacked column to stacked columns collection available in stacked header row object.
stackedHeaderRow1.StackedColumns.Add(New StackedColumn() With {.ChildColumns = "OrderID,OrderDate", .HeaderText = "Order"})
stackedHeaderRow1.StackedColumns.Add(New StackedColumn() With {.ChildColumns = "CustomerID,ContactNumber,", .HeaderText = "Customer"})
stackedHeaderRow1.StackedColumns.Add(New StackedColumn() With {.ChildColumns = "ProductName,Quantity,UnitPrice,ShipCountry", .HeaderText = "Product"})

'Adding stacked header row object to stacked header row collection available in SfDataGrid.
sfDataGrid1.StackedHeaderRows.Add(stackedHeaderRow1)

Me.sfDataGrid1.HeaderRowHeight = 60

'Set the font orientation for the stacked headers
Me.sfDataGrid1.Style.StackedHeaderStyle.Font.Orientation = 45

Windows form datagrid showing stacked header style

Column Sizing

SfDataGrid allows to set the column widths based on certain logic using SfDataGrid.AutoSizeColumnsMode or GridColumnBase.AutoSizeColumnsMode property. Below is the list of predefined column sizing options available.

Name Description
AllCells Calculates the width of column based on header and cell contents. So, header and cell contents are not truncated.
AllCellsExceptHeader Calculates the width of column based on cell contents. So, cell contents are not truncated.
AllCellsWithLastColumnFill Applies

AutoSizeColumnsMode.AllCells

width to all the columns except last column which is visible and sets the maximum between last column auto spacing width and remaining width to last column.
ColumnHeader Calculates the width of column based on header content. So, header content is not truncated.
Fill Divides the total width equally for columns.
LastColumnFill Applies

AutoSizeColumnsMode.AllCells

width to all the columns except last column which is visible and the remaining width from total width of SfDataGrid is set to last column.
None No sizing. Default column width or defined width set to column.

NOTE

AutoSizeColumnsMode will not work when the column width defined explicitly. AutoSizeCalculationMode calculates column width based on MinimumWidth and MaximumWidth  properties of the column.

Below code, applies AutoSizeColumnsMode.Fill to equally set width for SfDataGrid.Columns.

OrderInfoCollection collection = new OrderInfoCollection();
sfDataGrid.DataSource = collection.OrdersListDetails;
sfDataGrid.AutoSizeColumnsMode = AutoSizeColumnsMode.Fill;
Dim collection As New OrderInfoCollection()
sfDataGrid.DataSource = collection.OrdersListDetails
sfDataGrid.AutoSizeColumnsMode = AutoSizeColumnsMode.Fill

Windows form datagrid showing column size

NOTE

The GridColumnBase.AutoSizeColumnsMode takes higher priority than the SfDataGrid.AutoSizeColumnsMode.

Fill Remaining Width for any Column

While setting SfDataGrid.AutoSizeColumnsMode as LastColumnFill or AllCellsWithLastColumnFill remaining width is applied to last column. The remaining width to specific column can be applied by setting GridColumnBase.AutoSizeColumnsMode property as like below,

this.sfDataGrid.AutoSizeColumnsMode = AutoSizeColumnsMode.LastColumnFill;
this.sfDataGrid.Columns["ProductName"].AutoSizeColumnsMode = AutoSizeColumnsMode.LastColumnFill;
Me.sfDataGrid.AutoSizeColumnsMode = AutoSizeColumnsMode.LastColumnFill
Me.sfDataGrid.Columns("ProductName").AutoSizeColumnsMode = AutoSizeColumnsMode.LastColumnFill

Windows form datagrid showing auto-generated column size

Auto Size based on String Length

By default, the auto size of the column is calculated based on the string width. To improve the performance of the column auto sizing, the column auto size calculation logic can be calculated based on the length of the values by using SfDataGrid.AutoSizeController.AutoSizeCalculationMode property.
The default is AutoSizeCalculationMode.Default which calculates size for all the cell’s formatted text. The columns can also be auto sized based on string length of the cell using the AutoSizeCalculationMode.SmartFit which calculates the size for the cell which has longest string.

this.sfDataGrid. AutoSizeController.AutoSizeCalculationMode = AutoSizeCalculationMode.SmartFit;
this.sfDataGrid.AutoSizeColumnsMode = AutoSizeColumnsMode.AllCells;
Me.sfDataGrid.AutoSizeController.AutoSizeCalculationMode = AutoSizeCalculationMode.SmartFit
Me.sfDataGrid.AutoSizeColumnsMode = AutoSizeColumnsMode.AllCells

Column Auto Sizing for Visible Rows

By default, the column auto size is calculated for the whole rows. The column auto size can be calculated for the visible rows only by using the AutoSizeController.AutoSizeRange property.
The default is AutoSizeRange.Table which considers all the records in the table for auto sizing. The columns can be auto sized considering only the visible rows using the AutoSizeRange.VisibleRows mode as like below.

this.sfDataGrid.AutoSizeController.AutoSizeRange = AutoSizeRange.VisibleRows;
Me.sfDataGrid.AutoSizeController.AutoSizeRange = AutoSizeRange.VisibleRows

Refreshing ColumnSizer at Runtime

The auto column sizing can be refreshed at by calling SfDataGrid.AutoSizeController.Refresh method. The column auto width can be recalculated by calling the reset methods of AutoSizeController. The ResetAutoSizeWidthForAllColumns method reset widths to all columns. ResetAutoSizeWidth method reset the width to specific column.

NOTE

The column does not auto size its width automatically when the data of that column get changed.
For example, you can refresh all the column’s width based on the cell contents of newly added records at runtime.

var orderInfoCollection = this.sfDataGrid.DataSource as OrderInfoCollection;
orderInfoCollection.Orders.Add(new OrderInfo() { OrderID = 11, CustomerID = "BLFKI", ProductName = "Boston Crab Meat" });

this.sfDataGrid1.AutoSizeController.ResetAutoSizeWidthForAllColumns();
this.sfDataGrid1.AutoSizeController.Refresh();
Dim orderInfoCollection = TryCast(Me.sfDataGrid.DataSource, OrderInfoCollection)
orderInfoCollection.Orders.Add(New OrderInfo() With {.OrderID = 11, .CustomerID = "BLFKI", .ProductName = "Boston Crab Meat"})

Me.sfDataGrid1.AutoSizeController.ResetAutoSizeWidthForAllColumns()
Me.sfDataGrid1.AutoSizeController.Refresh()

Resetting Column Width to Apply AutoSizeColumnsMode

When the width of the column is explicitly defined or column is resized, column width is not changed based on AutoSizeColumnsMode. You can reset GridColumnBase.Width by setting -1 to apply column width based on column sizer.

foreach (var column in this.sfDataGrid.Columns)
{
    if (column.Width != 0)
        column.Width = -1;
}
this.sfDataGrid1.ColumnSizer.Refresh();
For Each column In Me.sfDataGrid.Columns
	If column.Width <> 0 Then
		column.Width = -1
	End If
Next column
Me.sfDataGrid1.ColumnSizer.Refresh()

Customizing Built-in Column Sizing Logic

The column auto sizing operations of the SfDataGrid is processed in the AutoSizeController class. The column sizing operations can be customized by overriding AutoSizeController and set it to SfDataGrid.AutoSizeController property.

this.sfDataGrid.AutoSizeController = new CustomGridColumnSizer(this.sfDataGrid);

public class CustomGridColumnSizer : AutoSizeController
{
    public CustomGridColumnSizer(SfDataGrid sfDataGrid)
        : base(sfDataGrid)
    { }

    // Calculate width for column when AutoSizeColumnsMode is AllCells.     
    protected override double CalculateAllCellsWidth(GridColumn column, bool isAllCells = false)
    {
        return base.CalculateAllCellsWidth(column, isAllCells);
    }

    // Calculate width for column when AutoSizeColumnsMode is ColumnHeader.     
    protected override int CalculateColumnHeaderWidth(GridColumn column, bool setWidth = true)
    {
        return base.CalculateColumnHeaderWidth(column, setWidth);
    }

    // Calculate width for column when AutoSizeColumnsMode is AllCellsExceptHeaderWidth.     
    protected override double CalculateAllCellsExceptHeaderWidth(GridColumn column, bool setWidth = true)
    {
        return base.CalculateAllCellsExceptHeaderWidth(column, setWidth);
    }
}
Me.sfDataGrid.AutoSizeController = New CustomGridColumnSizer(Me.sfDataGrid)

public class CustomGridColumnSizer : AutoSizeController
	public CustomGridColumnSizer(SfDataGrid sfDataGrid)
		MyBase.New(sfDataGrid)

	' Calculate width for column when AutoSizeColumnsMode is AllCells.     
	protected override Double CalculateAllCellsWidth(GridColumn column, Boolean isAllCells = False)
		Return MyBase.CalculateAllCellsWidth(column, isAllCells)

	' Calculate width for column when AutoSizeColumnsMode is ColumnHeader.     
	protected override Integer CalculateColumnHeaderWidth(GridColumn column, Boolean setWidth = True)
		Return MyBase.CalculateColumnHeaderWidth(column, setWidth)

	' Calculate width for column when AutoSizeColumnsMode is AllCellsExceptHeaderWidth.     
	protected override Double CalculateAllCellsExceptHeaderWidth(GridColumn column, Boolean setWidth = True)
		Return MyBase.CalculateAllCellsExceptHeaderWidth(column, setWidth)

Custom Column Sizer with Ratio Support

The AutoSizeColumnsMode.Fill width calculation logic can be customized by overriding SetFillWidth method of AutoSizeController.
For example, the column width can be calculated with specified ratios instead of dividing equal width for all columns in AutoSizeColumnsMode.Fill calculation using the logic in below FillRatio class.

public static class FillRatio
{
    // Returns the fill ratio for the column.
    public static int GetColumnRatio(GridColumn column)
    {
        int i = 0;
        switch (column.MappingName)
        {
            case "OrderID":
            case "CustomerID":
            case "Quantity":
            case "ShipCountry":
                i = 1;
                break;

            case "ProductName":
                i = 3;
                break;

            case "OrderDate":
                i = 2;
                break;
        }

        return i;
    }
}
Public NotInheritable Class FillRatio
	' Returns the fill ratio for the column.
	Private Sub New()
	End Sub
	Public Shared Function GetColumnRatio(ByVal column As GridColumn) As Integer
		Dim i As Integer = 0
		Select Case column.MappingName
			Case "OrderID", "CustomerID", "Quantity", "ShipCountry"
				i = 1

			Case "ProductName"
				i = 3

			Case "OrderDate"
				i = 2
		End Select

		Return i
	End Function
End Class

Below code to define the fill width calculation based on the FillRatio.

public class CustomGridColumnSizer : AutoSizeController
{
    public CustomGridColumnSizer(SfDataGrid sfDataGrid)
        : base(sfDataGrid)
    {    }

    // Overridden to customize the AutoSizeColumnsMode.Fill logic.
    protected override void SetFillWidth(double remainingColumnWidth, IEnumerable<GridColumn> remainingColumns)
    {
        var removedColumn = new List<GridColumn>();
        var columns = remainingColumns.ToList();
        var totalRemainingFillValue = remainingColumnWidth;
        double removedWidth = 0;
        bool isRemoved;

        while (columns.Count > 0)
        {
            isRemoved = false;
            removedWidth = 0;
            var columnsCount = 0;

            columns.ForEach((col) =>
            {
                columnsCount += FillRatio.GetColumnRatio(col);
            });

            double fillWidth = Math.Floor((totalRemainingFillValue / columnsCount));
            var column = columns.First();
            fillWidth *= FillRatio.GetColumnRatio(column);
            double computedWidth = SetColumnWidth(column, (int)fillWidth);

            if (fillWidth != computedWidth && fillWidth > 0)
            {
                isRemoved = true;
                columns.Remove(column);
                foreach (var remColumn in removedColumn)
                {
                    if (!columns.Contains(remColumn))
                    {
                        removedWidth += remColumn.ActualWidth;
                        columns.Add(remColumn);
                    }
                }
                removedColumn.Clear();
                totalRemainingFillValue += removedWidth;
            }

            totalRemainingFillValue = totalRemainingFillValue - computedWidth;

            if (!isRemoved)
            {
                columns.Remove(column);
                if (!removedColumn.Contains(column))
                    removedColumn.Add(column);
            }
        }
    }
}
Public Class CustomGridColumnSizer
	Inherits AutoSizeController
	Public Sub New(ByVal sfDataGrid As SfDataGrid)
		MyBase.New(sfDataGrid)
	End Sub

	' Overridden to customize the AutoSizeColumnsMode.Fill logic.
	Protected Overrides Sub SetFillWidth(ByVal remainingColumnWidth As Double, ByVal remainingColumns As IEnumerable(Of GridColumn))
		Dim removedColumn = New List(Of GridColumn)()
		Dim columns = remainingColumns.ToList()
		Dim totalRemainingFillValue = remainingColumnWidth
		Dim removedWidth As Double = 0
		Dim isRemoved As Boolean

		Do While columns.Count > 0
			isRemoved = False
			removedWidth = 0
			Dim columnsCount = 0

            For Each col As GridColumn In columns
                columnsCount += FillRatio.GetColumnRatio(col)
            Next

			Dim fillWidth As Double = Math.Floor((totalRemainingFillValue / columnsCount))
			Dim column = columns.First()
			fillWidth *= FillRatio.GetColumnRatio(column)
			Dim computedWidth As Double = SetColumnWidth(column, CInt(Fix(fillWidth)))

			If fillWidth <> computedWidth AndAlso fillWidth > 0 Then
				isRemoved = True
				columns.Remove(column)
				For Each remColumn In removedColumn
					If Not columns.Contains(remColumn) Then
						removedWidth += remColumn.ActualWidth
						columns.Add(remColumn)
					End If
				Next remColumn
				removedColumn.Clear()
				totalRemainingFillValue += removedWidth
			End If

			totalRemainingFillValue = totalRemainingFillValue - computedWidth

			If Not isRemoved Then
				columns.Remove(column)
				If Not removedColumn.Contains(column) Then
					removedColumn.Add(column)
				End If
			End If
		Loop
	End Sub
End Class

Below code to set the SfDataGrid.AutoSizeController to apply the custom logic for fill mode.

this.sfDataGrid.AutoGenerateColumns = false;
OrderInfoCollection orderInfoCollection = new OrderInfoCollection();
this.sfDataGrid.DataSource = orderInfoCollection.OrdersListDetails;

this.sfDataGrid.Columns.Add(new GridTextColumn() { MappingName = "OrderID" });
this.sfDataGrid.Columns.Add(new GridTextColumn() { MappingName = "CustomerID" });
this.sfDataGrid.Columns.Add(new GridTextColumn() { MappingName = "ProductName" });
this.sfDataGrid.Columns.Add(new GridDateTimeColumn() { MappingName = "OrderDate" });
this.sfDataGrid.Columns.Add(new GridNumericColumn() { MappingName = "Quantity" });
this.sfDataGrid.Columns.Add(new GridTextColumn() { MappingName = "ShipCountry" });

// Assigns the CustomGridColumnSizer to SfDataGrid.
this.sfDataGrid.AutoSizeController = new CustomGridColumnSizer(this.sfDataGrid);

this.sfDataGrid.AutoSizeColumnsMode = AutoSizeColumnsMode.Fill;
Me.sfDataGrid.AutoGenerateColumns = False
Dim orderInfoCollection As New OrderInfoCollection()
Me.sfDataGrid.DataSource = orderInfoCollection.OrdersListDetails

Me.sfDataGrid.Columns.Add(New GridTextColumn() With {.MappingName = "OrderID"})
Me.sfDataGrid.Columns.Add(New GridTextColumn() With {.MappingName = "CustomerID"})
Me.sfDataGrid.Columns.Add(New GridTextColumn() With {.MappingName = "ProductName"})
Me.sfDataGrid.Columns.Add(New GridDateTimeColumn() With {.MappingName = "OrderDate"})
Me.sfDataGrid.Columns.Add(New GridNumericColumn() With {.MappingName = "Quantity"})
Me.sfDataGrid.Columns.Add(New GridTextColumn() With {.MappingName = "ShipCountry"})

' Assigns the CustomGridColumnSizer to SfDataGrid.
Me.sfDataGrid.AutoSizeController = New CustomGridColumnSizer(Me.sfDataGrid)

Me.sfDataGrid.AutoSizeColumnsMode = AutoSizeColumnsMode.Fill

Windows form datagrid showing fill the auto-generated column size