7.5 KiB
Column Sizing in SfDataGrid
Table of Contents
- ColumnWidthMode Options
- Basic Usage
- Per-Column Width Mode
- Calculate Autofit for All Rows
- Custom Autofit Padding
- Autofit with Custom TextStyle
- Autofit with Formatted Values
- Fill Remaining Width for a Specific Column
- Recalculate Widths on Data Change
ColumnWidthMode Options
Set SfDataGrid.columnWidthMode (grid-level) or GridColumn.columnWidthMode (per-column) to
control how column widths are calculated.
| Mode | Description |
|---|---|
ColumnWidthMode.auto |
Fits to both the header label and cell values — nothing is truncated |
ColumnWidthMode.fitByCellValue |
Fits to cell values only — header may truncate |
ColumnWidthMode.fitByColumnName |
Fits to the header label only — cells may truncate |
ColumnWidthMode.lastColumnFill |
All columns use default width; the last visible column fills remaining space |
ColumnWidthMode.fill |
Divides total grid width equally across all columns |
ColumnWidthMode.none |
No automatic sizing — uses GridColumn.width or defaultColumnWidth |
Note:
columnWidthModeis ignored whenGridColumn.widthis set explicitly.
GridColumn.columnWidthModetakes priority overSfDataGrid.columnWidthMode.
Basic Usage
Set columnWidthMode at the grid level to apply to all columns:
SfDataGrid(
source: _employeeDataSource,
columnWidthMode: ColumnWidthMode.fill, // equal width for all columns
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text('ID', overflow: TextOverflow.ellipsis),
),
),
GridColumn(
columnName: 'name',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text('Name', overflow: TextOverflow.ellipsis),
),
),
GridColumn(
columnName: 'designation',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerLeft,
child: Text('Designation', overflow: TextOverflow.ellipsis),
),
),
GridColumn(
columnName: 'salary',
label: Container(
padding: EdgeInsets.symmetric(horizontal: 16.0),
alignment: Alignment.centerRight,
child: Text('Salary', overflow: TextOverflow.ellipsis),
),
),
],
)
Per-Column Width Mode
Override the grid-level mode for a specific column using GridColumn.columnWidthMode:
SfDataGrid(
source: _employeeDataSource,
columnWidthMode: ColumnWidthMode.lastColumnFill, // default for other columns
columns: <GridColumn>[
GridColumn(
columnName: 'id',
label: ...,
),
GridColumn(
columnName: 'name',
columnWidthMode: ColumnWidthMode.lastColumnFill, // this column fills remaining space
label: ...,
),
GridColumn(
columnName: 'salary',
label: ...,
),
GridColumn(
columnName: 'designation',
label: ...,
),
],
)
Calculate Autofit for All Rows
By default, autofit considers only visible rows. To base the calculation on all rows, set
columnWidthCalculationRange to ColumnWidthCalculationRange.allRows:
SfDataGrid(
source: _employeeDataSource,
columnWidthMode: ColumnWidthMode.auto,
columnWidthCalculationRange: ColumnWidthCalculationRange.allRows,
columns: <GridColumn>[
GridColumn(
columnName: 'ID',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.centerRight,
child: Text('ID', softWrap: false),
),
),
GridColumn(
columnName: 'Name',
label: Container(
padding: EdgeInsets.all(16.0),
alignment: Alignment.centerLeft,
child: Text('Name', softWrap: false),
),
),
],
)
Custom Autofit Padding
By default autofit adds EdgeInsets.all(16.0) around each cell's text. Override per-column with
GridColumn.autoFitPadding. The cell Container.padding and autoFitPadding must match to
ensure correct width calculation:
GridColumn(
columnName: 'id',
autoFitPadding: EdgeInsets.all(10.0), // must match container padding
label: Container(
padding: EdgeInsets.all(10.0),
alignment: Alignment.centerRight,
child: Text('ID', softWrap: false),
),
),
Autofit with Custom TextStyle
When cells use a non-default TextStyle, override ColumnSizer to pass the correct style into
the width calculation:
class CustomColumnSizer extends ColumnSizer {
@override
double computeHeaderCellWidth(GridColumn column, TextStyle style) {
if (column.columnName == 'Name' || column.columnName == 'Designation') {
style = TextStyle(fontWeight: FontWeight.bold, fontStyle: FontStyle.italic);
}
return super.computeHeaderCellWidth(column, style);
}
@override
double computeCellWidth(GridColumn column, DataGridRow row,
Object? cellValue, TextStyle textStyle) {
if (column.columnName == 'Name' || column.columnName == 'Designation') {
textStyle = TextStyle(fontWeight: FontWeight.bold, fontStyle: FontStyle.italic);
}
return super.computeCellWidth(column, row, cellValue, textStyle);
}
}
// Pass the custom sizer to SfDataGrid:
final CustomColumnSizer _customColumnSizer = CustomColumnSizer();
SfDataGrid(
source: _employeeDataSource,
columnSizer: _customColumnSizer,
columnWidthMode: ColumnWidthMode.auto,
columns: [...],
)
Autofit with Formatted Values
When cells display formatted values (e.g., DateFormat, NumberFormat), override
computeCellWidth to pass the formatted string instead of the raw value:
import 'package:intl/intl.dart';
class CustomColumnSizer extends ColumnSizer {
@override
double computeCellWidth(GridColumn column, DataGridRow row,
Object? cellValue, TextStyle textStyle) {
if (column.columnName == 'DOB') {
cellValue = DateFormat.yMMMMd('en_US').format(cellValue as DateTime);
} else if (column.columnName == 'Salary') {
cellValue = NumberFormat.simpleCurrency(decimalDigits: 0).format(cellValue);
}
return super.computeCellWidth(column, row, cellValue, textStyle);
}
}
Fill Remaining Width for a Specific Column
Using ColumnWidthMode.lastColumnFill at the grid level fills the last visible column. To fill
a specific column, set GridColumn.columnWidthMode on that column instead:
// Grid level: no mode (columns use default width)
// Column level: 'name' fills remaining space
GridColumn(
columnName: 'name',
columnWidthMode: ColumnWidthMode.lastColumnFill,
label: ...,
),
Recalculate Widths on Data Change
Column widths are calculated once on initial load. To recalculate when data changes at runtime,
override shouldRecalculateColumnWidths in your DataGridSource and return true:
Returning
truerecalculates on everynotifyListeners()call. Only do this when column content genuinely changes width — it may impact performance for large datasets.
class EmployeeDataSource extends DataGridSource {
// ...
@override
bool shouldRecalculateColumnWidths() {
return true;
}
}