Filter Row in MAUI DataGrid (SfDataGrid)
18 Nov 201824 minutes to read
The SfDataGrid includes a built-in Filter Row designed for efficient record filtering. You can enable the FilterRow by specifying the position where it should be displayed by setting SfDataGrid.FilterRowPosition property. Available positions include FixedTop, FixedBottom, and Scrollable.
<syncfusion:SfDataGrid x:Name="dataGrid"
FilterRowPosition="FixedTop"
SelectionMode="Single"
ItemsSource="{Binding Orders}" >SfDataGrid dataGrid = new SfDataGrid();
OrderInfoViewModel viewModel = new OrderInfoViewModel();
dataGrid.ItemsSource = viewModel.Orders;
dataGrid.FilterRowPosition = DataGridFilterRowPosition.FixedTop;
dataGrid.SelectionMode = DataGridSelectionMode.Single;
this.Content = dataGrid;
Getting the FilterRow index
Retrieve the row index of the FilterRow using the SfDataGrid.GetFilterRowIndex method.
int filterRowIndex = this.dataGrid.GetFilterRowIndex();Verify if a given row index corresponds to the FilterRow by utilizing the SfDataGrid.IsFilterRowIndex helper method.
bool isFilterRowIndex = this.dataGrid.IsFilterRowIndex(1);Built-in editors
The FilterRow automatically assigns an appropriate editor based on the column’s data type. The following table shows the default editor for each data type, and how to override it:
Default editor assignment:
- String columns: TextBox
- Numeric columns (int, double, decimal): Numeric editor
- Boolean columns: CheckBox
- DateTime columns: DateTime picker
You can override the default editor by explicitly setting the FilterRowEditorType property.
The FilterRow automatically initializes editors that correspond to the underlying property type, simplifying data filtering. Customize these default editors by setting the DataGridColumn.FilterRowEditorType property. Both XAML and C# use string literal values (e.g., "MultiSelectComboBox").
<syncfusion:DataGridTextColumn HeaderText="Ship Country"
MappingName="Country"
FilterRowEditorType="MultiSelectComboBox"/>var countryColumn = new DataGridTextColumn();
countryColumn.HeaderText = "Ship Country";
countryColumn.MappingName = "Country";
countryColumn.FilterRowEditorType = "MultiSelectComboBox";
dataGrid.Columns.Add(countryColumn);
Below are the built-in FilterRow editor types supported in SfDataGrid.
| FilterRowEditor Type | Editor Control | Renderer | Description |
|---|---|---|---|
| TextBox | SfDataGridEntry | DataGridFilterRowTextBoxRenderer | Filters string data. |
| Numeric | SfNumericEntry | DataGridFilterRowNumericBoxRenderer | Filters numeric data (int, double, decimal, etc.). |
| ComboBox | SfComboBox | DataGridFilterRowComboBoxRenderer | Selects a single value for filtering from a dropdown. |
| MultiSelectComboBox | SfComboBox | DataGridFilterRowMultiSelectRenderer | Selects multiple values for filtering from a dropdown. |
| CheckBox | SfCheckBox | DataGridFilterRowCheckBoxRenderer | Filters Boolean data. |
| DateTime | DatePicker | DataGridFilterRowDateRenderer | Filters DateTime data. |
Filter options
The FilterRowCell presents filter conditions in a dropdown menu, categorized by editor type, allowing for easy switching between conditions to refine data. To disable these filter options, set the DataGridColumn.FilterRowOptionsVisibility property.
<syncfusion:DataGridTextColumn HeaderText="Customer"
MappingName="Customer"
FilterRowOptionsVisibility="False" />var customerIdColumn = new DataGridTextColumn();
customerIdColumn.HeaderText = "Customer";
customerIdColumn.MappingName = "Customer";
customerIdColumn.FilterRowOptionsVisibility = false;
dataGrid.Columns.Add(customerIdColumn);
Below are the filter conditions supported by different filter row editors in SfDataGrid.
| Numeric Editor | TextBox Editor | DateTime Editor | CheckBox Editor | ComboBox, MultiSelectComboBox Editor |
|---|---|---|---|---|
The numeric editor is utilized in DataGridFilterRowCell when integer, double, short, decimal, byte, or long data types are bound to the DataGridColumn.FilterRowEditorType. |
The text editor is employed in DataGridFilterRowCell for string-bound DataGridColumn values or dynamic item sources. |
For DataGridColumn entries with datetime data types, the datetime editor is loaded into the DataGridFilterRowCell. |
When a boolean type is bound to the DataGridColumn, the checkbox editor is automatically loaded in the DataGridFilterRowCell. |
To use comboBox and MultiSelectComboBox editors, the FilterRowEditorType property must be explicitly set. |
The default numeric filter condition is Equals. Additional available conditions include:
|
The default text filter condition is Contains. Other available conditions include:
|
The default DateTime filter condition is Equal. Additional conditions provided are:
|
For checkbox values, the Equals filter condition is always applied. |
The filter condition will use either equals or not equals based on the number of selected items when filtering the list. |
Customize the default FilterRow condition for any specific column by setting the DataGridColumn.FilterRowCondition property using the FilterRowCondition enum (e.g., FilterRowCondition.LessThan, FilterRowCondition.Contains).
<syncfusion:DataGridNumericColumn HeaderText="Order ID"
MappingName="OrderID"
FilterRowCondition="LessThan"/>var orderIdColumn = new DataGridNumericColumn();
orderIdColumn.HeaderText = "Order ID";
orderIdColumn.MappingName = "OrderID";
orderIdColumn.FilterRowCondition = FilterRowCondition.LessThan;
dataGrid.Columns.Add(orderIdColumn);Filtering null values
Control the inclusion of null values in filtering by configuring the DataGridColumn.AllowBlankFilters property, which is true by default. When active, filter options display Null and Not Null choices, and ComboBox editors include a Blanks option for null value filtering.
<syncfusion:DataGridTextColumn HeaderText="Customer"
MappingName="Customer"
AllowBlankFilters="False"/>var customerColumn = new DataGridTextColumn();
customerColumn.HeaderText = "Customer";
customerColumn.MappingName = "Customer";
customerColumn.AllowBlankFilters = false;
dataGrid.Columns.Add(customerColumn);
<syncfusion:DataGridTextColumn HeaderText="Ship Country"
MappingName="Country"
AllowBlankFilters="True"
FilterRowEditorType="MultiSelectComboBox"/>var countryColumn = new DataGridTextColumn();
customerColumn.HeaderText = "Ship Country";
customerColumn.MappingName = "Country";
customerColumn.AllowBlankFilters = true;
customerColumn.FilterRowEditorType = "MultiSelectComboBox";
dataGrid.Columns.Add(countryColumn);
Instant filtering
Filters are typically applied to columns upon cell navigation or pressing the Enter key. However, by setting DataGridColumn.ImmediateUpdateColumnFilter to true, you can enable instant filtering as you type within the editor.
<syncfusion:DataGridTextColumn MappingName="Customer"
FilterRowEditorType="MultiSelectComboBox"
ImmediateUpdateColumnFilter="True"/>var customerColumn = new DataGridTextColumn();
customerColumn.MappingName = "Customer";
customerColumn.FilterRowEditorType = "MultiSelectComboBox";
customerColumn.ImmediateUpdateColumnFilter = true;
dataGrid.Columns.Add(customerColumn);Disable filtering for a particular cell
While filter row cells are editable by default for record filtering, you can prevent editing for a specific cell using the CurrentCellBeginEdit event.
this.dataGrid.CurrentCellBeginEdit += DataGrid_CurrentCellBeginEdit;
private void DataGrid_CurrentCellBeginEdit(object? sender, DataGridCurrentCellBeginEditEventArgs e)
{
if (e?.Column?.MappingName == "CustomerID" && dataGrid.IsFilterRowIndex(e.RowColumnIndex.RowIndex))
e.Cancel = true;
}Styling
Apply default style
You can customize the basic styling of the FilterRow in SfDataGrid using the DefaultStyle property. This approach allows you to modify attributes such as FilterRowFontAttributes, FilterIconHoverBackground, FilterRowBackground, FilterRowFontFamily, FilterRowFontSize, and FilterRowTextColor.
<syncfusion:SfDataGrid.DefaultStyle>
<syncfusion:DataGridStyle FilterRowFontAttributes="Bold"
FilterIconHoverBackground="AliceBlue"
FilterRowBackground="Yellow"
FilterRowTextColor="CadetBlue"
FilterRowFontSize="10" />
</syncfusion:SfDataGrid.DefaultStyle>var style = new DataGridStyle
{
FilterRowFontAttributes = FontAttributes.Bold,
FilterIconHoverBackground = Colors.AliceBlue,
FilterRowBackground = Colors.Yellow,
FilterRowTextColor = Colors.CadetBlue,
FilterRowFontSize = 10
};
dataGrid.DefaultStyle = style;Filter row style
Customize the appearance of the filter row by defining a style with TargetType DataGridFilterRowView.
<ContentPage.Resources>
<Style TargetType="syncfusion:DataGridFilterRowView">
<Setter Property="Background" Value="BlanchedAlmond"/>
</Style>
</ContentPage.Resources>
Styling filter row cells
Customize individual filter row cell appearance through the FilterRowCellStyle property.
<syncfusion:DataGridTextColumn MappingName="Customer"
HeaderText="Customer">
<syncfusion:DataGridTextColumn.FilterRowCellStyle>
<Style TargetType="syncfusion:DataGridFilterRowCell">
<Setter Property="Background" Value="LightGreen" />
</Style>
</syncfusion:DataGridTextColumn.FilterRowCellStyle>
</syncfusion:DataGridTextColumn>
Customizing filter row editors
SfDataGrid provides several approaches for customizing filter row editors based on your needs:
- Override the default renderer to modify existing editor behavior
- Create a custom renderer for completely new filter logic
- Override the MultiSelectRenderer to display editors immediately on load
Customizing the filter row renderer
SfDataGrid allows you to customize the filter row renderer behavior by overriding the corresponding renderer associated with the filter row cell. Each renderer has a set of virtual methods for handling the filter row behaviors. You can also create new renderers instead of overriding the existing renderer.
You can customize the default TextBox editor behavior by overriding DataGridFilterRowTextBoxRenderer class and add the custom renderer to FilterRowCellRenderers. Override methods such as OnInitializeDisplayView, OnInitializeEditView to customize rendering and filter behavior.
<syncfusion:DataGridTextColumn HeaderText="Customer"
MappingName="Customer"
FilterRowEditorType="CustomTextBox"/>public MainPage()
{
InitializeComponent();
this.dataGrid.FilterRowCellRenderers.Add("CustomTextBox", new CustomDataGridFilterRowTextBoxRenderer());
}
public class CustomDataGridFilterRowTextBoxRenderer : DataGridFilterRowTextBoxRenderer
{
public CustomDataGridFilterRowTextBoxRenderer(): base()
{
}
// Example: Override to customize the display view
protected override void OnInitializeDisplayView(DataColumnBase dataColumn, SfDataGridContentView? view)
{
base.OnInitializeDisplayView(dataColumn, view);
// Add custom logic here
}
}Filter based on numeric interval by using the multi select combobox filter
By default, columns support filtering multiple values using the MultiSelectComboBox filter editor type. To filter data based on a range of numeric values, you can override the PopulateComboBoxItems and GetFilterPredicates methods within the DataGridFilterRowComboBoxRenderer class, as demonstrated in the code below.
<syncfusion:DataGridTextColumn HeaderText="Customer"
MappingName="Customer"
FilterRowEditorType="CustomComboBox"/>public MainPage()
{
InitializeComponent();
this.dataGrid.FilterRowCellRenderers.Add("CustomComboBox", new CustomDataGridFilterRowComboBoxRenderer());
}
public class CustomDataGridFilterRowComboBoxRenderer : DataGridFilterRowComboBoxRenderer
{
private List<string>? numericComboBoxItems;
private string selectedText = string.Empty;
public CustomDataGridFilterRowComboBoxRenderer()
{
SetNumericComboBoxItemsList();
}
/// <summary>
/// Generate custom filter interval items for the ComboBox
/// </summary>
public void SetNumericComboBoxItemsList()
{
numericComboBoxItems = new List<string>();
numericComboBoxItems.Add("Between 10000 and 10005");
numericComboBoxItems.Add("Between 10005 and 10010");
numericComboBoxItems.Add("Between 10010 and 10015");
numericComboBoxItems.Add("Between 10015 and 10020");
numericComboBoxItems.Add(">10020");
}
/// <summary>
/// Gets filter predicates based on selected values.
/// </summary>
public override List<FilterPredicate> GetFilterPredicates(object? filterValue)
{
var predicates = new List<FilterPredicate>();
var filterMode = ColumnFilter.Value;
if (filterValue == null)
return predicates;
if (filterValue is string text)
{
selectedText = text;
text = text.Trim();
if (text.StartsWith("Between", StringComparison.OrdinalIgnoreCase))
{
var remainder = text.Substring(7).Trim();
var parts = remainder.Split(new[] { "and" }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length == 2 && TryParseDouble(parts[0], out var minVal) && TryParseDouble(parts[1], out var maxVal))
{
predicates.Add(new FilterPredicate
{
FilterType = FilterType.GreaterThanOrEqual,
PredicateType = PredicateType.And,
FilterMode = filterMode,
FilterValue = minVal
});
predicates.Add(new FilterPredicate
{
FilterType = FilterType.LessThanOrEqual,
PredicateType = PredicateType.And,
FilterMode = filterMode,
FilterValue = maxVal
});
return predicates;
}
}
if ((text.StartsWith(">=") || text.StartsWith(">") || text.StartsWith("<=") || text.StartsWith("<")))
{
FilterType? type = null;
string numberPart = string.Empty;
if (text.StartsWith(">="))
{
type = FilterType.GreaterThanOrEqual;
numberPart = text.Substring(2);
}
else if (text.StartsWith(">"))
{
type = FilterType.GreaterThan;
numberPart = text.Substring(1);
}
else if (text.StartsWith("<="))
{
type = FilterType.LessThanOrEqual;
numberPart = text.Substring(2);
}
else if (text.StartsWith("<"))
{
type = FilterType.LessThan;
numberPart = text.Substring(1);
}
if (type.HasValue && TryParseDouble(numberPart, out var value))
{
predicates.Add(new FilterPredicate
{
FilterType = type.Value,
PredicateType = PredicateType.And,
FilterMode = filterMode,
FilterValue = value
});
return predicates;
}
}
predicates.Add(new FilterPredicate
{
FilterType = FilterType.Equals,
PredicateType = PredicateType.And,
FilterMode = filterMode,
FilterValue = text
});
return predicates;
}
predicates.Add(new FilterPredicate
{
FilterType = FilterType.Equals,
PredicateType = PredicateType.And,
FilterMode = filterMode,
FilterValue = filterValue
});
return predicates;
}
private static bool TryParseDouble(string input, out double value)
{
input = (input ?? string.Empty).Trim();
return double.TryParse(input, NumberStyles.Any, CultureInfo.InvariantCulture, out value) ||
double.TryParse(input, NumberStyles.Any, CultureInfo.CurrentCulture, out value);
}
protected override void PopulateComboBoxItems(SfComboBox comboBox, DataGridColumn column)
{
var modifiedItemsSource = new ObservableCollection<object>();
foreach (var item in numericComboBoxItems)
{
modifiedItemsSource.Add(item);
}
comboBox.ItemsSource = modifiedItemsSource;
}
protected override void UpdateDisplayText(SfDataGridFilterRowLabel label, DataGridColumn column)
{
base.UpdateDisplayText(label, column);
label.Text = selectedText;
}
}
Customizing DataGridFilterRowMultiSelectRenderer
By default, the SfDataGrid loads a ComboBox when the FilterRow enters edit mode. However, you can tailor the DataGridFilterRowMultiSelectRenderer to ensure the ComboBox is visible immediately upon FilterRow initialization.
<syncfusion:DataGridTextColumn HeaderText="Customer ID"
MappingName="CustomerID"
FilterRowEditorType="MultiSelectComboBox"/>dataGrid.FilterRowCellRenderers.Remove("MultiSelectComboBox");
dataGrid.FilterRowCellRenderers.Add("MultiSelectComboBox", new CustomDataGridMultiSelectComboBoxRenderer());
public class CustomDataGridMultiSelectComboBoxRenderer : DataGridFilterRowMultiSelectRenderer
{
public CustomDataGridMultiSelectComboBoxRenderer()
{
// SupportsRenderOptimization: Set to false to disable optimization and always render the ComboBox
SupportsRenderOptimization = false;
// IsEditable: Set to true to make the filter row cell editable by default
IsEditable = true;
}
/// <summary>
/// Initialize the filter-row display with a live MultiSelect ComboBox instead of a label.
/// This method is called when initializing the display view in edit mode.
/// </summary>
protected override void OnInitializeDisplayView(DataColumnBase dataColumn, SfDataGridContentView? view)
{
InitializeComboBoxView(dataColumn, view);
}
}