How can I help you?
Filtering in Xamarin.Android SfDataGrid
24 Feb 202324 minutes to read
The data grid supports view filtering.
View filtering
The data grid supports filtering the records in the view by setting the SfDataGrid.View.Filter property where Filter is a predicate.
To filter the records in the data grid, assign the filtered strings to the ViewModel.FilterText property which will be applied later in Filter predicate that is assigned to SfDataGrid.View.Filter in the OnFilterChanged() method.
NOTE
To update the filtering for the newly added row or column, set the
SfDataGrid.View.LiveDataUpdateModetoLiveDataUpdateMode.AllowDataShaping.
The following code example illustrates the delegate, properties, and methods used in the ViewModel class perform the filtering operation.
// ViewModel.cs
#region Filtering
#region Fields
private string filterText = "";
private string selectedColumn = "All Columns";
private string selectedCondition = "Equals";
internal delegate void FilterChanged();
internal FilterChanged filterTextChanged;
#endregion
#region Property
public string FilterText
{
get { return filterText; }
set
{
filterText = value;
OnFilterTextChanged();
RaisePropertyChanged("FilterText");
}
}
public string SelectedCondition
{
get { return selectedCondition; }
set { selectedCondition = value; }
}
public string SelectedColumn
{
get { return selectedColumn; }
set { selectedColumn = value; }
}
#endregion
#region Private Methods
private void OnFilterTextChanged()
{
filterTextChanged();
}
private bool MakeStringFilter(OrderInfo o, string option, string condition)
{
var value = o.GetType().GetProperty(option);
var exactValue = value.GetValue(o, null);
exactValue = exactValue.ToString().ToLower();
string text = FilterText.ToLower();
var methods = typeof(string).GetMethods();
if (methods.Count() != 0)
{
if (condition == "Contains")
{
var methodInfo = methods.FirstOrDefault(method => method.Name == condition);
bool result1 = (bool)methodInfo.Invoke(exactValue, new object[] { text });
return result1;
}
else if (exactValue.ToString() == text.ToString())
{
bool result1 = String.Equals(exactValue.ToString(), text.ToString());
if (condition == "Equals")
return result1;
else if (condition == "NotEquals")
return false;
}
else if (condition == "NotEquals")
{
return true;
}
return false;
}
else
return false;
}
private bool MakeNumericFilter(OrderInfo o, string option, string condition)
{
var value = o.GetType().GetProperty(option);
var exactValue = value.GetValue(o, null);
double res;
bool checkNumeric = double.TryParse(exactValue.ToString(), out res);
if (checkNumeric)
{
switch (condition)
{
case "Equals":
try
{
if (exactValue.ToString() == FilterText)
{
if (Convert.ToDouble(exactValue) == (Convert.ToDouble(FilterText)))
return true;
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
break;
case "NotEquals":
try
{
if (Convert.ToDouble(FilterText) != Convert.ToDouble(exactValue))
return true;
}
catch (Exception e)
{
Console.WriteLine(e);
return true;
}
break;
}
}
return false;
}
#endregion
#region Public Methods
public bool FilerRecords(object o)
{
double res;
bool checkNumeric = double.TryParse(FilterText, out res);
var item = o as OrderInfo;
if (item != null && FilterText.Equals(""))
{
return true;
}
else
{
if (item != null)
{
if (checkNumeric && !SelectedColumn.Equals("All Columns"))
{
bool result = MakeNumericFilter(item, SelectedColumn, SelectedCondition);
return result;
}
else if (SelectedColumn.Equals("All Columns"))
{
if (item.CustomerID.ToLower().Contains(FilterText.ToLower()) ||
item.Country.ToLower().Contains(FilterText.ToLower()) ||
item.Freight.ToString().ToLower().Contains(FilterText.ToLower()) ||
item.OrderID.ToString().ToLower().Contains(FilterText.ToLower()))
return true;
return false;
}
else
{
bool result = MakeStringFilter(item, SelectedColumn, SelectedCondition);
return result;
}
}
}
return false;
}
#endregion
#endregionThe following code example illustrates how to create a SearchView and apply the filtered records to the ViewModel.FilterText property in SearchView.QueryTextChange event.
// Code-Behind
SearchView filterText = new SearchView(BaseContext);
filterText.SetQueryHint("Enter the Text to filter");
filterText.QueryTextChange += OnFilterTextChanged;
private void OnFilterTextChanged(object sender, SearchView.QueryTextChangeEventArgs e)
{
viewModel.FilterText = (sender as SearchView).Query.ToString();
}
Once you create the SearchView and a view model, you can perform filtering by setting the SfDataGrid.View.Filter property. You have to call the SfDataGrid.View.RefreshFilter() method after setting the filtered records to the SfDataGrid.View.Filter property as in the following code example.
// Code-Behind
viewModel.filterTextChanged = OnFilterChanged; //where ‘filterTextChanged’ is a delegate declared in ViewModel class.
private void OnFilterChanged()
{
if (dataGrid.View != null)
{
this.dataGrid.View.Filter = viewModel.FilerRecords;
this.dataGrid.View.RefreshFilter();
}
}Applying DataTable’s RowFilter to DataGrid
To filter the rows in SfDataGrid using DataView.RowFilter expression, set the value of SfDataGrid.CanUseViewFilter property to true. The default filter which created in DataView can be applied or canceled through this property.
Filter individual columns
You can filter the records in all the columns or in a particular column using the code in the OnColumnSelected() method.
For example, you can filter the records in OrderID or any other particular column alone.The following code example illustrates how to create a Spinner for columns. It also illustrates how the records will be filtered based on the selected column.
// Code-Behind
TextView columnTextView;
Spinner columnDropdown;
conditionTextView = new TextView(BaseContext);
conditionTextView.Text = "Select the condition to filter";
columnTextView = new TextView(BaseContext);
columnTextView.Text = "Select the column to filter";
columnDropdown = FindViewById<Spinner>(Resource.Id.column);
var columnAdapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleSpinnerItem);
columnAdapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
columnAdapter.Add("All Columns");
columnAdapter.Add("OrderID");
columnAdapter.Add("CustomerID");
columnAdapter.Add("Freight");
columnAdapter.Add("Country");
columnDropdown.Adapter = columnAdapter;
columnDropdown.ItemSelected += OnColumnSelected;
private void OnColumnSelected(object sender, AdapterView.ItemSelectedEventArgs e)
{
Spinner newSpinner = (Spinner)sender;
viewModel.SelectedColumn = newSpinner.GetItemAtPosition(e.Position).ToString();
if (viewModel.SelectedColumn == "All Columns")
{
conditionDropdown.Visibility = ViewStates.Gone;
conditionTextView.Visibility = ViewStates.Gone;
}
else
{
conditionDropdown.Visibility = ViewStates.Visible;
conditionTextView.Visibility = ViewStates.Visible;
foreach (var prop in typeof(OrderInfo).GetProperties())
{
// Records will be filtered based on selected column
if (prop.Name == viewModel.SelectedColumn)
{
var type = prop.GetType();
if (prop.PropertyType == typeof(Java.Lang.String))
{
conditionAdapter.Clear();
conditionAdapter.Add("Equals");
conditionAdapter.Add("Contains");
if (this.viewModel.SelectedCondition == "Equals")
this.viewModel.SelectedCondition = "Equals";
else
this.viewModel.SelectedCondition = "Contains";
}
else
{
conditionAdapter.Clear();
conditionAdapter.Add("Equals");
conditionAdapter.Add("NotEquals");
if (this.viewModel.SelectedCondition == "Equals")
this.viewModel.SelectedCondition = "Equals";
else
this.viewModel.SelectedCondition = "NotEquals";
}
}
}
}
if (filterText.Query != "")
this.OnFilterChanged();
}
Filter based on conditions
In addition to the column-based filtering, you can filter the records based on conditions. For example, you can filter the records based on the given input or you can filter the records in contrast to your input. You can perform the condition-based filtering for all columns or any particular column.
You can filter the records in the view based on any of the following conditions:
- Equals
- NotEquals
- Contains
These conditions are the mostly used conditions. However, you can add any other conditions and alter the following code example.
// ViewModel.cs
public bool FilerRecords(object o)
{
double res;
bool checkNumeric = double.TryParse(FilterText, out res);
var item = o as OrderInfo;
if (item != null && FilterText.Equals(""))
{
return true;
}
else
{
if (item != null)
{
if (checkNumeric && !SelectedColumn.Equals("All Columns"))
{
bool result = MakeNumericFilter(item, SelectedColumn, SelectedCondition);
return result;
}
else if (SelectedColumn.Equals("All Columns"))
{
if (item.CustomerID.ToLower().Contains(FilterText.ToLower()) ||
item.Country.ToLower().Contains(FilterText.ToLower()) ||
item.Freight.ToString().ToLower().Contains(FilterText.ToLower()) ||
item.OrderID.ToString().ToLower().Contains(FilterText.ToLower()))
return true;
return false;
}
else
{
bool result = MakeStringFilter(item, SelectedColumn, SelectedCondition);
return result;
}
}
}
return false;
}
private bool MakeStringFilter(OrderInfo o, string option, string condition)
{
var value = o.GetType().GetProperty(option);
var exactValue = value.GetValue(o, null);
exactValue = exactValue.ToString().ToLower();
string text = FilterText.ToLower();
var methods = typeof(string).GetMethods();
if (methods.Count() != 0)
{
if (condition == "Contains")
{
var methodInfo = methods.FirstOrDefault(method => method.Name == condition);
bool result1 = (bool)methodInfo.Invoke(exactValue, new object[] { text });
return result1;
}
else if (exactValue.ToString() == text.ToString())
{
bool result1 = String.Equals(exactValue.ToString(), text.ToString());
if (condition == "Equals")
return result1;
else if (condition == "NotEquals")
return false;
}
else if (condition == "NotEquals")
{
return true;
}
return false;
}
else
return false;
}
private bool MakeNumericFilter(OrderInfo o, string option, string condition)
{
var value = o.GetType().GetProperty(option);
var exactValue = value.GetValue(o, null);
double res;
bool checkNumeric = double.TryParse(exactValue.ToString(), out res);
if (checkNumeric)
{
switch (condition)
{
case "Equals":
try
{
if (exactValue.ToString() == FilterText)
{
if (Convert.ToDouble(exactValue) == (Convert.ToDouble(FilterText)))
return true;
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
break;
case "NotEquals":
try
{
if (Convert.ToDouble(FilterText) != Convert.ToDouble(exactValue))
return true;
}
catch (Exception e)
{
Console.WriteLine(e);
return true;
}
break;
}
}
return false;
}The following code example illustrates how to create a Spinner for conditions and add appropriate strings to that Spinner. It also illustrates how the records will be filtered based on the selected condition.
// Code-Behind
TextView conditionTextView;
Spinner conditionDropdown;
ArrayAdapter conditionAdapter;
conditionDropdown = FindViewById<Spinner>(Resource.Id.condition);
conditionAdapter = new ArrayAdapter(BaseContext, Android.Resource.Layout.SimpleSpinnerItem);
conditionAdapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
conditionAdapter.Add("Equals");
conditionAdapter.Add("NotEquals");
conditionAdapter.Add("Contains");
conditionDropdown.Adapter = conditionAdapter;
conditionDropdown.ItemSelected += OnConditionSelected;
private void OnConditionSelected(object sender, AdapterView.ItemSelectedEventArgs e)
{
Spinner newSpinner = (Spinner)sender;
viewModel.SelectedCondition = newSpinner.GetItemAtPosition(e.Position).ToString();
if (filterText.Query != "")
this.OnFilterChanged();
}
Clear filtering
The data grid allows clearing the applied filtering by setting the SfDataGrid.View.Filter property to null.
The following code example illustrates how to clear the applied filtering in the data grid.
// Code-Behind
private void OnFilterChanged()
{
if (dataGrid.View != null)
{
this.dataGrid.View.Filter = null;
this.dataGrid.View.RefreshFilter();
}
}You can download the filtering demo here.